refactor(semantic): clean up redeclaration diagnostic

This commit is contained in:
Boshen 2024-05-12 01:18:30 +08:00
parent 312f74bb63
commit c5588c9b1c
No known key found for this signature in database
GPG key ID: 9C7A8C8AB22BEBD1
4 changed files with 29 additions and 28 deletions

View file

@ -19,7 +19,7 @@ use crate::{
control_flow::{ control_flow::{
AssignmentValue, ControlFlowGraph, EdgeType, Register, StatementControlFlowType, AssignmentValue, ControlFlowGraph, EdgeType, Register, StatementControlFlowType,
}, },
diagnostics::Redeclaration, diagnostics::redeclaration,
jsdoc::JSDocBuilder, jsdoc::JSDocBuilder,
label::LabelBuilder, label::LabelBuilder,
module_record::ModuleRecordBuilder, module_record::ModuleRecordBuilder,
@ -279,7 +279,7 @@ impl<'a> SemanticBuilder<'a> {
let symbol_id = self.scope.get_binding(scope_id, name)?; let symbol_id = self.scope.get_binding(scope_id, name)?;
if report_error && self.symbols.get_flag(symbol_id).intersects(excludes) { if report_error && self.symbols.get_flag(symbol_id).intersects(excludes) {
let symbol_span = self.symbols.get_span(symbol_id); let symbol_span = self.symbols.get_span(symbol_id);
self.error(Redeclaration(CompactStr::from(name), symbol_span, span)); self.error(redeclaration(name, symbol_span, span));
} }
Some(symbol_id) Some(symbol_id)
} }

View file

