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
13 changes: 6 additions & 7 deletions crates/oxc_linter/src/ast_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ pub fn get_enclosing_function<'a, 'b>(
{
return Some(current_node);
}
current_node = semantic.nodes().parent_node(current_node.id())?;
current_node = semantic.nodes().parent_node(current_node.id());
}
}

Expand All @@ -222,11 +222,10 @@ pub fn outermost_paren<'a, 'b>(
let mut node = node;

loop {
if let Some(parent) = semantic.nodes().parent_node(node.id()) {
if let AstKind::ParenthesizedExpression(_) = parent.kind() {
node = parent;
continue;
}
let parent = semantic.nodes().parent_node(node.id());
if let AstKind::ParenthesizedExpression(_) = parent.kind() {
node = parent;
continue;
}

break;
Expand Down Expand Up @@ -652,7 +651,7 @@ pub fn is_default_this_binding<'a>(

let mut current_node = node;
loop {
let parent = semantic.nodes().parent_node(current_node.id()).unwrap();
let parent = semantic.nodes().parent_node(current_node.id());
let parent_kind = parent.kind();
match parent_kind {
AstKind::ChainExpression(_)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,8 @@ impl Rule for ArrayCallbackReturn {
/// to the target array methods we're interested in.
pub fn get_array_method_name<'a>(node: &AstNode<'a>, ctx: &LintContext<'a>) -> Option<&'a str> {
let mut current_node = node;
while let Some(parent) = ctx.nodes().parent_node(current_node.id()) {
loop {
let parent = ctx.nodes().parent_node(current_node.id());
match parent.kind() {
// foo.every(nativeFoo || function foo() { ... })
AstKind::LogicalExpression(_)
Expand All @@ -174,7 +175,7 @@ pub fn get_array_method_name<'a>(node: &AstNode<'a>, ctx: &LintContext<'a>) -> O
let func_node = outermost_paren(func_node, ctx);

// the node that calls func_node
let func_parent = ctx.nodes().parent_node(func_node.id()).unwrap();
let func_parent = ctx.nodes().parent_node(func_node.id());

if let AstKind::CallExpression(call) = func_parent.kind() {
let expected_callee = &call.callee;
Expand Down
19 changes: 11 additions & 8 deletions crates/oxc_linter/src/rules/eslint/curly.rs
Original file line number Diff line number Diff line change
Expand Up @@ -293,10 +293,10 @@ fn report_if_needed<'a>(
let fixed = format!("{{{}}}", ctx.source_range(body.span()));
fixer.replace(body.span(), fixed)
} else {
let needs_preceding_space = ctx
.nodes()
.parent_node(get_node_by_statement(body, ctx).id())
.is_some_and(|parent| matches!(parent.kind(), AstKind::DoWhileStatement(_)));
let needs_preceding_space = matches!(
ctx.nodes().parent_kind(get_node_by_statement(body, ctx).id()),
AstKind::DoWhileStatement(_)
);
let mut fixed = ctx.source_range(body.span()).to_string();

if let Some(stripped) = fixed.strip_prefix(|c: char| c.is_whitespace() || c == '{') {
Expand Down Expand Up @@ -329,10 +329,13 @@ fn is_collapsed_one_liner(node: &Statement, ctx: &LintContext) -> bool {

let before_node_span = get_token_before(node, ctx).map_or_else(
|| {
ctx.nodes()
.parent_node(node.id())
.filter(|parent| parent.span().start < span.start)
.map_or(Span::empty(0), |parent| Span::empty(parent.span().start))
let parent = ctx.nodes().parent_node(node.id());

if parent.span().start < span.start {
Span::empty(parent.span().start)
} else {
Span::empty(0)
}
},
oxc_span::GetSpan::span,
);
Expand Down
4 changes: 1 addition & 3 deletions crates/oxc_linter/src/rules/eslint/func_names.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,9 +248,7 @@ impl Rule for FuncNames {
match node.kind() {
// check function if it invalid, do not report it because maybe later the function is calling itself
AstKind::Function(func) => {
let Some(parent_node) = ctx.nodes().parent_node(node.id()) else {
continue;
};
let parent_node = ctx.nodes().parent_node(node.id());
let config =
if func.generator { &self.generators_config } else { &self.default_config };

Expand Down
10 changes: 3 additions & 7 deletions crates/oxc_linter/src/rules/eslint/func_style.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,9 +232,7 @@ impl Rule for FuncStyle {
for node in semantic.nodes() {
match node.kind() {
AstKind::Function(func) => {
let Some(parent) = semantic.nodes().parent_node(node.id()) else {
continue;
};
let parent = semantic.nodes().parent_node(node.id());
match func.r#type {
FunctionType::FunctionDeclaration => {
// There are two situations to diagnostic
Expand Down Expand Up @@ -301,7 +299,7 @@ impl Rule for FuncStyle {
.ancestors(node.id())
.skip(1)
.find(|v| matches!(v.kind(), AstKind::FunctionBody(_)))
.map(|el| semantic.nodes().parent_node(el.id()).unwrap());
.map(|el| semantic.nodes().parent_node(el.id()));
if let Some(ret) = arrow_func_ancestor {
arrow_func_ancestor_records.insert(ret.id());
}
Expand All @@ -317,9 +315,7 @@ impl Rule for FuncStyle {
// We deal with arrow functions that do not contain this and super
for node in arrow_func_nodes {
if !arrow_func_ancestor_records.contains(&node.id()) {
let Some(parent) = semantic.nodes().parent_node(node.id()) else {
return;
};
let parent = semantic.nodes().parent_node(node.id());
if let AstKind::VariableDeclarator(decl) = parent.kind() {
let is_type_annotation =
self.allow_type_annotation && decl.id.type_annotation.is_some();
Expand Down
34 changes: 17 additions & 17 deletions crates/oxc_linter/src/rules/eslint/getter_return.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,66 +147,66 @@ impl GetterReturn {
}

/// Checks whether it is necessary to check the node
fn is_wanted_node(node: &AstNode, ctx: &LintContext<'_>) -> Option<bool> {
let parent = ctx.nodes().parent_node(node.id())?;
fn is_wanted_node(node: &AstNode, ctx: &LintContext<'_>) -> bool {
let parent = ctx.nodes().parent_node(node.id());
match parent.kind() {
AstKind::MethodDefinition(mdef) => {
if matches!(mdef.kind, MethodDefinitionKind::Get) {
return Some(true);
return true;
}
}
AstKind::ObjectProperty(ObjectProperty { kind, key: prop_key, .. }) => {
if matches!(kind, PropertyKind::Get) {
return Some(true);
return true;
}
if prop_key.name().is_some_and(|key| key != "get") {
return Some(false);
return false;
}

let parent_2 = ctx.nodes().parent_node(parent.id())?;
let parent_3 = ctx.nodes().parent_node(parent_2.id())?;
let parent_4 = ctx.nodes().parent_node(parent_3.id())?;
let parent_2 = ctx.nodes().parent_node(parent.id());
let parent_3 = ctx.nodes().parent_node(parent_2.id());
let parent_4 = ctx.nodes().parent_node(parent_3.id());
// handle (X())
match parent_4.kind() {
AstKind::ParenthesizedExpression(p) => {
if Self::handle_paren_expr(&p.expression) {
return Some(true);
return true;
}
}
AstKind::CallExpression(ce) => {
if Self::handle_actual_expression(&ce.callee) {
return Some(true);
return true;
}
}
_ => {}
}

let parent_5 = ctx.nodes().parent_node(parent_4.id())?;
let parent_6 = ctx.nodes().parent_node(parent_5.id())?;
let parent_5 = ctx.nodes().parent_node(parent_4.id());
let parent_6 = ctx.nodes().parent_node(parent_5.id());
match parent_6.kind() {
AstKind::ParenthesizedExpression(p) => {
if Self::handle_paren_expr(&p.expression) {
return Some(true);
return true;
}
}
AstKind::CallExpression(ce) => {
if Self::handle_actual_expression(&ce.callee) {
return Some(true);
return true;
}
}
_ => {
return Some(false);
return false;
}
}
}
_ => {}
}

Some(false)
false
}

fn run_diagnostic<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>, span: Span) {
if !Self::is_wanted_node(node, ctx).unwrap_or_default() {
if !Self::is_wanted_node(node, ctx) {
return;
}

Expand Down
22 changes: 7 additions & 15 deletions crates/oxc_linter/src/rules/eslint/id_length.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,9 +224,7 @@ impl IdLength {
return;
}

let Some(parent_node) = ctx.nodes().parent_node(node.id()) else {
return;
};
let parent_node = ctx.nodes().parent_node(node.id());
match parent_node.kind() {
AstKind::ImportSpecifier(import_specifier) => {
if import_specifier.imported.name() == import_specifier.local.name {
Expand All @@ -238,7 +236,7 @@ impl IdLength {
}
}
AstKind::BindingProperty(_) => {
if let Some(AstKind::ObjectPattern(object_pattern)) =
if let AstKind::ObjectPattern(object_pattern) =
ctx.nodes().parent_kind(parent_node.id())
{
let binding_property_option =
Expand Down Expand Up @@ -279,9 +277,7 @@ impl IdLength {
return;
}

let Some(parent_node) = ctx.nodes().parent_node(node.id()) else {
return;
};
let parent_node = ctx.nodes().parent_node(node.id());
match parent_node.kind() {
AstKind::ExportSpecifier(_)
| AstKind::ImportAttribute(_)
Expand All @@ -292,10 +288,8 @@ impl IdLength {
AstKind::ComputedMemberExpression(_)
| AstKind::PrivateFieldExpression(_)
| AstKind::StaticMemberExpression(_) => {
let Some(parent_parent_node) = ctx.nodes().parent_node(parent_node.id()) else {
return;
};
let AstKind::SimpleAssignmentTarget(_) = parent_parent_node.kind() else {
let AstKind::SimpleAssignmentTarget(_) = ctx.nodes().parent_kind(parent_node.id())
else {
return;
};

Expand All @@ -308,11 +302,9 @@ impl IdLength {
return;
}

let Some(mut parent_parent_node) = ctx.nodes().parent_node(parent_node.id()) else {
return;
};
let mut parent_parent_node = ctx.nodes().parent_node(parent_node.id());
if matches!(parent_parent_node.kind(), AstKind::BindingProperty(_)) {
parent_parent_node = ctx.nodes().parent_node(parent_parent_node.id()).unwrap();
parent_parent_node = ctx.nodes().parent_node(parent_parent_node.id());
}

match parent_parent_node.kind() {
Expand Down
4 changes: 1 addition & 3 deletions crates/oxc_linter/src/rules/eslint/init_declarations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,7 @@ impl Rule for InitDeclarations {

fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {
if let AstKind::VariableDeclaration(decl) = node.kind() {
let Some(parent) = ctx.nodes().parent_node(node.id()) else {
return;
};
let parent = ctx.nodes().parent_node(node.id());
// support for TypeScript's declare variables
if self.mode == Mode::Always {
if decl.declare {
Expand Down
2 changes: 1 addition & 1 deletion crates/oxc_linter/src/rules/eslint/max_depth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ impl Rule for MaxDepth {
}

fn should_count(node: &AstNode<'_>, nodes: &AstNodes<'_>) -> bool {
matches!(node.kind(), AstKind::IfStatement(_) if !matches!(nodes.parent_kind(node.id()), Some(AstKind::IfStatement(_))))
matches!(node.kind(), AstKind::IfStatement(_) if !matches!(nodes.parent_kind(node.id()), AstKind::IfStatement(_)))
|| matches!(node.kind(), |AstKind::SwitchStatement(_)| AstKind::TryStatement(_)
| AstKind::DoWhileStatement(_)
| AstKind::WhileStatement(_)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,8 +218,7 @@ impl Rule for MaxLinesPerFunction {

let final_lines = lines_in_function.saturating_sub(comment_lines);
if final_lines > self.max {
let name =
get_function_name_with_kind(node, ctx.nodes().parent_node(node.id()).unwrap());
let name = get_function_name_with_kind(node, ctx.nodes().parent_node(node.id()));
ctx.diagnostic(max_lines_per_function_diagnostic(&name, final_lines, self.max, span));
}
}
Expand Down
8 changes: 4 additions & 4 deletions crates/oxc_linter/src/rules/eslint/no_await_in_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,19 +70,19 @@ impl Rule for NoAwaitInLoop {
// Perform validation for AwaitExpression and ForOfStatement that contains await
let mut parent_node = nodes.parent_node(node.id());
let mut is_in_loop = false;
while let Some(parent) = parent_node {
while !matches!(parent_node.kind(), AstKind::Program(_)) {
// Check if the current node is the boundary of the loop
if Self::is_boundary(parent) {
if Self::is_boundary(parent_node) {
break;
}

// if AwaitExpression or AwaitForOfStatement are in loop, break and report error
if Self::is_looped(span, parent) {
if Self::is_looped(span, parent_node) {
is_in_loop = true;
break;
}

parent_node = nodes.parent_node(parent.id());
parent_node = nodes.parent_node(parent_node.id());
}

if is_in_loop {
Expand Down
7 changes: 3 additions & 4 deletions crates/oxc_linter/src/rules/eslint/no_console.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,10 +142,9 @@ impl Rule for NoConsole {
ctx.diagnostic_with_suggestion(
no_console_diagnostic(diagnostic_span, &self.allow),
|fixer| {
if let Some(parent) = ctx.nodes().parent_node(node.id()) {
if let AstKind::CallExpression(_) = parent.kind() {
return remove_console(fixer, ctx, parent);
}
let parent = ctx.nodes().parent_node(node.id());
if let AstKind::CallExpression(_) = parent.kind() {
return remove_console(fixer, ctx, parent);
}
fixer.noop()
},
Expand Down
5 changes: 3 additions & 2 deletions crates/oxc_linter/src/rules/eslint/no_dupe_else_if.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ impl Rule for NoDupeElseIf {
let AstKind::IfStatement(if_stmt) = node.kind() else {
return;
};
let Some(AstKind::IfStatement(parent_if_stmt)) = ctx.nodes().parent_kind(node.id()) else {
let AstKind::IfStatement(parent_if_stmt) = ctx.nodes().parent_kind(node.id()) else {
return;
};
let Some(Statement::IfStatement(child_if_stmt)) = &parent_if_stmt.alternate else {
Expand All @@ -134,7 +134,8 @@ impl Rule for NoDupeElseIf {
.collect();

let mut current_node = node;
while let Some(parent_node) = ctx.nodes().parent_node(current_node.id()) {
loop {
let parent_node = ctx.nodes().parent_node(current_node.id());
let AstKind::IfStatement(stmt) = parent_node.kind() else {
break;
};
Expand Down
6 changes: 1 addition & 5 deletions crates/oxc_linter/src/rules/eslint/no_else_return.rs
Original file line number Diff line number Diff line change
Expand Up @@ -346,12 +346,8 @@ impl Rule for NoElseReturn {
return;
};

let Some(parent_node) = ctx.nodes().parent_node(node.id()) else {
return;
};

if !matches!(
parent_node.kind(),
ctx.nodes().parent_kind(node.id()),
AstKind::Program(_)
| AstKind::BlockStatement(_)
| AstKind::StaticBlock(_)
Expand Down
Loading
Loading