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

Commit

Permalink
fix(rome_js_analyze): Add constructor support (#4605)
Browse files Browse the repository at this point in the history
  • Loading branch information
denbezrukov authored Jun 30, 2023
1 parent 9cde65c commit 08645a8
Show file tree
Hide file tree
Showing 11 changed files with 775 additions and 365 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ multiple files:

### Linter

- [`noDuplicateParameters`](https://docs.rome.tools/lint/rules/noduplicateparameters/): enhanced rule to manage constructor parameters.

#### BREAKING CHANGES

- Remove `lint/complexity/noExtraSemicolon` ([#4553](https://github.com/rome/tools/issues/4553))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
use rome_analyze::{context::RuleContext, declare_rule, Ast, Rule, RuleDiagnostic};
use rome_console::markup;
use rome_js_syntax::parameter_ext::{AnyJsParameterList, AnyJsParameters, AnyParameter};
use rome_js_syntax::{
AnyJsArrayBindingPatternElement, AnyJsBinding, AnyJsBindingPattern, AnyJsFormalParameter,
AnyJsObjectBindingPatternMember, AnyJsParameter, JsArrowFunctionExpression,
JsFunctionDeclaration, JsFunctionExportDefaultDeclaration, JsFunctionExpression,
JsIdentifierBinding, JsMethodClassMember, JsMethodObjectMember,
AnyJsArrayBindingPatternElement, AnyJsBinding, AnyJsBindingPattern,
AnyJsObjectBindingPatternMember, JsIdentifierBinding,
};
use rome_rowan::{declare_node_union, AstNode};
use rome_rowan::AstNode;
use rustc_hash::FxHashSet;

declare_rule! {
Expand Down Expand Up @@ -47,28 +46,26 @@ declare_rule! {
}

impl Rule for NoDuplicateParameters {
type Query = Ast<AnyJsFunctionAndMethod>;
type Query = Ast<AnyJsParameters>;
type State = JsIdentifierBinding;
type Signals = Option<Self::State>;
type Options = ();

fn run(ctx: &RuleContext<Self>) -> Option<Self::State> {
let function = ctx.query();
let args = match function {
AnyJsFunctionAndMethod::JsArrowFunctionExpression(func) => {
func.parameters().ok()?.as_js_parameters()?.clone()
let parameters = ctx.query();

let list = match parameters {
AnyJsParameters::JsParameters(parameters) => {
AnyJsParameterList::from(parameters.items())
}
AnyJsFunctionAndMethod::JsFunctionDeclaration(func) => func.parameters().ok()?,
AnyJsFunctionAndMethod::JsFunctionExportDefaultDeclaration(func) => {
func.parameters().ok()?
AnyJsParameters::JsConstructorParameters(parameters) => {
AnyJsParameterList::from(parameters.parameters())
}
AnyJsFunctionAndMethod::JsFunctionExpression(func) => func.parameters().ok()?,
AnyJsFunctionAndMethod::JsMethodClassMember(member) => member.parameters().ok()?,
AnyJsFunctionAndMethod::JsMethodObjectMember(member) => member.parameters().ok()?,
};

let mut set = FxHashSet::default();
// Traversing the parameters of the function in preorder and checking for duplicates,
args.items().into_iter().find_map(|parameter| {
list.iter().find_map(|parameter| {
let parameter = parameter.ok()?;
traverse_parameter(parameter, &mut set)
})
Expand All @@ -92,21 +89,12 @@ impl Rule for NoDuplicateParameters {
/// Traverse the parameter recursively and check if it is duplicated.
/// Return `Some(JsIdentifierBinding)` if it is duplicated.
fn traverse_parameter(
parameter: AnyJsParameter,
parameter: AnyParameter,
tracked_bindings: &mut FxHashSet<String>,
) -> Option<JsIdentifierBinding> {
match parameter {
AnyJsParameter::AnyJsFormalParameter(p) => match p {
AnyJsFormalParameter::JsFormalParameter(parameter) => {
traverse_binding(parameter.binding().ok()?, tracked_bindings)
}
AnyJsFormalParameter::JsBogusParameter(_) => None,
},
AnyJsParameter::JsRestParameter(rest_parameter) => {
traverse_binding(rest_parameter.binding().ok()?, tracked_bindings)
}
AnyJsParameter::TsThisParameter(_) => None,
}
parameter
.binding()
.and_then(|binding| traverse_binding(binding, tracked_bindings))
}

/// Traverse a [JsAnyBindingPattern] in preorder and check if the name of [JsIdentifierBinding] has seem before.
Expand Down Expand Up @@ -198,8 +186,3 @@ fn track_binding(
false
}
}

declare_node_union! {
/// A union of all possible FunctionLike `JsAstNode` in the JS grammar.
pub(crate) AnyJsFunctionAndMethod = JsArrowFunctionExpression| JsFunctionDeclaration| JsFunctionExportDefaultDeclaration | JsFunctionExpression | JsMethodClassMember | JsMethodObjectMember
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
function b(a, b, b) {}
function c(a, a, a) {}
const d = (a, b, a) => {};
function e(a, b, a, b) {}
var f = function (a, b, b) {};
class G {
ggg(a, a, a) {}
}
let objectMethods = { method(a, b, c, c) {} };
var h = function (a, b, a) {};
export default function (a, b, a, a) {}
function f({ test: res = 3 }, res) {}
export function f2(a, b, c = (a, b, b) => {}) {}
class A {
constructor(a, a) {}
}
class A {
constructor(private a, a) {}
}
class A {
constructor(a, readonly a) {}
}
class A {
constructor(private a, private a) {}
}
class A {
constructor(readonly a, private a) {}
}
Loading

0 comments on commit 08645a8

Please sign in to comment.