@ -14,7 +14,7 @@ use oxc_syntax::{
use phf::{phf_set, Set}; use phf::{phf_set, Set};
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
use crate::{builder::SemanticBuilder, diagnostics::Redeclaration, scope::ScopeFlags, AstNode}; use crate::{builder::SemanticBuilder, diagnostics::redeclaration, scope::ScopeFlags, AstNode};
pub struct EarlyErrorJavaScript; pub struct EarlyErrorJavaScript;
@ -131,7 +131,7 @@ fn check_duplicate_class_elements(ctx: &SemanticBuilder<'_>) {
}; };
if is_duplicate { if is_duplicate {
ctx.error(Redeclaration(element.name.clone(), prev_element.span, element.span)); ctx.error(redeclaration(&element.name, prev_element.span, element.span));
} }
} }
} }
@ -429,8 +429,10 @@ fn check_string_literal(lit: &StringLiteral, ctx: &SemanticBuilder<'_>) {
} }
fn illegal_use_strict(span0: Span) -> OxcDiagnostic { fn illegal_use_strict(span0: Span) -> OxcDiagnostic {
OxcDiagnostic::error("Illegal 'use strict' directive in function with non-simple parameter list") OxcDiagnostic::error(
.with_labels([span0.into()]) "Illegal 'use strict' directive in function with non-simple parameter list",
)
.with_labels([span0.into()])
} }
// It is a Syntax Error if FunctionBodyContainsUseStrict of AsyncFunctionBody is true and IsSimpleParameterList of FormalParameters is false. // It is a Syntax Error if FunctionBodyContainsUseStrict of AsyncFunctionBody is true and IsSimpleParameterList of FormalParameters is false.
@ -454,8 +456,10 @@ fn check_directive(directive: &Directive, ctx: &SemanticBuilder<'_>) {
} }
fn top_level(x0: &str, span1: Span) -> OxcDiagnostic { fn top_level(x0: &str, span1: Span) -> OxcDiagnostic {
OxcDiagnostic::error(format!("'{x0}' declaration can only be used at the top level of a module")) OxcDiagnostic::error(format!(
.with_labels([span1.into()]) "'{x0}' declaration can only be used at the top level of a module"
))
.with_labels([span1.into()])
} }
fn module_code(x0: &str, span1: Span) -> OxcDiagnostic { fn module_code(x0: &str, span1: Span) -> OxcDiagnostic {
@ -613,7 +617,7 @@ fn check_switch_statement<'a>(stmt: &SwitchStatement<'a>, ctx: &SemanticBuilder<
for case in &stmt.cases { for case in &stmt.cases {
if case.test.is_none() { if case.test.is_none() {
if let Some(previous_span) = previous_default { if let Some(previous_span) = previous_default {
ctx.error(Redeclaration("default".into(), previous_span, case.span)); ctx.error(redeclaration("default", previous_span, case.span));
break; break;
} }
previous_default.replace(case.span); previous_default.replace(case.span);
@ -720,7 +724,7 @@ fn check_labeled_statement(ctx: &SemanticBuilder) {
let mut defined = FxHashMap::default(); let mut defined = FxHashMap::default();
for labeled in labels { for labeled in labels {
if let Some(span) = defined.get(labeled.name) { if let Some(span) = defined.get(labeled.name) {
ctx.error(Redeclaration(labeled.name.into(), *span, labeled.span)); ctx.error(redeclaration(labeled.name, *span, labeled.span));
} else { } else {
defined.insert(labeled.name, labeled.span); defined.insert(labeled.name, labeled.span);
} }
@ -729,8 +733,10 @@ fn check_labeled_statement(ctx: &SemanticBuilder) {
} }
fn multiple_declaration_in_for_loop_head(x0: &str, span1: Span) -> OxcDiagnostic { fn multiple_declaration_in_for_loop_head(x0: &str, span1: Span) -> OxcDiagnostic {
OxcDiagnostic::error(format!("Only a single declaration is allowed in a `for...{x0}` statement")) OxcDiagnostic::error(format!(
.with_labels([span1.into()]) "Only a single declaration is allowed in a `for...{x0}` statement"
))
.with_labels([span1.into()])
} }
fn unexpected_initializer_in_for_loop_head(x0: &str, span1: Span) -> OxcDiagnostic { fn unexpected_initializer_in_for_loop_head(x0: &str, span1: Span) -> OxcDiagnostic {
@ -1036,7 +1042,7 @@ fn check_object_expression(obj_expr: &ObjectExpression, ctx: &SemanticBuilder<'_
for prop_name in prop_names { for prop_name in prop_names {
if prop_name.0 == "__proto__" { if prop_name.0 == "__proto__" {
if let Some(prev_span) = prev_proto { if let Some(prev_span) = prev_proto {
ctx.error(Redeclaration("__proto__".into(), prev_span, prop_name.1)); ctx.error(redeclaration("__proto__", prev_span, prop_name.1));
} }
prev_proto = Some(prop_name.1); prev_proto = Some(prop_name.1);
} }

View file

@ -5,7 +5,7 @@ use oxc_diagnostics::OxcDiagnostic;
use oxc_span::{Atom, GetSpan, Span}; use oxc_span::{Atom, GetSpan, Span};
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
use crate::{builder::SemanticBuilder, diagnostics::Redeclaration, AstNode}; use crate::{builder::SemanticBuilder, diagnostics::redeclaration, AstNode};
pub struct EarlyErrorTypeScript; pub struct EarlyErrorTypeScript;
@ -93,7 +93,7 @@ fn check_duplicate_bound_names<'a, T: BoundNames<'a>>(bound_names: &T, ctx: &Sem
let mut idents: FxHashMap<Atom<'a>, Span> = FxHashMap::default(); let mut idents: FxHashMap<Atom<'a>, Span> = FxHashMap::default();
bound_names.bound_names(&mut |ident| { bound_names.bound_names(&mut |ident| {
if let Some(old_span) = idents.insert(ident.name.clone(), ident.span) { if let Some(old_span) = idents.insert(ident.name.clone(), ident.span) {
ctx.error(Redeclaration(ident.name.to_compact_str(), old_span, ident.span)); ctx.error(redeclaration(&ident.name, old_span, ident.span));
} }
}); });
} }

View file

@ -1,14 +1,9 @@
use oxc_diagnostics::{ use oxc_diagnostics::{LabeledSpan, OxcDiagnostic};
miette::{self, Diagnostic}, use oxc_span::Span;
thiserror::{self, Error},
};
use oxc_span::{CompactStr, Span};
#[derive(Debug, Error, Diagnostic)] pub fn redeclaration(x0: &str, span1: Span, span2: Span) -> OxcDiagnostic {
#[error("Identifier `{0}` has already been declared")] OxcDiagnostic::error(format!("Identifier `{x0}` has already been declared")).with_labels([
#[diagnostic()] LabeledSpan::new_with_span(Some(format!("`{x0}` has already been declared here")), span1),
pub struct Redeclaration( LabeledSpan::new_with_span(Some("It can not be redeclared here".into()), span2),
pub CompactStr, ])
#[label("`{0}` has already been declared here")] pub Span, }
#[label("It can not be redeclared here")] pub Span,
);