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:
Dunqing 2024-01-22 14:23:39 +08:00 committed by GitHub
parent 5ca07bcb09
commit 8bccdab2e9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 57 additions and 21 deletions

View file

@ -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()

View file

@ -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);
}
}
}

View file

@ -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.

View file

@ -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));
});
}
}

View file

@ -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);