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
refactor(semantic): splitting the FormalParameters binder implementat…
…ion and add binder for FormalParameter
  • Loading branch information
Dunqing committed Jan 22, 2024
commit 4a60946d068311f96ed089ec358e07257b4f00c2
6 changes: 6 additions & 0 deletions crates/oxc_ast/src/ast/js.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1648,6 +1648,12 @@ pub enum FormalParameterKind {
Signature,
}

impl FormalParameterKind {
pub fn is_signature(&self) -> bool {
matches!(self, Self::Signature)
}
}

impl<'a> FormalParameters<'a> {
pub fn is_empty(&self) -> bool {
self.items.is_empty()
Expand Down
10 changes: 4 additions & 6 deletions crates/oxc_linter/src/rules/eslint/no_redeclare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,10 @@ impl Rule for NoRedeclare {
}
}
}
AstKind::FormalParameters(params) => {
for item in &params.items {
if let BindingPatternKind::BindingIdentifier(ident) = &item.pattern.kind {
if *symbol_table.get_name(variable.symbol_id) == ident.name {
self.report_diagnostic(ctx, variable, ident);
}
AstKind::FormalParameter(param) => {
if let BindingPatternKind::BindingIdentifier(ident) = &param.pattern.kind {
if *symbol_table.get_name(variable.symbol_id) == ident.name {
self.report_diagnostic(ctx, variable, ident);
}
}
}
Expand Down
6 changes: 4 additions & 2 deletions crates/oxc_linter/src/rules/oxc/no_accumulating_spread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,10 @@ impl Rule for NoAccumulatingSpread {
let reference = symbols.get_reference(reference_id);
let Some(referenced_symbol_id) = reference.symbol_id() else { return };
let declaration_id = symbols.get_declaration(referenced_symbol_id);
let declaration = ctx.semantic().nodes().get_node(declaration_id);
let AstKind::FormalParameters(params) = declaration.kind() else { return };
let Some(declaration) = ctx.semantic().nodes().parent_node(declaration_id) else { return };
let AstKind::FormalParameters(params) = declaration.kind() else {
return;
};

// We're only looking for the first parameter, since that's where acc is.
// Skip non-parameter or non-first-parameter declarations.
Expand Down
49 changes: 38 additions & 11 deletions crates/oxc_semantic/src/binder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,13 +182,42 @@ impl<'a> Binder for Function<'a> {
}
}

impl<'a> Binder for FormalParameters<'a> {
// Binds the formal parameters of a function or method.
impl<'a> Binder for RestElement<'a> {
// Binds the FormalParameters's rest of a function or method.
fn bind(&self, builder: &mut SemanticBuilder) {
let parent_kind = builder.nodes.parent_kind(builder.current_node_id).unwrap();
let AstKind::FormalParameters(parameters) = parent_kind else {
return;
};

if parameters.kind.is_signature() {
return;
}

let includes = SymbolFlags::FunctionScopedVariable;
let excludes =
SymbolFlags::FunctionScopedVariable | SymbolFlags::FunctionScopedVariableExcludes;
self.bound_names(&mut |ident| {
let symbol_id = builder.declare_symbol(ident.span, &ident.name, includes, excludes);
ident.symbol_id.set(Some(symbol_id));
});
}
}

impl<'a> Binder for FormalParameter<'a> {
// Binds the FormalParameter of a function or method.
fn bind(&self, builder: &mut SemanticBuilder) {
let parent_kind = builder.nodes.parent_kind(builder.current_node_id).unwrap();
let AstKind::FormalParameters(parameters) = parent_kind else { unreachable!() };

if parameters.kind.is_signature() {
return;
}

let includes = SymbolFlags::FunctionScopedVariable;

let is_not_allowed_duplicate_parameters = matches!(
self.kind,
parameters.kind,
// ArrowFormalParameters: UniqueFormalParameters
FormalParameterKind::ArrowFormalParameters |
// UniqueFormalParameters : FormalParameters
Expand All @@ -199,20 +228,18 @@ impl<'a> Binder for FormalParameters<'a> {
builder.strict_mode() ||
// FormalParameters : FormalParameterList
// * It is a Syntax Error if IsSimpleParameterList of FormalParameterList is false and BoundNames of FormalParameterList contains any duplicate elements.
!self.is_simple_parameter_list();
!parameters.is_simple_parameter_list();

let excludes = if is_not_allowed_duplicate_parameters {
SymbolFlags::FunctionScopedVariable | SymbolFlags::FunctionScopedVariableExcludes
} else {
SymbolFlags::FunctionScopedVariableExcludes
};
let is_signature = self.kind == FormalParameterKind::Signature;
if !is_signature {
self.bound_names(&mut |ident| {
let symbol_id = builder.declare_symbol(ident.span, &ident.name, includes, excludes);
ident.symbol_id.set(Some(symbol_id));
});
}

self.bound_names(&mut |ident| {
let symbol_id = builder.declare_symbol(ident.span, &ident.name, includes, excludes);
ident.symbol_id.set(Some(symbol_id));
});
}
}

Expand Down
7 changes: 5 additions & 2 deletions crates/oxc_semantic/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -450,8 +450,11 @@ impl<'a> SemanticBuilder<'a> {
&self.nodes,
);
}
AstKind::FormalParameters(params) => {
params.bind(self);
AstKind::RestElement(element) => {
element.bind(self);
}
AstKind::FormalParameter(param) => {
param.bind(self);
}
AstKind::CatchClause(clause) => {
clause.bind(self);
Expand Down