refactor(syntax)!: remove SymbolFlags::ArrowFunction (#5857)

`SymbolFlags::ArrowFunction` is an oddity, as whether a symbol is an arrow function is not statically knowable. In the following cases, `f` symbol did not have `ArrowFunction` flag set:

```js
const {f} = {f: () => {}};
```

```js
let f = 123;
f = () => {};
```

`SymbolFlags::ArrowFunction` is therefore not particularly useful, and possibly misleading. Having it complicates the transformer, and it's not used anywhere in Oxc.

This PR removes it.
This commit is contained in:
overlookmotel 2024-09-18 14:03:03 +00:00
parent 7f05eed8cf
commit c96b712f6b
32 changed files with 49 additions and 102 deletions

View file

@ -23,7 +23,7 @@ pub(crate) trait Binder<'a> {
impl<'a> Binder<'a> for VariableDeclarator<'a> {
fn bind(&self, builder: &mut SemanticBuilder<'a>) {
let (mut includes, excludes) = match self.kind {
let (includes, excludes) = match self.kind {
VariableDeclarationKind::Const => (
SymbolFlags::BlockScopedVariable | SymbolFlags::ConstVariable,
SymbolFlags::BlockScopedVariableExcludes,
@ -38,12 +38,6 @@ impl<'a> Binder<'a> for VariableDeclarator<'a> {
}
};
if self.init.as_ref().is_some_and(|init| {
matches!(init.get_inner_expression(), Expression::ArrowFunctionExpression(_))
}) {
includes |= SymbolFlags::ArrowFunction;
}
if self.kind.is_lexical() {
self.id.bound_names(&mut |ident| {
let symbol_id = builder.declare_symbol(ident.span, &ident.name, includes, excludes);

View file

@ -18,7 +18,7 @@ input_file: crates/oxc_semantic/tests/fixtures/oxc/jsx/element-name.jsx
"node": "Program",
"symbols": [
{
"flags": "SymbolFlags(BlockScopedVariable | ArrowFunction)",
"flags": "SymbolFlags(BlockScopedVariable)",
"id": 0,
"name": "Component",
"node": "VariableDeclarator(Component)",

View file

@ -18,7 +18,7 @@ input_file: crates/oxc_semantic/tests/fixtures/typescript-eslint/call-expression
"node": "Program",
"symbols": [
{
"flags": "SymbolFlags(BlockScopedVariable | ConstVariable | ArrowFunction)",
"flags": "SymbolFlags(BlockScopedVariable | ConstVariable)",
"id": 0,
"name": "foo",
"node": "VariableDeclarator(foo)",

View file

@ -47,7 +47,7 @@ input_file: crates/oxc_semantic/tests/fixtures/typescript-eslint/functions/arrow
]
},
{
"flags": "SymbolFlags(BlockScopedVariable | ArrowFunction)",
"flags": "SymbolFlags(BlockScopedVariable)",
"id": 1,
"name": "foo",
"node": "VariableDeclarator(foo)",

View file

@ -40,7 +40,7 @@ input_file: crates/oxc_semantic/tests/fixtures/typescript-eslint/functions/arrow
]
},
{
"flags": "SymbolFlags(BlockScopedVariable | ArrowFunction)",
"flags": "SymbolFlags(BlockScopedVariable)",
"id": 1,
"name": "foo",
"node": "VariableDeclarator(foo)",

View file

@ -40,7 +40,7 @@ input_file: crates/oxc_semantic/tests/fixtures/typescript-eslint/functions/arrow
]
},
{
"flags": "SymbolFlags(BlockScopedVariable | ArrowFunction)",
"flags": "SymbolFlags(BlockScopedVariable)",
"id": 1,
"name": "foo",
"node": "VariableDeclarator(foo)",

View file

@ -55,7 +55,7 @@ input_file: crates/oxc_semantic/tests/fixtures/typescript-eslint/functions/arrow
]
},
{
"flags": "SymbolFlags(BlockScopedVariable | ArrowFunction)",
"flags": "SymbolFlags(BlockScopedVariable)",
"id": 1,
"name": "foo",
"node": "VariableDeclarator(foo)",

View file

@ -48,7 +48,7 @@ input_file: crates/oxc_semantic/tests/fixtures/typescript-eslint/functions/arrow
]
},
{
"flags": "SymbolFlags(BlockScopedVariable | ArrowFunction)",
"flags": "SymbolFlags(BlockScopedVariable)",
"id": 1,
"name": "foo",
"node": "VariableDeclarator(foo)",

View file

@ -47,7 +47,7 @@ input_file: crates/oxc_semantic/tests/fixtures/typescript-eslint/functions/arrow
"references": []
},
{
"flags": "SymbolFlags(BlockScopedVariable | ArrowFunction)",
"flags": "SymbolFlags(BlockScopedVariable)",
"id": 1,
"name": "foo",
"node": "VariableDeclarator(foo)",

View file

@ -40,7 +40,7 @@ input_file: crates/oxc_semantic/tests/fixtures/typescript-eslint/functions/arrow
]
},
{
"flags": "SymbolFlags(BlockScopedVariable | ArrowFunction)",
"flags": "SymbolFlags(BlockScopedVariable)",
"id": 1,
"name": "foo",
"node": "VariableDeclarator(foo)",

View file

@ -33,7 +33,7 @@ input_file: crates/oxc_semantic/tests/fixtures/typescript-eslint/functions/arrow
"node": "Program",
"symbols": [
{
"flags": "SymbolFlags(BlockScopedVariable | ArrowFunction)",
"flags": "SymbolFlags(BlockScopedVariable)",
"id": 0,
"name": "foo",
"node": "VariableDeclarator(foo)",

View file

@ -40,7 +40,7 @@ input_file: crates/oxc_semantic/tests/fixtures/typescript-eslint/functions/arrow
"node": "Program",
"symbols": [
{
"flags": "SymbolFlags(BlockScopedVariable | ConstVariable | ArrowFunction)",
"flags": "SymbolFlags(BlockScopedVariable | ConstVariable)",
"id": 0,
"name": "arrow",
"node": "VariableDeclarator(arrow)",

View file

@ -40,7 +40,7 @@ input_file: crates/oxc_semantic/tests/fixtures/typescript-eslint/functions/arrow
"node": "Program",
"symbols": [
{
"flags": "SymbolFlags(BlockScopedVariable | ConstVariable | ArrowFunction)",
"flags": "SymbolFlags(BlockScopedVariable | ConstVariable)",
"id": 0,
"name": "foo",
"node": "VariableDeclarator(foo)",

View file

@ -40,7 +40,7 @@ input_file: crates/oxc_semantic/tests/fixtures/typescript-eslint/functions/arrow
"node": "Program",
"symbols": [
{
"flags": "SymbolFlags(BlockScopedVariable | ConstVariable | ArrowFunction)",
"flags": "SymbolFlags(BlockScopedVariable | ConstVariable)",
"id": 0,
"name": "foo",
"node": "VariableDeclarator(foo)",

View file

@ -33,7 +33,7 @@ input_file: crates/oxc_semantic/tests/fixtures/typescript-eslint/functions/arrow
"node": "Program",
"symbols": [
{
"flags": "SymbolFlags(BlockScopedVariable | ConstVariable | ArrowFunction)",
"flags": "SymbolFlags(BlockScopedVariable | ConstVariable)",
"id": 0,
"name": "foo",
"node": "VariableDeclarator(foo)",

View file

@ -40,7 +40,7 @@ input_file: crates/oxc_semantic/tests/fixtures/typescript-eslint/functions/arrow
"node": "Program",
"symbols": [
{
"flags": "SymbolFlags(BlockScopedVariable | ConstVariable | ArrowFunction)",
"flags": "SymbolFlags(BlockScopedVariable | ConstVariable)",
"id": 0,
"name": "foo",
"node": "VariableDeclarator(foo)",

View file

@ -33,7 +33,7 @@ input_file: crates/oxc_semantic/tests/fixtures/typescript-eslint/functions/arrow
"node": "Program",
"symbols": [
{
"flags": "SymbolFlags(BlockScopedVariable | ConstVariable | ArrowFunction)",
"flags": "SymbolFlags(BlockScopedVariable | ConstVariable)",
"id": 0,
"name": "foo",
"node": "VariableDeclarator(foo)",

View file

@ -26,7 +26,7 @@ input_file: crates/oxc_semantic/tests/fixtures/typescript-eslint/functions/arrow
"node": "Program",
"symbols": [
{
"flags": "SymbolFlags(BlockScopedVariable | ConstVariable | ArrowFunction)",
"flags": "SymbolFlags(BlockScopedVariable | ConstVariable)",
"id": 0,
"name": "foo",
"node": "VariableDeclarator(foo)",

View file

@ -47,7 +47,7 @@ input_file: crates/oxc_semantic/tests/fixtures/typescript-eslint/functions/arrow
]
},
{
"flags": "SymbolFlags(BlockScopedVariable | ConstVariable | ArrowFunction)",
"flags": "SymbolFlags(BlockScopedVariable | ConstVariable)",
"id": 1,
"name": "foo",
"node": "VariableDeclarator(foo)",

View file

@ -33,7 +33,7 @@ input_file: crates/oxc_semantic/tests/fixtures/typescript-eslint/functions/arrow
"node": "Program",
"symbols": [
{
"flags": "SymbolFlags(BlockScopedVariable | ConstVariable | ArrowFunction)",
"flags": "SymbolFlags(BlockScopedVariable | ConstVariable)",
"id": 0,
"name": "foo",
"node": "VariableDeclarator(foo)",

View file

@ -54,7 +54,7 @@ input_file: crates/oxc_semantic/tests/fixtures/typescript-eslint/functions/arrow
]
},
{
"flags": "SymbolFlags(BlockScopedVariable | ConstVariable | ArrowFunction)",
"flags": "SymbolFlags(BlockScopedVariable | ConstVariable)",
"id": 1,
"name": "foo",
"node": "VariableDeclarator(foo)",

View file

@ -18,7 +18,7 @@ input_file: crates/oxc_semantic/tests/fixtures/typescript-eslint/global-resoluti
"node": "Program",
"symbols": [
{
"flags": "SymbolFlags(BlockScopedVariable | ConstVariable | ArrowFunction)",
"flags": "SymbolFlags(BlockScopedVariable | ConstVariable)",
"id": 0,
"name": "top",
"node": "VariableDeclarator(top)",

View file

@ -18,7 +18,7 @@ input_file: crates/oxc_semantic/tests/fixtures/typescript-eslint/global-resoluti
"node": "Program",
"symbols": [
{
"flags": "SymbolFlags(BlockScopedVariable | ArrowFunction)",
"flags": "SymbolFlags(BlockScopedVariable)",
"id": 0,
"name": "top",
"node": "VariableDeclarator(top)",

View file

@ -18,7 +18,7 @@ input_file: crates/oxc_semantic/tests/fixtures/typescript-eslint/global-resoluti
"node": "Program",
"symbols": [
{
"flags": "SymbolFlags(FunctionScopedVariable | ArrowFunction)",
"flags": "SymbolFlags(FunctionScopedVariable)",
"id": 0,
"name": "top",
"node": "VariableDeclarator(top)",

View file

@ -18,7 +18,7 @@ input_file: crates/oxc_semantic/tests/fixtures/typescript-eslint/global-resoluti
"node": "Program",
"symbols": [
{
"flags": "SymbolFlags(BlockScopedVariable | ConstVariable | ArrowFunction)",
"flags": "SymbolFlags(BlockScopedVariable | ConstVariable)",
"id": 0,
"name": "top",
"node": "VariableDeclarator(top)",

View file

@ -18,7 +18,7 @@ input_file: crates/oxc_semantic/tests/fixtures/typescript-eslint/global-resoluti
"node": "Program",
"symbols": [
{
"flags": "SymbolFlags(BlockScopedVariable | ArrowFunction)",
"flags": "SymbolFlags(BlockScopedVariable)",
"id": 0,
"name": "top",
"node": "VariableDeclarator(top)",

View file

@ -18,7 +18,7 @@ input_file: crates/oxc_semantic/tests/fixtures/typescript-eslint/global-resoluti
"node": "Program",
"symbols": [
{
"flags": "SymbolFlags(FunctionScopedVariable | ArrowFunction)",
"flags": "SymbolFlags(FunctionScopedVariable)",
"id": 0,
"name": "top",
"node": "VariableDeclarator(top)",

View file

@ -82,24 +82,22 @@ bitflags! {
const CatchVariable = 1 << 6;
/// A function declaration or expression
const Function = 1 << 7;
/// A function or block-scoped variable initialized to an arrow function
const ArrowFunction = 1 << 8;
/// Imported ESM binding
const Import = 1 << 9;
const Import = 1 << 8;
/// Imported ESM type-only binding
const TypeImport = 1 << 10;
const TypeImport = 1 << 9;
// Type specific symbol flags
const TypeAlias = 1 << 11;
const Interface = 1 << 12;
const RegularEnum = 1 << 13;
const ConstEnum = 1 << 14;
const EnumMember = 1 << 15;
const TypeLiteral = 1 << 16;
const TypeParameter = 1 << 17;
const NameSpaceModule = 1 << 18;
const ValueModule = 1 << 19;
const TypeAlias = 1 << 10;
const Interface = 1 << 11;
const RegularEnum = 1 << 12;
const ConstEnum = 1 << 13;
const EnumMember = 1 << 14;
const TypeLiteral = 1 << 15;
const TypeParameter = 1 << 16;
const NameSpaceModule = 1 << 17;
const ValueModule = 1 << 18;
// In a dts file or there is a declare flag
const Ambient = 1 << 20;
const Ambient = 1 << 19;
const Enum = Self::ConstEnum.bits() | Self::RegularEnum.bits();
@ -158,24 +156,11 @@ impl SymbolFlags {
}
/// Returns `true` if this symbol is a function declaration or expression.
///
/// Use [`SymbolFlags::is_function_like`] to check if this symbol is a function or an arrow function.
#[inline]
pub fn is_function(&self) -> bool {
self.contains(Self::Function)
}
#[inline]
pub fn is_arrow_function(&self) -> bool {
self.contains(Self::ArrowFunction)
}
/// Returns `true` if this symbol is an arrow function or a function declaration/expression.
#[inline]
pub fn is_function_like(&self) -> bool {
self.intersects(Self::Function | Self::ArrowFunction)
}
#[inline]
pub fn is_class(&self) -> bool {
self.contains(Self::Class)

View file

@ -246,20 +246,6 @@ impl<'a> Traverse<'a> for ArrowFunctions<'a> {
*expr = self.transform_arrow_function_expression(arrow_function_expr.unbox(), ctx);
}
}
fn enter_variable_declarator(
&mut self,
node: &mut VariableDeclarator<'a>,
ctx: &mut TraverseCtx<'a>,
) {
if !matches!(node.init, Some(Expression::ArrowFunctionExpression(_))) {
return;
}
let Some(id) = node.id.get_binding_identifier() else { return };
*ctx.symbols_mut().get_flags_mut(id.symbol_id.get().unwrap()) &=
!SymbolFlags::ArrowFunction;
}
}
impl<'a> ArrowFunctions<'a> {

View file

@ -107,16 +107,6 @@ impl<'a> Traverse<'a> for ES2015<'a> {
}
}
fn enter_variable_declarator(
&mut self,
node: &mut VariableDeclarator<'a>,
ctx: &mut TraverseCtx<'a>,
) {
if self.options.arrow_function.is_some() {
self.arrow_functions.enter_variable_declarator(node, ctx);
}
}
fn enter_jsx_element_name(&mut self, node: &mut JSXElementName<'a>, ctx: &mut TraverseCtx<'a>) {
if self.options.arrow_function.is_some() {
self.arrow_functions.enter_jsx_element_name(node, ctx);

View file

@ -388,14 +388,6 @@ impl<'a> Traverse<'a> for Transformer<'a> {
self.x2_es2019.enter_catch_clause(clause, ctx);
}
fn enter_variable_declarator(
&mut self,
node: &mut VariableDeclarator<'a>,
ctx: &mut TraverseCtx<'a>,
) {
self.x3_es2015.enter_variable_declarator(node, ctx);
}
fn enter_import_declaration(
&mut self,
node: &mut ImportDeclaration<'a>,

View file

@ -8272,8 +8272,8 @@ Bindings mismatch:
after transform: ScopeId(4): ["a", "b", "p"]
rebuilt : ScopeId(2): ["a", "b"]
Symbol flags mismatch:
after transform: SymbolId(0): SymbolFlags(BlockScopedVariable | ConstVariable | Export | ArrowFunction | Interface)
rebuilt : SymbolId(0): SymbolFlags(BlockScopedVariable | ConstVariable | Export | ArrowFunction)
after transform: SymbolId(0): SymbolFlags(BlockScopedVariable | ConstVariable | Export | Interface)
rebuilt : SymbolId(0): SymbolFlags(BlockScopedVariable | ConstVariable | Export)
Symbol span mismatch:
after transform: SymbolId(0): Span { start: 17, end: 22 }
rebuilt : SymbolId(0): Span { start: 171, end: 176 }
@ -8284,8 +8284,8 @@ Symbol redeclarations mismatch:
after transform: SymbolId(0): [Span { start: 171, end: 176 }]
rebuilt : SymbolId(0): []
Symbol flags mismatch:
after transform: SymbolId(1): SymbolFlags(BlockScopedVariable | ConstVariable | Export | ArrowFunction | Interface)
rebuilt : SymbolId(3): SymbolFlags(BlockScopedVariable | ConstVariable | Export | ArrowFunction)
after transform: SymbolId(1): SymbolFlags(BlockScopedVariable | ConstVariable | Export | Interface)
rebuilt : SymbolId(3): SymbolFlags(BlockScopedVariable | ConstVariable | Export)
Symbol span mismatch:
after transform: SymbolId(1): Span { start: 93, end: 97 }
rebuilt : SymbolId(3): Span { start: 237, end: 241 }
@ -17662,8 +17662,8 @@ semantic error: Scope children mismatch:
after transform: ScopeId(0): [ScopeId(1), ScopeId(2)]
rebuilt : ScopeId(0): [ScopeId(1)]
Symbol flags mismatch:
after transform: SymbolId(0): SymbolFlags(BlockScopedVariable | ConstVariable | Export | ArrowFunction | Interface)
rebuilt : SymbolId(0): SymbolFlags(BlockScopedVariable | ConstVariable | Export | ArrowFunction)
after transform: SymbolId(0): SymbolFlags(BlockScopedVariable | ConstVariable | Export | Interface)
rebuilt : SymbolId(0): SymbolFlags(BlockScopedVariable | ConstVariable | Export)
Symbol span mismatch:
after transform: SymbolId(0): Span { start: 10, end: 20 }
rebuilt : SymbolId(0): Span { start: 52, end: 62 }
@ -39879,8 +39879,8 @@ Symbol reference IDs mismatch:
after transform: SymbolId(2): [ReferenceId(1), ReferenceId(5)]
rebuilt : SymbolId(0): [ReferenceId(2)]
Symbol flags mismatch:
after transform: SymbolId(9): SymbolFlags(BlockScopedVariable | ConstVariable | ArrowFunction | Interface)
rebuilt : SymbolId(7): SymbolFlags(BlockScopedVariable | ConstVariable | ArrowFunction)
after transform: SymbolId(9): SymbolFlags(BlockScopedVariable | ConstVariable | Interface)
rebuilt : SymbolId(7): SymbolFlags(BlockScopedVariable | ConstVariable)
Symbol span mismatch:
after transform: SymbolId(9): Span { start: 247, end: 256 }
rebuilt : SymbolId(7): Span { start: 287, end: 296 }
@ -59054,8 +59054,8 @@ Bindings mismatch:
after transform: ScopeId(20): ["T", "f"]
rebuilt : ScopeId(9): ["f"]
Symbol flags mismatch:
after transform: SymbolId(70): SymbolFlags(BlockScopedVariable | ConstVariable | ArrowFunction | TypeAlias)
rebuilt : SymbolId(32): SymbolFlags(BlockScopedVariable | ConstVariable | ArrowFunction)
after transform: SymbolId(70): SymbolFlags(BlockScopedVariable | ConstVariable | TypeAlias)
rebuilt : SymbolId(32): SymbolFlags(BlockScopedVariable | ConstVariable)
Symbol span mismatch:
after transform: SymbolId(70): Span { start: 1594, end: 1596 }
rebuilt : SymbolId(32): Span { start: 1621, end: 1627 }