Skip to content
This repository has been archived by the owner on Aug 31, 2023. It is now read-only.

Commit

Permalink
fix(semantic_analyzers): fix the false positive for noConstAssign (#…
Browse files Browse the repository at this point in the history
…3747)

Co-authored-by: Micha Reiser <micha@reiser.io>
Co-authored-by: Anchen Li <anchen.li@pslm-qxy9gygyvj.lan>
  • Loading branch information
3 people authored Nov 18, 2022
1 parent 2594803 commit 0bbf70d
Show file tree
Hide file tree
Showing 3 changed files with 337 additions and 59 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@ use crate::semantic_services::Semantic;
use rome_analyze::context::RuleContext;
use rome_analyze::{declare_rule, Rule, RuleDiagnostic};
use rome_console::markup;
use rome_js_syntax::{JsIdentifierAssignment, JsVariableDeclaration};
use rome_js_syntax::{
JsAnyArrayBindingPatternElement, JsAnyObjectBindingPatternMember,
JsArrayBindingPatternElementList, JsForVariableDeclaration, JsIdentifierAssignment,
JsIdentifierBinding, JsObjectBindingPatternPropertyList, JsVariableDeclaration,
JsVariableDeclarator, JsVariableDeclaratorList,
};
use rome_rowan::{AstNode, TextRange};

declare_rule! {
Expand Down Expand Up @@ -61,13 +66,31 @@ impl Rule for NoConstAssign {
let model = ctx.model();

let declared_binding = model.declaration(node)?;
if let Some(variable_declaration) = declared_binding
.syntax()
.ancestors()
.find_map(|ancestor| JsVariableDeclaration::cast_ref(&ancestor))
{
if variable_declaration.is_const() {
return Some(declared_binding.syntax().text_trimmed_range());

if let Some(possible_declarator) = declared_binding.syntax().ancestors().find(|node| {
!JsAnyObjectBindingPatternMember::can_cast(node.kind())
&& !JsObjectBindingPatternPropertyList::can_cast(node.kind())
&& !JsAnyArrayBindingPatternElement::can_cast(node.kind())
&& !JsArrayBindingPatternElementList::can_cast(node.kind())
&& !JsIdentifierBinding::can_cast(node.kind())
}) {
if JsVariableDeclarator::can_cast(possible_declarator.kind()) {
let possible_declaration = possible_declarator.parent()?;
if let Some(js_for_variable_declaration) =
JsForVariableDeclaration::cast_ref(&possible_declaration)
{
if js_for_variable_declaration.is_const() {
return Some(declared_binding.syntax().text_trimmed_range());
}
} else if let Some(js_variable_declaration) =
JsVariableDeclaratorList::cast_ref(&possible_declaration)
.and_then(|declaration| declaration.syntax().parent())
.and_then(JsVariableDeclaration::cast)
{
if js_variable_declaration.is_const() {
return Some(declared_binding.syntax().text_trimmed_range());
}
}
}
}

Expand Down
50 changes: 47 additions & 3 deletions crates/rome_js_analyze/tests/specs/nursery/noConstAssign.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,55 @@
const a = 1;
a = 2;

const b = 2, c = 43;
const b = 2,
c = 43;
b = 4;
++b;
b += 45;
b--;
function f() {
b++;
}
b++;
}
function f(d) {
b++;
}
const fn = (val) => {
val = 0;
};

const e = () => {
try {
foo();
} catch (err) {
err = 4;
}
};

const f = (...rest) => {
rest = 4;
};

const g = class bar {};
bar = 1;

const h = function foo() {
foo = 1;
};

const {
i,
j: { l },
} = { i: 1, j: { l: 2 } };
i = 4;
l = 4;

for (const k in [1, 2]) {
k = 4;
}

const [p, { q }] = [1, { q: 2 }];
p = 3;
q = 4;

const { r, ...rest } = s;
r = 4;
Loading

0 comments on commit 0bbf70d

Please sign in to comment.