Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/oxc_linter/src/fixer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ impl<'c, 'a: 'c> RuleFixer<'c, 'a> {

/// Creates a fix command that inserts text at the specified index in the source text.
fn insert_text_at(&self, index: u32, text: Cow<'a, str>) -> RuleFix<'a> {
let fix = Fix::new(text, Span::new(index, index));
let fix = Fix::new(text, Span::empty(index));
let content = self.possibly_truncate_snippet(&fix.content);
let message = self.auto_message.then(|| Cow::Owned(format!("Insert `{content}`")));
self.new_fix(CompositeFix::Single(fix), message)
Expand Down
4 changes: 1 addition & 3 deletions crates/oxc_linter/src/rules/eslint/curly.rs
Original file line number Diff line number Diff line change
Expand Up @@ -332,9 +332,7 @@ fn is_collapsed_one_liner(node: &Statement, ctx: &LintContext) -> bool {
ctx.nodes()
.parent_node(node.id())
.filter(|parent| parent.span().start < span.start)
.map_or(Span::new(0, 0), |parent| {
Span::new(parent.span().start, parent.span().start)
})
.map_or(Span::empty(0), |parent| Span::empty(parent.span().start))
},
oxc_span::GetSpan::span,
);
Expand Down
4 changes: 2 additions & 2 deletions crates/oxc_linter/src/rules/eslint/default_case_last.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,9 @@ impl Rule for DefaultCaseLast {
if let Some(index) = index_of_default {
if index != cases.len() - 1 {
let default_clause = &cases[index];
ctx.diagnostic(default_case_last_diagnostic(Span::new(
ctx.diagnostic(default_case_last_diagnostic(Span::sized(
default_clause.span.start,
default_clause.span.start + 7,
7,
)));
}
}
Expand Down
2 changes: 1 addition & 1 deletion crates/oxc_linter/src/rules/eslint/max_lines.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ impl Rule for MaxLines {
if final_lines > self.max {
// Point to end of the file for `eslint-disable max-lines` to work.
let end = ctx.source_text().len().saturating_sub(1) as u32;
ctx.diagnostic(max_lines_diagnostic(final_lines, self.max, Span::new(end, end)));
ctx.diagnostic(max_lines_diagnostic(final_lines, self.max, Span::empty(end)));
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion crates/oxc_linter/src/rules/eslint/no_await_in_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ impl Rule for NoAwaitInLoop {
Span::new(for_of_stmt.span.start + 4, for_of_stmt.span.start + 9)
}
// only highlight the 'await' keyword
AstKind::AwaitExpression(expr) => Span::new(expr.span.start, expr.span.start + 5),
AstKind::AwaitExpression(expr) => Span::sized(expr.span.start, 5),
// other node type, return
_ => return,
};
Expand Down
5 changes: 1 addition & 4 deletions crates/oxc_linter/src/rules/eslint/no_continue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,7 @@ declare_oxc_lint!(
impl Rule for NoContinue {
fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {
if let AstKind::ContinueStatement(continue_statement) = node.kind() {
ctx.diagnostic(no_continue_diagnostic(Span::new(
continue_statement.span.start,
continue_statement.span.start + 8,
)));
ctx.diagnostic(no_continue_diagnostic(Span::sized(continue_statement.span.start, 8)));
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions crates/oxc_linter/src/rules/eslint/no_invalid_regexp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,28 +108,28 @@ impl Rule for NoInvalidRegexp {
if ch == 'u' {
if v_flag_found {
return ctx
.diagnostic(invalid_unicode_flags_diagnostic(Span::new(start, start)));
.diagnostic(invalid_unicode_flags_diagnostic(Span::empty(start)));
}
u_flag_found = true;
}
if ch == 'v' {
if u_flag_found {
return ctx
.diagnostic(invalid_unicode_flags_diagnostic(Span::new(start, start)));
.diagnostic(invalid_unicode_flags_diagnostic(Span::empty(start)));
}
v_flag_found = true;
}

// Duplicated: user defined, invalid or valid
if !unique_flags.insert(ch) {
return ctx.diagnostic(duplicated_flag_diagnostic(Span::new(start, start)));
return ctx.diagnostic(duplicated_flag_diagnostic(Span::empty(start)));
}

// Unknown: not valid, not user defined
if !(matches!(ch, 'd' | 'g' | 'i' | 'm' | 's' | 'u' | 'v' | 'y')
|| self.0.allow_constructor_flags.contains(&ch))
{
return ctx.diagnostic(unknown_flag_diagnostic(Span::new(start, start)));
return ctx.diagnostic(unknown_flag_diagnostic(Span::empty(start)));
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion crates/oxc_linter/src/rules/eslint/no_label_var.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ impl Rule for NoLabelVar {
ctx.diagnostic(no_label_var_diagnostic(
&labeled_stmt.label.name,
decl_span,
Span::new(label_decl, label_decl + 1),
Span::sized(label_decl, 1),
));
}
}
Expand Down
5 changes: 1 addition & 4 deletions crates/oxc_linter/src/rules/eslint/no_multi_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,7 @@ impl Rule for NoMultiStr {
// character.
let multi_span_start =
literal.span.start + u32::try_from(position).unwrap_or_default() - 1;
ctx.diagnostic(no_multi_str_diagnostic(Span::new(
multi_span_start,
multi_span_start + 1,
)));
ctx.diagnostic(no_multi_str_diagnostic(Span::sized(multi_span_start, 1)));
}
}
}
Expand Down
5 changes: 1 addition & 4 deletions crates/oxc_linter/src/rules/eslint/no_proto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,7 @@ impl Rule for NoProto {
};
if let Some(static_property_name) = member_expression.static_property_name() {
if static_property_name == "__proto__" {
ctx.diagnostic(no_proto_diagnostic(Span::new(
member_expression.span().start,
member_expression.span().end,
)));
ctx.diagnostic(no_proto_diagnostic(member_expression.span()));
}
}
}
Expand Down
8 changes: 2 additions & 6 deletions crates/oxc_linter/src/rules/eslint/no_script_url.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ impl Rule for NoScriptUrl {
AstKind::StringLiteral(literal)
if literal.value.cow_to_ascii_lowercase().starts_with("javascript:") =>
{
emit_diagnostic(ctx, literal.span);
ctx.diagnostic(no_script_url_diagnostic(literal.span));
}
AstKind::TemplateLiteral(literal)
if !is_tagged_template_expression(ctx, node, literal.span) =>
Expand All @@ -63,18 +63,14 @@ impl Rule for NoScriptUrl {
.cow_to_ascii_lowercase()
.starts_with("javascript:")
{
emit_diagnostic(ctx, literal.span);
ctx.diagnostic(no_script_url_diagnostic(literal.span));
}
}
_ => {}
}
}
}

fn emit_diagnostic(ctx: &LintContext, span: Span) {
ctx.diagnostic(no_script_url_diagnostic(Span::new(span.start, span.end)));
}

fn is_tagged_template_expression(ctx: &LintContext, node: &AstNode, literal_span: Span) -> bool {
matches!(
ctx.nodes().parent_kind(node.id()),
Expand Down
5 changes: 1 addition & 4 deletions crates/oxc_linter/src/rules/eslint/no_ternary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,7 @@ declare_oxc_lint!(
impl Rule for NoTernary {
fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {
if let AstKind::ConditionalExpression(cond_expr) = node.kind() {
ctx.diagnostic(no_ternary_diagnostic(Span::new(
cond_expr.span.start,
cond_expr.span.end,
)));
ctx.diagnostic(no_ternary_diagnostic(cond_expr.span));
}
}
}
Expand Down
14 changes: 4 additions & 10 deletions crates/oxc_linter/src/rules/eslint/no_var.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,10 @@ impl Rule for NoVar {
if let AstKind::VariableDeclaration(dec) = node.kind() {
if dec.kind == VariableDeclarationKind::Var {
let is_written_to = dec.declarations.iter().any(|v| is_written_to(&v.id, ctx));

ctx.diagnostic_with_fix(
no_var_diagnostic(Span::new(dec.span.start, dec.span.start + 3)),
|fixer| {
fixer.replace(
Span::new(dec.span.start, dec.span.start + 3),
if is_written_to { "let" } else { "const" },
)
},
);
let span = Span::sized(dec.span.start, 3);
ctx.diagnostic_with_fix(no_var_diagnostic(span), |fixer| {
fixer.replace(span, if is_written_to { "let" } else { "const" })
});
}
}
}
Expand Down
5 changes: 1 addition & 4 deletions crates/oxc_linter/src/rules/eslint/no_with.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,7 @@ declare_oxc_lint!(
impl Rule for NoWith {
fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {
if let AstKind::WithStatement(with_statement) = node.kind() {
ctx.diagnostic(no_with_diagnostic(Span::new(
with_statement.span.start,
with_statement.span.start + 4,
)));
ctx.diagnostic(no_with_diagnostic(Span::sized(with_statement.span.start, 4)));
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion crates/oxc_linter/src/rules/eslint/radix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ impl Radix {
.unwrap_or(", 10");

ctx.diagnostic_with_dangerous_fix(missing_radix(call_expr.span), |fixer| {
fixer.insert_text_before_range(Span::new(end - 1, end - 1), insert_param)
fixer.insert_text_before_range(Span::empty(end - 1), insert_param)
});
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ impl Rule for ConsistentTypeSpecifierStyle {
.find("type")
.map(|pos| {
let start = import_decl.span.start + pos as u32;
Span::new(start, start + 4)
Span::sized(start, 4)
})
{
let remove_fix = fixer.delete_range(type_token_span);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ impl Rule for NoEmptyNamedBlocks {
let Some(end) = source_token_str[start..].find("from") else { return };

let start = span.start + start as u32;
let span = Span::new(start, start + end as u32);
let span = Span::sized(start, end as u32);

ctx.diagnostic_with_fix(no_empty_named_blocks_diagnostic(import_decl.span), |fixer| {
if start == specifier.span.end {
Expand Down
4 changes: 2 additions & 2 deletions crates/oxc_linter/src/rules/jest/no_focused_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,9 @@ fn run<'a>(possible_jest_node: &PossibleJestNode<'a, '_>, ctx: &LintContext<'a>)

if name.starts_with('f') {
ctx.diagnostic_with_fix(
no_focused_tests_diagnostic(Span::new(
no_focused_tests_diagnostic(Span::sized(
call_expr.span.start,
call_expr.span.start + u32::try_from(name.len()).unwrap_or(1),
u32::try_from(name.len()).unwrap_or(1),
)),
|fixer| fixer.delete_range(Span::sized(call_expr.span.start, 1)),
);
Expand Down
2 changes: 1 addition & 1 deletion crates/oxc_linter/src/rules/oxc/no_const_enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ impl Rule for NoConstEnum {
return;
}

let span = Span::new(enum_decl.span.start, enum_decl.span.start + 5);
let span = Span::sized(enum_decl.span.start, 5);

ctx.diagnostic_with_fix(no_const_enum_diagnostic(span), |fixer| {
// const enum Color { Red, Green, Blue }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ impl Rule for NoUnescapedEntities {
#[expect(clippy::cast_possible_truncation)]
let start = jsx_text.span.start + i as u32;
ctx.diagnostic(no_unescaped_entities_diagnostic(
Span::new(start, start + 1),
Span::sized(start, 1),
byte as char,
));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ impl GetMethod for TSSignature<'_> {
r#static: false,
call_signature: false,
kind: MethodKind::Normal,
span: Span::new(decl.span.start, decl.span.start + 3),
span: Span::sized(decl.span.start, 3),
}),
_ => None,
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ impl Rule for ConsistentTypeDefinitions {
consistent_type_definitions_diagnostic(
"type",
"interface",
Span::new(decl.span.start, decl.span.start + 9),
Span::sized(decl.span.start, 9),
),
|fixer| {
fixer.replace(
Expand Down Expand Up @@ -229,7 +229,7 @@ impl Rule for ConsistentTypeDefinitions {
consistent_type_definitions_diagnostic(
"type",
"interface",
Span::new(start, start + 9),
Span::sized(start, 9),
),
|fixer| {
fixer.replace(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -502,10 +502,9 @@ fn fix_to_type_import_declaration<'a>(options: &FixOptions<'a, '_>) -> FixerResu
if type_names.len() == import_decl.specifiers.as_ref().map_or(0, |s| s.len()) {
// import type Type from 'foo'
// ^^^^^ insert
rule_fixes.push(fixer.insert_text_after(
&Span::new(import_decl.span().start, import_decl.span().start + 6),
" type",
));
rule_fixes.push(
fixer.insert_text_after(&Span::sized(import_decl.span().start, 6), " type"),
);
} else {
let import_text = ctx.source_range(import_decl.span);
// import Type, { Foo } from 'foo'
Expand Down Expand Up @@ -556,8 +555,7 @@ fn fix_insert_named_specifiers_in_named_specifier_list<'a>(
let first_non_whitespace_before_close_brace =
import_text[..close_brace as usize].chars().rev().find(|c| !c.is_whitespace());

let span =
Span::new(import_decl.span().start + close_brace, import_decl.span().start + close_brace);
let span = Span::empty(import_decl.span().start + close_brace);
if first_non_whitespace_before_close_brace.is_some_and(|ch| !matches!(ch, ',' | '{')) {
Ok(fixer.insert_text_before(&span, format!(",{insert_text}")))
} else {
Expand Down Expand Up @@ -800,9 +798,7 @@ fn fix_insert_type_specifier_for_import_declaration<'a>(

// "import { Foo, Bar } from 'foo'" => "import type { Foo, Bar } from 'foo'"
// ^^^^ add
rule_fixes.push(
fixer.replace(Span::new(import_decl.span.start, import_decl.span.start + 6), "import type"),
);
rule_fixes.push(fixer.replace(Span::sized(import_decl.span.start, 6), "import type"));

if is_default_import {
if let Ok(_opening_brace_token) = try_find_char(import_source, '{') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ impl Rule for NoExtraNonNullAssertion {

if let Some(expr) = expr {
let end = expr.span.end - 1;
ctx.diagnostic(no_extra_non_null_assertion_diagnostic(Span::new(end, end)));
ctx.diagnostic(no_extra_non_null_assertion_diagnostic(Span::empty(end)));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,10 +113,7 @@ impl Rule for NoImportTypeSideEffects {
// import type A from 'foo.js'
// ^^^^ add
if raw.starts_with("import") {
fix.push(Fix::new(
"import type",
Span::new(import_decl.span.start, import_decl.span.start + 6),
));
fix.push(Fix::new("import type", Span::sized(import_decl.span.start, 6)));
}

for specifier in type_specifiers {
Expand Down
4 changes: 2 additions & 2 deletions crates/oxc_linter/src/rules/typescript/no_misused_new.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,9 @@ impl Rule for NoMisusedNew {
};
if let TSTypeName::IdentifierReference(id) = &type_ref.type_name {
if id.name == decl_name {
ctx.diagnostic(no_misused_new_interface_diagnostic(Span::new(
ctx.diagnostic(no_misused_new_interface_diagnostic(Span::sized(
sig.span.start,
sig.span.start + 3,
3,
)));
}
}
Expand Down
12 changes: 6 additions & 6 deletions crates/oxc_linter/src/rules/typescript/no_namespace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,12 +161,12 @@ impl Rule for NoNamespace {

let span = match declaration.kind {
TSModuleDeclarationKind::Global => None, // handled above
TSModuleDeclarationKind::Module => declaration_code.find("module").map(|i| {
Span::new(declaration.span.start + i as u32, declaration.span.start + i as u32 + 6)
}),
TSModuleDeclarationKind::Namespace => declaration_code.find("namespace").map(|i| {
Span::new(declaration.span.start + i as u32, declaration.span.start + i as u32 + 9)
}),
TSModuleDeclarationKind::Module => declaration_code
.find("module")
.map(|i| Span::sized(declaration.span.start + i as u32, 6)),
TSModuleDeclarationKind::Namespace => declaration_code
.find("namespace")
.map(|i| Span::sized(declaration.span.start + i as u32, 9)),
};
if let Some(span) = span {
ctx.diagnostic(no_namespace_diagnostic(span));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ impl Rule for NoAwaitInPromiseMethods {
.expect("callee is a static property");

ctx.diagnostic(no_await_in_promise_methods_diagnostic(
Span::new(await_expr.span.start, await_expr.span.start + 5),
Span::sized(await_expr.span.start, 5),
property_name,
));
}
Expand Down
4 changes: 2 additions & 2 deletions crates/oxc_linter/src/rules/unicorn/no_lonely_if.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ impl Rule for NoLonelyIf {
};

ctx.diagnostic(no_lonely_if_diagnostic(
Span::new(if_stmt.span.start, if_stmt.span.start + 2),
Span::new(parent_if_stmt_span.start, parent_if_stmt_span.start + 2),
Span::sized(if_stmt.span.start, 2),
Span::sized(parent_if_stmt_span.start, 2),
));
}
}
Expand Down
Loading
Loading