refactor(linter): improve diagnostic labeling (#3960)

This commit is contained in:
DonIsaac 2024-06-29 05:19:21 +00:00
parent f64ad4b7c2
commit 2705df93b3
41 changed files with 217 additions and 201 deletions

View file

@ -118,8 +118,11 @@ impl OxcDiagnostic {
}
#[must_use]
pub fn with_labels<T: IntoIterator<Item = LabeledSpan>>(mut self, labels: T) -> Self {
self.inner.labels = Some(labels.into_iter().collect());
pub fn with_labels<L: Into<LabeledSpan>, T: IntoIterator<Item = L>>(
mut self,
labels: T,
) -> Self {
self.inner.labels = Some(labels.into_iter().map(Into::into).collect());
self
}
@ -132,9 +135,12 @@ impl OxcDiagnostic {
}
#[must_use]
pub fn and_labels<T: IntoIterator<Item = LabeledSpan>>(mut self, labels: T) -> Self {
pub fn and_labels<L: Into<LabeledSpan>, T: IntoIterator<Item = L>>(
mut self,
labels: T,
) -> Self {
let mut all_labels = self.inner.labels.unwrap_or_default();
all_labels.extend(labels);
all_labels.extend(labels.into_iter().map(Into::into));
self.inner.labels = Some(all_labels);
self
}

View file

@ -5,7 +5,7 @@ use std::{env, path::Path};
use oxc_allocator::Allocator;
use oxc_ast::AstKind;
use oxc_diagnostics::{LabeledSpan, OxcDiagnostic};
use oxc_diagnostics::OxcDiagnostic;
use oxc_parser::Parser;
use oxc_semantic::SemanticBuilder;
use oxc_span::{SourceType, Span};
@ -73,8 +73,8 @@ fn print_errors(source_text: &str, errors: Vec<OxcDiagnostic>) {
// 1 │ debugger;
// · ─────────
// ╰────
fn no_debugger(span0: Span) -> OxcDiagnostic {
OxcDiagnostic::error("`debugger` statement is not allowed").with_labels([span0.into()])
fn no_debugger(debugger_span: Span) -> OxcDiagnostic {
OxcDiagnostic::error("`debugger` statement is not allowed").with_label(debugger_span)
}
// This prints:
@ -85,8 +85,7 @@ fn no_debugger(span0: Span) -> OxcDiagnostic {
// · ─┬
// · ╰── Empty object binding pattern
// ╰────
fn no_empty_pattern(s0: &str, span1: Span) -> OxcDiagnostic {
OxcDiagnostic::error("empty destructuring pattern is not allowed").with_labels([
LabeledSpan::new_with_span(Some(format!("Empty {s0} binding pattern")), span1),
])
fn no_empty_pattern(binding_kind: &str, span: Span) -> OxcDiagnostic {
OxcDiagnostic::error("empty destructuring pattern is not allowed")
.with_label(span.label(format!("Empty {binding_kind} binding pattern")))
}

View file

@ -290,8 +290,8 @@ mod test {
OxcDiagnostic::warn("removestart")
}
fn remove_middle(span0: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("removemiddle").with_labels([span0.into()])
fn remove_middle(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("removemiddle").with_labels([span])
}
fn remove_end() -> OxcDiagnostic {
@ -302,16 +302,16 @@ mod test {
OxcDiagnostic::warn("reversed range")
}
fn no_fix(span0: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("nofix").with_labels([span0.into()])
fn no_fix(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("nofix").with_labels([span])
}
fn no_fix_1(span0: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("nofix1").with_labels([span0.into()])
fn no_fix_1(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("nofix1").with_labels([span])
}
fn no_fix_2(span0: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("nofix2").with_labels([span0.into()])
fn no_fix_2(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("nofix2").with_labels([span])
}
const TEST_CODE: &str = "var answer = 6 * 7;";

View file

@ -1,5 +1,5 @@
use oxc_ast::AstKind;
use oxc_diagnostics::{LabeledSpan, OxcDiagnostic};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::Span;
@ -9,10 +9,7 @@ fn default_case_last_diagnostic(span0: Span) -> OxcDiagnostic {
OxcDiagnostic::warn(
"eslint(default-case-last): Enforce default clauses in switch statements to be last",
)
.with_labels([LabeledSpan::new_with_span(
Some("Default clause should be the last clause.".into()),
span0,
)])
.with_label(span0.label("Default clause should be the last clause."))
}
#[derive(Debug, Default, Clone)]

View file

@ -5,7 +5,7 @@ use oxc_ast::{
},
AstKind,
};
use oxc_diagnostics::{LabeledSpan, OxcDiagnostic};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::Span;
use oxc_syntax::operator::{AssignmentOperator, BinaryOperator, UnaryOperator, UpdateOperator};
@ -15,7 +15,10 @@ use crate::{context::LintContext, rule::Rule, AstNode};
fn for_direction_diagnostic(span0: Span, span1: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("eslint(for-direction): The update clause in this loop moves the variable in the wrong direction")
.with_help("Use while loop for intended infinite loop")
.with_labels([LabeledSpan::new_with_span(Some("This test moves in the wrong direction".into()), span0), LabeledSpan::new_with_span(Some("with this update".into()), span1)])
.with_labels([
span0.label("This test moves in the wrong direction"),
span1.label("with this update"),
])
}
#[derive(Debug, Default, Clone)]

View file

@ -1,4 +1,4 @@
use oxc_diagnostics::{LabeledSpan, OxcDiagnostic};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_semantic::SymbolId;
use oxc_span::Span;
@ -8,8 +8,8 @@ use crate::{context::LintContext, rule::Rule};
fn no_class_assign_diagnostic(x0: &str, span1: Span, span2: Span) -> OxcDiagnostic {
OxcDiagnostic::warn(format!("eslint(no-class-assign): Unexpected re-assignment of class {x0}"))
.with_labels([
LabeledSpan::new_with_span(Some(format!("{x0} is declared as class here")), span1),
LabeledSpan::new_with_span(Some(format!("{x0} is re-assigned here")), span2),
span1.label(format!("{x0} is declared as class here")),
span2.label(format!("{x0} is re-assigned here")),
])
}

View file

@ -1,4 +1,4 @@
use oxc_diagnostics::{LabeledSpan, OxcDiagnostic};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_semantic::SymbolId;
use oxc_span::Span;
@ -10,8 +10,8 @@ fn no_const_assign_diagnostic(x0: &str, span1: Span, span2: Span) -> OxcDiagnost
"eslint(no-const-assign): Unexpected re-assignment of const variable {x0}"
))
.with_labels([
LabeledSpan::new_with_span(Some(format!("{x0} is declared here as const")), span1),
LabeledSpan::new_with_span(Some(format!("{x0} is re-assigned here")), span2),
span1.label(format!("{x0} is declared here as const")),
span2.label(format!("{x0} is re-assigned here")),
])
}

View file

@ -1,4 +1,4 @@
use oxc_diagnostics::{LabeledSpan, OxcDiagnostic};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::Span;
use rustc_hash::FxHashMap;
@ -12,7 +12,10 @@ fn no_dupe_class_members_diagnostic(
) -> OxcDiagnostic {
OxcDiagnostic::warn(format!("eslint(no-dupe-class-members): Duplicate class member: {x0:?}"))
.with_help("The last declaration overwrites previous ones, remove one of them or rename if both should be retained")
.with_labels([LabeledSpan::new_with_span(Some(format!("{x0:?} is previously declared here")), span1), LabeledSpan::new_with_span(Some(format!("{x0:?} is re-declared here")), span2)])
.with_labels([
span1.label(format!("{x0:?} is previously declared here")),
span2.label(format!("{x0:?} is re-declared here")),
])
}
#[derive(Debug, Default, Clone)]

View file

@ -12,7 +12,7 @@ use crate::{ast_util::calculate_hash, context::LintContext, rule::Rule, AstNode}
fn no_dupe_else_if_diagnostic(span0: Span, span1: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("eslint(no-dupe-else-if): duplicate conditions in if-else-if chains")
.with_help("This branch can never execute. Its condition is a duplicate or covered by previous conditions in the if-else-if chain")
.with_labels([span0.into(), span1.into()])
.with_labels([span0, span1])
}
#[derive(Debug, Default, Clone)]

View file

@ -12,7 +12,7 @@ use crate::{context::LintContext, rule::Rule, AstNode};
fn no_dupe_keys_diagnostic(span0: Span, span1: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("eslint(no-dupe-keys): Disallow duplicate keys in object literals")
.with_help("Consider removing the duplicated key")
.with_labels([span0.into(), span1.into()])
.with_labels([span0, span1])
}
#[derive(Debug, Default, Clone)]

View file

@ -9,7 +9,7 @@ use crate::{ast_util::calculate_hash, context::LintContext, rule::Rule, AstNode}
fn no_duplicate_case_diagnostic(span0: Span, span1: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("eslint(no-duplicate-case): Disallow duplicate case labels")
.with_help("Remove the duplicated case")
.with_labels([span0.into(), span1.into()])
.with_labels([span0, span1])
}
#[derive(Debug, Default, Clone)]

View file

@ -1,5 +1,5 @@
use oxc_ast::AstKind;
use oxc_diagnostics::{LabeledSpan, OxcDiagnostic};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::Span;
@ -8,7 +8,7 @@ use crate::{context::LintContext, rule::Rule, AstNode};
fn no_empty_diagnostic(x0: &str, span1: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("eslint(no-empty): Disallow empty block statements")
.with_help(format!("Add comment inside empty {x0} statement"))
.with_labels([LabeledSpan::new_with_span(Some(format!("Empty {x0} statement")), span1)])
.with_label(span1.label(format!("Empty {x0} statement")))
}
#[derive(Debug, Default, Clone)]

View file

@ -1,5 +1,5 @@
use oxc_ast::AstKind;
use oxc_diagnostics::{LabeledSpan, OxcDiagnostic};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::Span;
@ -8,7 +8,9 @@ use crate::{context::LintContext, rule::Rule, AstNode};
fn no_empty_pattern_diagnostic(x0: &str, span1: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("eslint(no-empty-pattern): Disallow empty destructuring patterns.")
.with_help("Passing `null` or `undefined` will result in runtime error because `null` and `undefined` cannot be destructured.")
.with_labels([LabeledSpan::new_with_span(Some(format!("Empty {x0} binding pattern")), span1)])
.with_label(
span1.label(format!("Empty {x0} binding pattern")),
)
}
#[derive(Debug, Default, Clone)]

View file

@ -1,5 +1,5 @@
use oxc_ast::AstKind;
use oxc_diagnostics::{LabeledSpan, OxcDiagnostic};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_semantic::SymbolId;
use oxc_span::Span;
@ -8,7 +8,7 @@ use crate::{context::LintContext, rule::Rule};
fn no_func_assign_diagnostic(x0: &str, span1: Span) -> OxcDiagnostic {
OxcDiagnostic::warn(format!("eslint(no-func-assign): '{x0}' is a function."))
.with_labels([LabeledSpan::new_with_span(Some(format!("{x0} is re-assigned here")), span1)])
.with_label(span1.label(format!("{x0} is re-assigned here")))
}
#[derive(Debug, Default, Clone)]

View file

@ -1,4 +1,4 @@
use oxc_diagnostics::{LabeledSpan, OxcDiagnostic};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::{CompactStr, Span};
@ -8,10 +8,7 @@ fn no_global_assign_diagnostic(x0: &str, span1: Span) -> OxcDiagnostic {
OxcDiagnostic::warn(format!(
"eslint(no-global-assign): Read-only global '{x0}' should not be modified."
))
.with_labels([LabeledSpan::new_with_span(
Some(format!("Read-only global '{x0}' should not be modified.")),
span1,
)])
.with_label(span1.label(format!("Read-only global '{x0}' should not be modified.")))
}
#[derive(Debug, Default, Clone)]

View file

@ -2,7 +2,7 @@ use oxc_ast::{
ast::{BindingIdentifier, BindingPatternKind},
AstKind,
};
use oxc_diagnostics::{LabeledSpan, OxcDiagnostic};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::Span;
@ -10,8 +10,8 @@ use crate::{context::LintContext, rule::Rule};
fn no_redeclare_diagnostic(x0: &str, span1: Span, span2: Span) -> OxcDiagnostic {
OxcDiagnostic::warn(format!("eslint(no-redeclare): '{x0}' is already defined.")).with_labels([
LabeledSpan::new_with_span(Some(format!("'{x0}' is already defined.")), span1),
LabeledSpan::new_with_span(Some("It can not be redeclare here.".into()), span2),
span1.label(format!("'{x0}' is already defined.")),
span2.label("It can not be redeclare here."),
])
}
@ -19,21 +19,9 @@ fn no_redeclare_as_builti_in_diagnostic(x0: &str, span1: Span) -> OxcDiagnostic
OxcDiagnostic::warn(format!(
"eslint(no-redeclare): '{x0}' is already defined as a built-in global variable."
))
.with_labels([LabeledSpan::new_with_span(
Some(format!("'{x0}' is already defined as a built-in global variable.")),
span1,
)])
.with_label(span1.label(format!("'{x0}' is already defined as a built-in global variable.")))
}
// #[derive(Debug, Error, Diagnostic)]
// #[error("eslint(no-redeclare): '{0}' is already defined by a variable declaration.")]
// #[diagnostic(severity(warning))]
// struct NoRedeclareBySyntaxDiagnostic(
// String,
// #[label("'{0}' is already defined by a variable declaration.")] pub Span,
// #[label("It cannot be redeclared here.")] pub Span,
// );
#[derive(Debug, Default, Clone)]
pub struct NoRedeclare {
built_in_globals: bool,

View file

@ -10,7 +10,7 @@ fn no_self_compare_diagnostic(span0: Span, span1: Span) -> OxcDiagnostic {
"eslint(no-self-compare): Disallow comparisons where both sides are exactly the same",
)
.with_help("If you are testing for NaN, you can use Number.isNaN function.")
.with_labels([span0.into(), span1.into()])
.with_labels([span0, span1])
}
#[derive(Debug, Default, Clone)]

View file

@ -2,24 +2,20 @@ use oxc_ast::{
ast::{BindingPatternKind, Expression, Statement},
AstKind,
};
use oxc_diagnostics::{LabeledSpan, OxcDiagnostic};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::Span;
use crate::{context::LintContext, rule::Rule, AstNode};
fn no_useless_catch_diagnostic(span0: Span, span1: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("eslint(no-useless-catch): Unnecessary try/catch wrapper").with_labels([
LabeledSpan::new_with_span(Some("is caught here".into()), span0),
LabeledSpan::new_with_span(Some("and re-thrown here".into()), span1),
])
fn no_useless_catch_diagnostic(catch: Span, rethrow: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("eslint(no-useless-catch): Unnecessary try/catch wrapper")
.with_labels([catch.label("is caught here"), rethrow.label("and re-thrown here")])
}
fn no_useless_catch_finalizer_diagnostic(span0: Span, span1: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("eslint(no-useless-catch): Unnecessary catch clause").with_labels([
LabeledSpan::new_with_span(Some("is caught here".into()), span0),
LabeledSpan::new_with_span(Some("and re-thrown here".into()), span1),
])
fn no_useless_catch_finalizer_diagnostic(catch: Span, rethrow: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("eslint(no-useless-catch): Unnecessary catch clause")
.with_labels([catch.label("is caught here"), rethrow.label("and re-thrown here")])
}
#[derive(Debug, Default, Clone)]

View file

@ -1,15 +1,22 @@
use oxc_ast::{ast::Expression, AstKind};
use oxc_diagnostics::{LabeledSpan, OxcDiagnostic};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::{GetSpan, Span};
use oxc_syntax::operator::BinaryOperator;
use crate::{ast_util::is_method_call, context::LintContext, rule::Rule, AstNode};
fn bad_char_at_comparison_diagnostic(span0: Span, span1: Span, x2: usize) -> OxcDiagnostic {
fn bad_char_at_comparison_diagnostic(
char_at: Span,
compared_string: Span,
x2: usize,
) -> OxcDiagnostic {
OxcDiagnostic::warn("oxc(bad-char-at-comparison): Invalid comparison with `charAt` method")
.with_help("`String.prototype.charAt` returns a string of length 1. If the return value is compared with a string of length greater than 1, the comparison will always be false.")
.with_labels([LabeledSpan::new_with_span(Some("`charAt` called here".into()), span0), LabeledSpan::new_with_span(Some(format!("And compared with a string of length {x2} here")), span1)])
.with_labels([
char_at.label("`charAt` called here"),
compared_string.label(format!("And compared with a string of length {x2} here")),
])
}
#[derive(Debug, Default, Clone)]

View file

@ -2,7 +2,7 @@ use oxc_ast::{
ast::{Expression, RegExpFlags},
AstKind,
};
use oxc_diagnostics::{LabeledSpan, OxcDiagnostic};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::Span;
@ -16,7 +16,10 @@ use crate::{
fn bad_replace_all_arg_diagnostic(span0: Span, span1: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("oxc(bad-replace-all-arg): Global flag (g) is missing in the regular expression supplied to the `replaceAll` method.")
.with_help("To replace all occurrences of a string, use the `replaceAll` method with the global flag (g) in the regular expression.")
.with_labels([LabeledSpan::new_with_span(Some("`replaceAll` called here".into()), span0), LabeledSpan::new_with_span(Some("RegExp supplied here".into()), span1)])
.with_labels([
span0.label("`replaceAll` called here"),
span1.label("RegExp supplied here"),
])
}
#[derive(Debug, Default, Clone)]

View file

@ -5,7 +5,7 @@ use oxc_ast::{
ast::{Expression, NumericLiteral},
AstKind,
};
use oxc_diagnostics::{LabeledSpan, OxcDiagnostic};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::{GetSpan, Span};
use oxc_syntax::operator::{BinaryOperator, LogicalOperator};
@ -16,8 +16,8 @@ fn redundant_left_hand_side(span0: Span, span1: Span, x2: &str) -> OxcDiagnostic
OxcDiagnostic::warn("oxc(const-comparisons): Left-hand side of `&&` operator has no effect.")
.with_help(x2.to_string())
.with_labels([
LabeledSpan::new_with_span(Some("If this evaluates to `true`".into()), span0),
LabeledSpan::new_with_span(Some("This will always evaluate to true.".into()), span1),
span0.label("If this evaluates to `true`"),
span1.label("This will always evaluate to true."),
])
}
@ -25,8 +25,8 @@ fn redundant_right_hand_side(span0: Span, span1: Span, x2: &str) -> OxcDiagnosti
OxcDiagnostic::warn("oxc(const-comparisons): Right-hand side of `&&` operator has no effect.")
.with_help(x2.to_string())
.with_labels([
LabeledSpan::new_with_span(Some("If this evaluates to `true`".into()), span0),
LabeledSpan::new_with_span(Some("This will always evaluate to true.".into()), span1),
span0.label("If this evaluates to `true`"),
span1.label("This will always evaluate to true."),
])
}
@ -34,8 +34,8 @@ fn impossible(span0: Span, span1: Span, x2: &str, x3: &str, x4: &str) -> OxcDiag
OxcDiagnostic::warn("oxc(const-comparisons): Unexpected constant comparison")
.with_help(x4.to_string())
.with_labels([
LabeledSpan::new_with_span(Some(format!("Requires that {x2}")), span0),
LabeledSpan::new_with_span(Some(format!("Requires that {x3}")), span1),
span0.label(format!("Requires that {x2}")),
span1.label(format!("Requires that {x3}")),
])
}

View file

@ -2,7 +2,7 @@ use oxc_ast::{
ast::{Argument, BindingPatternKind, CallExpression, Expression},
AstKind,
};
use oxc_diagnostics::{LabeledSpan, OxcDiagnostic};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_semantic::SymbolId;
use oxc_span::Span;
@ -15,17 +15,30 @@ use crate::{
};
fn likely_array(span0: Span, span1: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("oxc(no-accumulating-spread): Do not spread accumulators in Array.prototype.reduce()").with_help("It looks like you're spreading an `Array`. Consider using the `Array.push` or `Array.concat` methods to mutate the accumulator instead.\nUsing spreads within accumulators leads to `O(n^2)` time complexity.").with_labels([LabeledSpan::new_with_span(Some("From this spread".into()), span0), LabeledSpan::new_with_span(Some("For this reduce".into()), span1)])
OxcDiagnostic::warn("oxc(no-accumulating-spread): Do not spread accumulators in Array.prototype.reduce()")
.with_help("It looks like you're spreading an `Array`. Consider using the `Array.push` or `Array.concat` methods to mutate the accumulator instead.\nUsing spreads within accumulators leads to `O(n^2)` time complexity.")
.with_labels([
span0.label("From this spread"),
span1.label("For this reduce")
])
}
fn likely_object(span0: Span, span1: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("oxc(no-accumulating-spread): Do not spread accumulators in Array.prototype.reduce()").with_help("It looks like you're spreading an `Object`. Consider using the `Object.assign` or assignment operators to mutate the accumulator instead.\nUsing spreads within accumulators leads to `O(n^2)` time complexity.").with_labels([LabeledSpan::new_with_span(Some("From this spread".into()), span0), LabeledSpan::new_with_span(Some("For this reduce".into()), span1)])
OxcDiagnostic::warn("oxc(no-accumulating-spread): Do not spread accumulators in Array.prototype.reduce()")
.with_help("It looks like you're spreading an `Object`. Consider using the `Object.assign` or assignment operators to mutate the accumulator instead.\nUsing spreads within accumulators leads to `O(n^2)` time complexity.")
.with_labels([
span0.label("From this spread"),
span1.label("For this reduce")
])
}
fn unknown(span0: Span, span1: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("oxc(no-accumulating-spread): Do not spread accumulators in Array.prototype.reduce()")
.with_help("Consider using `Object.assign()` or `Array.prototype.push()` to mutate the accumulator instead.\nUsing spreads within accumulators leads to `O(n^2)` time complexity.")
.with_labels([LabeledSpan::new_with_span(Some("From this spread".into()), span0), LabeledSpan::new_with_span(Some("For this reduce".into()), span1)])
.with_labels([
span0.label("From this spread"),
span1.label("For this reduce")
])
}
#[derive(Debug, Default, Clone)]

View file

@ -1,4 +1,4 @@
use oxc_diagnostics::{LabeledSpan, OxcDiagnostic};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_semantic::ModuleRecord;
use oxc_syntax::module_graph_visitor::{ModuleGraphVisitorBuilder, VisitFoldWhile};
@ -89,10 +89,7 @@ impl Rule for NoBarrelFile {
if let Some(remote_module) = module_record.loaded_modules.get(module_request.name()) {
if let Some(count) = count_loaded_modules(remote_module.value()) {
total += count;
labels.push(LabeledSpan::new_with_span(
Some(format!("{count} modules")),
module_request.span(),
));
labels.push(module_request.span().label(format!("{count} modules")));
}
};
}

View file

@ -2,7 +2,7 @@ use oxc_ast::{
ast::{Argument, MemberExpression},
AstKind,
};
use oxc_diagnostics::{LabeledSpan, OxcDiagnostic};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::{GetSpan, Span};
@ -14,11 +14,8 @@ fn uninvoked_array_callback_diagnostic(span0: Span, span1: Span) -> OxcDiagnosti
"consider filling the array with `undefined` values using `Array.prototype.fill()`",
)
.with_labels([
LabeledSpan::new_with_span(Some("this callback will not be invoked".into()), span0),
LabeledSpan::new_with_span(
Some("because this is an array with only empty slots".into()),
span1,
),
span0.label("this callback will not be invoked"),
span1.label("because this is an array with only empty slots"),
])
}

View file

@ -13,16 +13,16 @@ use crate::{
AstNode,
};
fn missing_property(span0: Span) -> OxcDiagnostic {
fn missing_property(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("eslint-plugin-react(checked-requires-onchange-or-readonly): `checked` should be used with either `onChange` or `readOnly`.")
.with_help("Add either `onChange` or `readOnly`.")
.with_label(span0)
.with_label(span)
}
fn exclusive_checked_attribute(span0: Span, span1: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("eslint-plugin-react(checked-requires-onchange-or-readonly): Use either `checked` or `defaultChecked`, but not both.")
.with_help("Remove either `checked` or `defaultChecked`.")
.with_labels([span0.into(), span1.into()])
.with_labels([span0, span1])
}
#[derive(Debug, Default, Clone)]

View file

@ -2,7 +2,7 @@ use oxc_ast::{
ast::{JSXAttributeItem, JSXAttributeName, JSXElement, JSXFragment, Statement},
AstKind,
};
use oxc_diagnostics::{LabeledSpan, OxcDiagnostic};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::{GetSpan, Span};
@ -16,7 +16,10 @@ fn missing_key_prop_for_element_in_array(span0: Span) -> OxcDiagnostic {
fn missing_key_prop_for_element_in_iterator(span0: Span, span1: Span) -> OxcDiagnostic {
OxcDiagnostic::warn(r#"eslint-plugin-react(jsx-key): Missing "key" prop for element in iterator."#)
.with_help(r#"Add a "key" prop to the element in the iterator (https://react.dev/learn/rendering-lists#keeping-list-items-in-order-with-key)."#)
.with_labels([LabeledSpan::new_with_span(Some("Iterator starts here".into()), span0), LabeledSpan::new_with_span(Some("Element generated here".into()), span1)])
.with_labels([
span0.label("Iterator starts here."),
span1.label("Element generated here."),
])
}
fn key_prop_must_be_placed_before_spread(span0: Span) -> OxcDiagnostic {

View file

@ -12,7 +12,7 @@ use crate::{context::LintContext, rule::Rule, AstNode};
fn jsx_no_duplicate_props_diagnostic(x0: &str, span1: Span, span2: Span) -> OxcDiagnostic {
OxcDiagnostic::warn(format!("eslint-plugin-react(jsx-no-duplicate-props): No duplicate props allowed. The prop \"{x0}\" is duplicated."))
.with_help("Remove one of the props, or rename them so each prop is distinct.")
.with_labels([span1.into(), span2.into()])
.with_labels([span1, span2])
}
#[derive(Debug, Default, Clone)]

View file

@ -2,7 +2,7 @@ use oxc_ast::{
ast::{ExportDefaultDeclarationKind, TSType},
AstKind,
};
use oxc_diagnostics::{LabeledSpan, OxcDiagnostic};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::Span;
@ -11,10 +11,7 @@ use crate::{context::LintContext, rule::Rule, AstNode};
fn consistent_type_definitions_diagnostic(x0: &str, x1: &str, span2: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("typescript-eslint(consistent-type-definitions):")
.with_help(format!("Use an `{x0}` instead of a `{x1}`"))
.with_labels([LabeledSpan::new_with_span(
Some(format!("Use an `{x0}` instead of a `{x1}`")),
span2,
)])
.with_label(span2.label(format!("Use an `{x0}` instead of a `{x1}`")))
}
#[derive(Debug, Default, Clone)]

View file

@ -11,7 +11,7 @@ fn no_duplicate_enum_values_diagnostic(span0: Span, span1: Span) -> OxcDiagnosti
"typescript-eslint(no-duplicate-enum-values): Disallow duplicate enum member values",
)
.with_help("Duplicate values can lead to bugs that are hard to track down")
.with_labels([span0.into(), span1.into()])
.with_labels([span0, span1])
}
#[derive(Debug, Default, Clone)]

View file

@ -11,7 +11,7 @@ use crate::{context::LintContext, rule::Rule, AstNode};
fn no_non_null_asserted_optional_chain_diagnostic(span0: Span, span1: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("typescript-eslint(no-non-null-asserted-optional-chain): non-null assertions after an optional chain expression")
.with_help("Optional chain expressions can return undefined by design - using a non-null assertion is unsafe and wrong. You should remove the non-null assertion.")
.with_labels([span0.into(), span1.into()])
.with_labels([span0, span1])
}
#[derive(Debug, Default, Clone)]

View file

@ -13,7 +13,7 @@ fn no_unnecessary_type_constraint_diagnostic(
) -> OxcDiagnostic {
OxcDiagnostic::warn(format!("typescript-eslint(no-unnecessary-type-constraint): constraining the generic type {x0:?} to {x1:?} does nothing and is unnecessary"))
.with_help(format!("Remove the unnecessary {x1:?} constraint"))
.with_labels([span2.into(), span3.into()])
.with_labels([span2, span3])
}
#[derive(Debug, Default, Clone)]

View file

@ -9,7 +9,7 @@ use crate::{context::LintContext, rule::Rule, AstNode};
fn no_unsafe_declaration_merging_diagnostic(span0: Span, span1: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("typescript-eslint(no-unsafe-declaration-merging): Unsafe declaration merging between classes and interfaces.")
.with_help("The TypeScript compiler doesn't check whether properties are initialized, which can cause lead to TypeScript not detecting code that will cause runtime errors.")
.with_labels([span0.into(), span1.into()])
.with_labels([span0, span1])
}
#[derive(Debug, Default, Clone)]

View file

@ -2,16 +2,19 @@ use oxc_ast::{
ast::{Argument, MemberExpression},
AstKind,
};
use oxc_diagnostics::{LabeledSpan, OxcDiagnostic};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::{GetSpan, Span};
use crate::{context::LintContext, rule::Rule, AstNode};
fn no_invalid_remove_event_listener_diagnostic(span0: Span, span1: Span) -> OxcDiagnostic {
fn no_invalid_remove_event_listener_diagnostic(call_span: Span, arg_span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("eslint-plugin-unicorn(no-invalid-remove-event-listener): Invalid `removeEventListener` call.")
.with_help("The listener argument should be a function reference.")
.with_labels([LabeledSpan::new_with_span(Some("`removeEventListener` called here.".into()), span0), LabeledSpan::new_with_span(Some("Invalid argument here".into()), span1)])
.with_labels([
call_span.label("`removeEventListener` called here."),
arg_span.label("Invalid argument here"),
])
}
#[derive(Debug, Default, Clone)]

View file

@ -8,7 +8,7 @@ use crate::{context::LintContext, rule::Rule, AstNode};
fn no_lonely_if_diagnostic(span0: Span, span1: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("eslint-plugin-unicorn(no-lonely-if): Unexpected `if` as the only statement in a `if` block without `else`.")
.with_help("Move the inner `if` test to the outer `if` test.")
.with_labels([span0.into(), span1.into()])
.with_labels([span0, span1])
}
#[derive(Debug, Default, Clone)]

View file

@ -23,8 +23,8 @@ source: crates/oxc_linter/src/tester.rs
╭─[jsx_key.tsx:1:11]
1 │ [1, 2 ,3].map(function(x) { return <App /> });
· ─┬─ ─┬─
· │ ╰── Element generated here
· ╰── Iterator starts here
· │ ╰── Element generated here.
· ╰── Iterator starts here.
╰────
help: Add a "key" prop to the element in the iterator (https://react.dev/learn/rendering-lists#keeping-list-items-in-order-with-key).
@ -32,8 +32,8 @@ source: crates/oxc_linter/src/tester.rs
╭─[jsx_key.tsx:1:11]
1 │ [1, 2 ,3].map(x => <App />);
· ─┬─ ─┬─
· │ ╰── Element generated here
· ╰── Iterator starts here
· │ ╰── Element generated here.
· ╰── Iterator starts here.
╰────
help: Add a "key" prop to the element in the iterator (https://react.dev/learn/rendering-lists#keeping-list-items-in-order-with-key).
@ -41,8 +41,8 @@ source: crates/oxc_linter/src/tester.rs
╭─[jsx_key.tsx:1:11]
1 │ [1, 2 ,3].map(x => x && <App x={x} />);
· ─┬─ ─┬─
· │ ╰── Element generated here
· ╰── Iterator starts here
· │ ╰── Element generated here.
· ╰── Iterator starts here.
╰────
help: Add a "key" prop to the element in the iterator (https://react.dev/learn/rendering-lists#keeping-list-items-in-order-with-key).
@ -50,8 +50,8 @@ source: crates/oxc_linter/src/tester.rs
╭─[jsx_key.tsx:1:11]
1 │ [1, 2 ,3].map(x => x ? <App x={x} key="1" /> : <OtherApp x={x} />);
· ─┬─ ────┬───
· │ ╰── Element generated here
· ╰── Iterator starts here
· │ ╰── Element generated here.
· ╰── Iterator starts here.
╰────
help: Add a "key" prop to the element in the iterator (https://react.dev/learn/rendering-lists#keeping-list-items-in-order-with-key).
@ -59,8 +59,8 @@ source: crates/oxc_linter/src/tester.rs
╭─[jsx_key.tsx:1:11]
1 │ [1, 2 ,3].map(x => x ? <App x={x} /> : <OtherApp x={x} key="2" />);
· ─┬─ ─┬─
· │ ╰── Element generated here
· ╰── Iterator starts here
· │ ╰── Element generated here.
· ╰── Iterator starts here.
╰────
help: Add a "key" prop to the element in the iterator (https://react.dev/learn/rendering-lists#keeping-list-items-in-order-with-key).
@ -68,8 +68,8 @@ source: crates/oxc_linter/src/tester.rs
╭─[jsx_key.tsx:1:11]
1 │ [1, 2 ,3].map(x => { return <App /> });
· ─┬─ ─┬─
· │ ╰── Element generated here
· ╰── Iterator starts here
· │ ╰── Element generated here.
· ╰── Iterator starts here.
╰────
help: Add a "key" prop to the element in the iterator (https://react.dev/learn/rendering-lists#keeping-list-items-in-order-with-key).
@ -77,8 +77,8 @@ source: crates/oxc_linter/src/tester.rs
╭─[jsx_key.tsx:1:7]
1 │ Array.from([1, 2 ,3], function(x) { return <App /> });
· ──┬─ ─┬─
· │ ╰── Element generated here
· ╰── Iterator starts here
· │ ╰── Element generated here.
· ╰── Iterator starts here.
╰────
help: Add a "key" prop to the element in the iterator (https://react.dev/learn/rendering-lists#keeping-list-items-in-order-with-key).
@ -86,8 +86,8 @@ source: crates/oxc_linter/src/tester.rs
╭─[jsx_key.tsx:1:7]
1 │ Array.from([1, 2 ,3], (x => { return <App /> }));
· ──┬─ ─┬─
· │ ╰── Element generated here
· ╰── Iterator starts here
· │ ╰── Element generated here.
· ╰── Iterator starts here.
╰────
help: Add a "key" prop to the element in the iterator (https://react.dev/learn/rendering-lists#keeping-list-items-in-order-with-key).
@ -95,8 +95,8 @@ source: crates/oxc_linter/src/tester.rs
╭─[jsx_key.tsx:1:7]
1 │ Array.from([1, 2 ,3], (x => <App />));
· ──┬─ ─┬─
· │ ╰── Element generated here
· ╰── Iterator starts here
· │ ╰── Element generated here.
· ╰── Iterator starts here.
╰────
help: Add a "key" prop to the element in the iterator (https://react.dev/learn/rendering-lists#keeping-list-items-in-order-with-key).
@ -104,8 +104,8 @@ source: crates/oxc_linter/src/tester.rs
╭─[jsx_key.tsx:1:12]
1 │ [1, 2, 3]?.map(x => <BabelEslintApp />)
· ─┬─ ───────┬──────
· │ ╰── Element generated here
· ╰── Iterator starts here
· │ ╰── Element generated here.
· ╰── Iterator starts here.
╰────
help: Add a "key" prop to the element in the iterator (https://react.dev/learn/rendering-lists#keeping-list-items-in-order-with-key).
@ -113,8 +113,8 @@ source: crates/oxc_linter/src/tester.rs
╭─[jsx_key.tsx:1:12]
1 │ [1, 2, 3]?.map(x => <TypescriptEslintApp />)
· ─┬─ ─────────┬─────────
· │ ╰── Element generated here
· ╰── Iterator starts here
· │ ╰── Element generated here.
· ╰── Iterator starts here.
╰────
help: Add a "key" prop to the element in the iterator (https://react.dev/learn/rendering-lists#keeping-list-items-in-order-with-key).
@ -122,8 +122,8 @@ source: crates/oxc_linter/src/tester.rs
╭─[jsx_key.tsx:1:12]
1 │ [1, 2, 3]?.map(x => <><OxcCompilerHello /></>)
· ─┬─ ─┬
· │ ╰── Element generated here
· ╰── Iterator starts here
· │ ╰── Element generated here.
· ╰── Iterator starts here.
╰────
help: Add a "key" prop to the element in the iterator (https://react.dev/learn/rendering-lists#keeping-list-items-in-order-with-key).
@ -131,8 +131,8 @@ source: crates/oxc_linter/src/tester.rs
╭─[jsx_key.tsx:1:11]
1 │ [1, 2, 3].map(x => <>{x}</>);
· ─┬─ ─┬
· │ ╰── Element generated here
· ╰── Iterator starts here
· │ ╰── Element generated here.
· ╰── Iterator starts here.
╰────
help: Add a "key" prop to the element in the iterator (https://react.dev/learn/rendering-lists#keeping-list-items-in-order-with-key).
@ -161,11 +161,11 @@ source: crates/oxc_linter/src/tester.rs
6 │ <div>
7 │ {list.map(item => {
· ─┬─
· ╰── Iterator starts here
· ╰── Iterator starts here.
8 │ if (item < 2) {
9 │ return <div>{item}</div>;
· ─┬─
· ╰── Element generated here
· ╰── Element generated here.
10 │ }
╰────
help: Add a "key" prop to the element in the iterator (https://react.dev/learn/rendering-lists#keeping-list-items-in-order-with-key).
@ -175,14 +175,14 @@ source: crates/oxc_linter/src/tester.rs
6 │ <div>
7 │ {list.map(item => {
· ─┬─
· ╰── Iterator starts here
· ╰── Iterator starts here.
8 │ if (item < 2) {
9 │ return <div>{item}</div>;
10 │ }
11 │
12 │ return <div />;
· ─┬─
· ╰── Element generated here
· ╰── Element generated here.
13 │ })}
╰────
help: Add a "key" prop to the element in the iterator (https://react.dev/learn/rendering-lists#keeping-list-items-in-order-with-key).
@ -192,11 +192,11 @@ source: crates/oxc_linter/src/tester.rs
6 │ <div>
7 │ {list.map(item => {
· ─┬─
· ╰── Iterator starts here
· ╰── Iterator starts here.
8 │ if (item < 2) {
9 │ return <div>{item}</div>;
· ─┬─
· ╰── Element generated here
· ╰── Element generated here.
10 │ } else if (item < 5) {
╰────
help: Add a "key" prop to the element in the iterator (https://react.dev/learn/rendering-lists#keeping-list-items-in-order-with-key).
@ -206,13 +206,13 @@ source: crates/oxc_linter/src/tester.rs
6 │ <div>
7 │ {list.map(item => {
· ─┬─
· ╰── Iterator starts here
· ╰── Iterator starts here.
8 │ if (item < 2) {
9 │ return <div>{item}</div>;
10 │ } else if (item < 5) {
11 │ return <div></div>
· ─┬─
· ╰── Element generated here
· ╰── Element generated here.
12 │ } else {
╰────
help: Add a "key" prop to the element in the iterator (https://react.dev/learn/rendering-lists#keeping-list-items-in-order-with-key).
@ -222,7 +222,7 @@ source: crates/oxc_linter/src/tester.rs
6 │ <div>
7 │ {list.map(item => {
· ─┬─
· ╰── Iterator starts here
· ╰── Iterator starts here.
8 │ if (item < 2) {
9 │ return <div>{item}</div>;
10 │ } else if (item < 5) {
@ -230,7 +230,7 @@ source: crates/oxc_linter/src/tester.rs
12 │ } else {
13 │ return <div></div>
· ─┬─
· ╰── Element generated here
· ╰── Element generated here.
14 │ }
╰────
help: Add a "key" prop to the element in the iterator (https://react.dev/learn/rendering-lists#keeping-list-items-in-order-with-key).
@ -240,14 +240,14 @@ source: crates/oxc_linter/src/tester.rs
6 │ <div>
7 │ {list.map(item => {
· ─┬─
· ╰── Iterator starts here
· ╰── Iterator starts here.
8 │ if (item < 2) {
╰────
╭─[jsx_key.tsx:16:33]
15 │
16 │ return <div />;
· ─┬─
· ╰── Element generated here
· ╰── Element generated here.
17 │ })}
╰────
help: Add a "key" prop to the element in the iterator (https://react.dev/learn/rendering-lists#keeping-list-items-in-order-with-key).
@ -257,10 +257,10 @@ source: crates/oxc_linter/src/tester.rs
6 │ <div>
7 │ {list.map(item => {
· ─┬─
· ╰── Iterator starts here
· ╰── Iterator starts here.
8 │ if (item < 2) return <div>{item}</div>;
· ─┬─
· ╰── Element generated here
· ╰── Element generated here.
9 │ else if (item < 5) return <div />;
╰────
help: Add a "key" prop to the element in the iterator (https://react.dev/learn/rendering-lists#keeping-list-items-in-order-with-key).
@ -270,11 +270,11 @@ source: crates/oxc_linter/src/tester.rs
6 │ <div>
7 │ {list.map(item => {
· ─┬─
· ╰── Iterator starts here
· ╰── Iterator starts here.
8 │ if (item < 2) return <div>{item}</div>;
9 │ else if (item < 5) return <div />;
· ─┬─
· ╰── Element generated here
· ╰── Element generated here.
10 │ else return <div />;
╰────
help: Add a "key" prop to the element in the iterator (https://react.dev/learn/rendering-lists#keeping-list-items-in-order-with-key).
@ -284,12 +284,12 @@ source: crates/oxc_linter/src/tester.rs
6 │ <div>
7 │ {list.map(item => {
· ─┬─
· ╰── Iterator starts here
· ╰── Iterator starts here.
8 │ if (item < 2) return <div>{item}</div>;
9 │ else if (item < 5) return <div />;
10 │ else return <div />;
· ─┬─
· ╰── Element generated here
· ╰── Element generated here.
11 │ })}
╰────
help: Add a "key" prop to the element in the iterator (https://react.dev/learn/rendering-lists#keeping-list-items-in-order-with-key).
@ -299,8 +299,8 @@ source: crates/oxc_linter/src/tester.rs
6 │ <div>
7 │ {list.map(item => <Text foo bar baz qux onClick={() => onClickHandler()} onPointerDown={() => onPointerDownHandler()} onMouseDown={() => onMouseDownHandler()} />)}
· ─┬─ ──┬─
· │ ╰── Element generated here
· ╰── Iterator starts here
· │ ╰── Element generated here.
· ╰── Iterator starts here.
8 │ </div>
╰────
help: Add a "key" prop to the element in the iterator (https://react.dev/learn/rendering-lists#keeping-list-items-in-order-with-key).
@ -310,8 +310,8 @@ source: crates/oxc_linter/src/tester.rs
6 │ <div>
7 │ {list.map(item => (<div>
· ─┬─ ─┬─
· │ ╰── Element generated here
· ╰── Iterator starts here
· │ ╰── Element generated here.
· ╰── Iterator starts here.
8 │ <Text foo bar baz qux onClick={() => onClickHandler()} onPointerDown={() => onPointerDownHandler()} onMouseDown={() => onMouseDownHandler()} />
╰────
help: Add a "key" prop to the element in the iterator (https://react.dev/learn/rendering-lists#keeping-list-items-in-order-with-key).

View file

@ -1,11 +1,11 @@
use oxc_diagnostics::{LabeledSpan, OxcDiagnostic};
use oxc_diagnostics::OxcDiagnostic;
use oxc_span::Span;
#[cold]
pub fn redeclaration(x0: &str, span1: Span, span2: Span) -> OxcDiagnostic {
pub fn redeclaration(x0: &str, declare_span: Span, redeclare_span: Span) -> OxcDiagnostic {
OxcDiagnostic::error(format!("Identifier `{x0}` has already been declared")).with_labels([
LabeledSpan::new_with_span(Some(format!("`{x0}` has already been declared here")), span1),
LabeledSpan::new_with_span(Some("It can not be redeclared here".to_string()), span2),
declare_span.label(format!("`{x0}` has already been declared here")),
redeclare_span.label("It can not be redeclared here"),
])
}
@ -25,9 +25,9 @@ pub fn unexpected_token(span0: Span) -> OxcDiagnostic {
}
#[cold]
pub fn expect_token(x0: &str, x1: &str, span2: Span) -> OxcDiagnostic {
pub fn expect_token(x0: &str, x1: &str, span: Span) -> OxcDiagnostic {
OxcDiagnostic::error(format!("Expected `{x0}` but found `{x1}`"))
.with_labels([LabeledSpan::new_with_span(Some(format!("`{x0}` expected")), span2)])
.with_label(span.label(format!("`{x0}` expected")))
}
#[cold]
@ -290,8 +290,8 @@ pub fn empty_parenthesized_expression(span0: Span) -> OxcDiagnostic {
#[cold]
pub fn illegal_newline(x0: &str, span1: Span, span2: Span) -> OxcDiagnostic {
OxcDiagnostic::error(format!("Illegal newline after {x0}")).with_labels([
LabeledSpan::new_with_span(Some(format!("{x0} starts here")), span1),
LabeledSpan::new_with_span(Some("A newline is not expected here".to_string()), span2),
span1.label(format!("{x0} starts here")),
span2.label("A newline is not expected here"),
])
}
@ -396,7 +396,7 @@ pub fn static_constructor(span0: Span) -> OxcDiagnostic {
#[cold]
pub fn jsx_element_no_match(span0: Span, span1: Span, name: &str) -> OxcDiagnostic {
OxcDiagnostic::error(format!("Expected corresponding JSX closing tag for '{name}'."))
.with_labels([span0.into(), span1.into()])
.with_labels([span0, span1])
}
#[cold]

View file

@ -58,8 +58,8 @@ fn undefined_export(x0: &str, span1: Span) -> OxcDiagnostic {
fn duplicate_export(x0: &str, span1: Span, span2: Span) -> OxcDiagnostic {
OxcDiagnostic::error(format!("Duplicated export '{x0}'")).with_labels([
LabeledSpan::new_with_span(Some("Export has already been declared here".into()), span1),
LabeledSpan::new_with_span(Some("It cannot be redeclared here".into()), span2),
span1.label("Export has already been declared here"),
span2.label("It cannot be redeclared here"),
])
}
@ -548,7 +548,10 @@ fn invalid_label_target(span0: Span) -> OxcDiagnostic {
fn invalid_label_non_iteration(x0: &str, span1: Span, span2: Span) -> OxcDiagnostic {
OxcDiagnostic::error(format!("A `{x0}` statement can only jump to a label of an enclosing `for`, `while` or `do while` statement."))
.with_labels([LabeledSpan::new_with_span(Some("This is an non-iteration statement".into()), span1), LabeledSpan::new_with_span(Some("for this label".into()), span2)])
.with_labels([
span1.label("This is an non-iteration statement"),
span2.label("for this label")
])
}
fn check_label(label: &LabelIdentifier, ctx: &SemanticBuilder, is_continue: bool) {
@ -1068,12 +1071,8 @@ fn is_in_formal_parameters<'a>(node: &AstNode<'a>, ctx: &SemanticBuilder<'a>) ->
}
fn await_or_yield_in_parameter(x0: &str, span1: Span) -> OxcDiagnostic {
OxcDiagnostic::error(format!("{x0} expression not allowed in formal parameter")).with_labels([
LabeledSpan::new_with_span(
Some(format!("{x0} expression not allowed in formal parameter")),
span1,
),
])
OxcDiagnostic::error(format!("{x0} expression not allowed in formal parameter"))
.with_label(span1.label(format!("{x0} expression not allowed in formal parameter")))
}
pub fn check_await_expression<'a>(

View file

@ -1,9 +1,9 @@
use oxc_diagnostics::{LabeledSpan, OxcDiagnostic};
use oxc_diagnostics::OxcDiagnostic;
use oxc_span::Span;
pub fn redeclaration(x0: &str, span1: Span, span2: Span) -> OxcDiagnostic {
OxcDiagnostic::error(format!("Identifier `{x0}` has already been declared")).with_labels([
LabeledSpan::new_with_span(Some(format!("`{x0}` has already been declared here")), span1),
LabeledSpan::new_with_span(Some("It can not be redeclared here".into()), span2),
span1.label(format!("`{x0}` has already been declared here")),
span2.label("It can not be redeclared here"),
])
}

View file

@ -275,6 +275,12 @@ impl Span {
pub fn source_text<'a>(&self, source_text: &'a str) -> &'a str {
&source_text[self.start as usize..self.end as usize]
}
/// Create a [`LabeledSpan`] covering this [`Span`] with the given label.
#[must_use]
pub fn label<S: Into<String>>(self, label: S) -> LabeledSpan {
LabeledSpan::new_with_span(Some(label.into()), self)
}
}
impl Index<Span> for str {

View file

@ -21,16 +21,16 @@ pub fn invalid_import_source() -> OxcDiagnostic {
.with_help("Fix `importSource` option.")
}
pub fn namespace_does_not_support(span0: Span) -> OxcDiagnostic {
pub fn namespace_does_not_support(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("Namespace tags are not supported by default. React's JSX doesn't support namespace tags. You can set `throwIfNamespace: false` to bypass this warning.")
.with_labels([span0.into()])
.with_label(span)
}
pub fn valueless_key(span0: Span) -> OxcDiagnostic {
pub fn valueless_key(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("Please provide an explicit key value. Using \"key\" as a shorthand for \"key={true}\" is not allowed.")
.with_labels([span0.into()])
.with_label(span)
}
pub fn spread_children_are_not_supported(span0: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("Spread children are not supported in React.").with_labels([span0.into()])
pub fn spread_children_are_not_supported(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("Spread children are not supported in React.").with_label(span)
}

View file

@ -1,14 +1,14 @@
use oxc_diagnostics::OxcDiagnostic;
use oxc_span::Span;
pub fn import_equals_require_unsupported(span0: Span) -> OxcDiagnostic {
pub fn import_equals_require_unsupported(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("`import lib = require(...);` is only supported when compiling modules to CommonJS.\nPlease consider using `import lib from '...';` alongside Typescript's --allowSyntheticDefaultImports option, or add @babel/plugin-transform-modules-commonjs to your Babel config.")
.with_labels([span0.into()])
.with_label(span)
}
pub fn export_assignment_unsupported(span0: Span) -> OxcDiagnostic {
pub fn export_assignment_unsupported(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("`export = <value>;` is only supported when compiling modules to CommonJS.\nPlease consider using `export default <value>;`, or add @babel/plugin-transform-modules-commonjs to your Babel config.")
.with_labels([span0.into()])
.with_label(span)
}
pub fn ambient_module_nested(span0: Span) -> OxcDiagnostic {