mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 12:19:15 +00:00
refactor(semantic): add binder for FormalParameters and RestElement, replacing the binder for FormalParameters (#2114)
Similar with #2013. This way we will be able to find the corresponding Ast accurately. The snapshots look a little strange but the change is expected.
This commit is contained in:
parent
5ca07bcb09
commit
8bccdab2e9
5 changed files with 57 additions and 21 deletions
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -86,12 +86,10 @@ impl Rule for NoRedeclare {
|
|||
}
|
||||
}
|
||||
}
|
||||
AstKind::FormalParameters(params) => {
|
||||
for item in ¶ms.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) = ¶m.pattern.kind {
|
||||
if *symbol_table.get_name(variable.symbol_id) == ident.name {
|
||||
self.report_diagnostic(ctx, variable, ident);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in a new issue