mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 12:21:58 +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,
|
Signature,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FormalParameterKind {
|
||||||
|
pub fn is_signature(&self) -> bool {
|
||||||
|
matches!(self, Self::Signature)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> FormalParameters<'a> {
|
impl<'a> FormalParameters<'a> {
|
||||||
pub fn is_empty(&self) -> bool {
|
pub fn is_empty(&self) -> bool {
|
||||||
self.items.is_empty()
|
self.items.is_empty()
|
||||||
|
|
|
||||||
|
|
@ -86,12 +86,10 @@ impl Rule for NoRedeclare {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AstKind::FormalParameters(params) => {
|
AstKind::FormalParameter(param) => {
|
||||||
for item in ¶ms.items {
|
if let BindingPatternKind::BindingIdentifier(ident) = ¶m.pattern.kind {
|
||||||
if let BindingPatternKind::BindingIdentifier(ident) = &item.pattern.kind {
|
if *symbol_table.get_name(variable.symbol_id) == ident.name {
|
||||||
if *symbol_table.get_name(variable.symbol_id) == ident.name {
|
self.report_diagnostic(ctx, variable, ident);
|
||||||
self.report_diagnostic(ctx, variable, ident);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -89,8 +89,10 @@ impl Rule for NoAccumulatingSpread {
|
||||||
let reference = symbols.get_reference(reference_id);
|
let reference = symbols.get_reference(reference_id);
|
||||||
let Some(referenced_symbol_id) = reference.symbol_id() else { return };
|
let Some(referenced_symbol_id) = reference.symbol_id() else { return };
|
||||||
let declaration_id = symbols.get_declaration(referenced_symbol_id);
|
let declaration_id = symbols.get_declaration(referenced_symbol_id);
|
||||||
let declaration = ctx.semantic().nodes().get_node(declaration_id);
|
let Some(declaration) = ctx.semantic().nodes().parent_node(declaration_id) else { return };
|
||||||
let AstKind::FormalParameters(params) = declaration.kind() else { return };
|
let AstKind::FormalParameters(params) = declaration.kind() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
// We're only looking for the first parameter, since that's where acc is.
|
// We're only looking for the first parameter, since that's where acc is.
|
||||||
// Skip non-parameter or non-first-parameter declarations.
|
// Skip non-parameter or non-first-parameter declarations.
|
||||||
|
|
|
||||||
|
|
@ -182,13 +182,42 @@ impl<'a> Binder for Function<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Binder for FormalParameters<'a> {
|
impl<'a> Binder for RestElement<'a> {
|
||||||
// Binds the formal parameters of a function or method.
|
// Binds the FormalParameters's rest of a function or method.
|
||||||
fn bind(&self, builder: &mut SemanticBuilder) {
|
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 includes = SymbolFlags::FunctionScopedVariable;
|
||||||
|
|
||||||
let is_not_allowed_duplicate_parameters = matches!(
|
let is_not_allowed_duplicate_parameters = matches!(
|
||||||
self.kind,
|
parameters.kind,
|
||||||
// ArrowFormalParameters: UniqueFormalParameters
|
// ArrowFormalParameters: UniqueFormalParameters
|
||||||
FormalParameterKind::ArrowFormalParameters |
|
FormalParameterKind::ArrowFormalParameters |
|
||||||
// UniqueFormalParameters : FormalParameters
|
// UniqueFormalParameters : FormalParameters
|
||||||
|
|
@ -199,20 +228,18 @@ impl<'a> Binder for FormalParameters<'a> {
|
||||||
builder.strict_mode() ||
|
builder.strict_mode() ||
|
||||||
// FormalParameters : FormalParameterList
|
// FormalParameters : FormalParameterList
|
||||||
// * It is a Syntax Error if IsSimpleParameterList of FormalParameterList is false and BoundNames of FormalParameterList contains any duplicate elements.
|
// * 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 {
|
let excludes = if is_not_allowed_duplicate_parameters {
|
||||||
SymbolFlags::FunctionScopedVariable | SymbolFlags::FunctionScopedVariableExcludes
|
SymbolFlags::FunctionScopedVariable | SymbolFlags::FunctionScopedVariableExcludes
|
||||||
} else {
|
} else {
|
||||||
SymbolFlags::FunctionScopedVariableExcludes
|
SymbolFlags::FunctionScopedVariableExcludes
|
||||||
};
|
};
|
||||||
let is_signature = self.kind == FormalParameterKind::Signature;
|
|
||||||
if !is_signature {
|
self.bound_names(&mut |ident| {
|
||||||
self.bound_names(&mut |ident| {
|
let symbol_id = builder.declare_symbol(ident.span, &ident.name, includes, excludes);
|
||||||
let symbol_id = builder.declare_symbol(ident.span, &ident.name, includes, excludes);
|
ident.symbol_id.set(Some(symbol_id));
|
||||||
ident.symbol_id.set(Some(symbol_id));
|
});
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -450,8 +450,11 @@ impl<'a> SemanticBuilder<'a> {
|
||||||
&self.nodes,
|
&self.nodes,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
AstKind::FormalParameters(params) => {
|
AstKind::RestElement(element) => {
|
||||||
params.bind(self);
|
element.bind(self);
|
||||||
|
}
|
||||||
|
AstKind::FormalParameter(param) => {
|
||||||
|
param.bind(self);
|
||||||
}
|
}
|
||||||
AstKind::CatchClause(clause) => {
|
AstKind::CatchClause(clause) => {
|
||||||
clause.bind(self);
|
clause.bind(self);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue