mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 04:08:41 +00:00
refactor(linter): improve diagnostic labeling (#3960)
This commit is contained in:
parent
f64ad4b7c2
commit
2705df93b3
41 changed files with 217 additions and 201 deletions
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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")))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;";
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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")),
|
||||
])
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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")),
|
||||
])
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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}")),
|
||||
])
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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")));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"),
|
||||
])
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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).
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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>(
|
||||
|
|
|
|||
|
|
@ -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"),
|
||||
])
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
Loading…
Reference in a new issue