Skip to content

Commit

Permalink
fix(transformer/async-to-generator): only transform object method in …
Browse files Browse the repository at this point in the history
…exit_function (#7199)

part of #7175
  • Loading branch information
Dunqing committed Nov 8, 2024
1 parent b4cb587 commit 293d072
Show file tree
Hide file tree
Showing 8 changed files with 99 additions and 70 deletions.
20 changes: 16 additions & 4 deletions crates/oxc_transformer/src/common/arrow_function_converter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -397,10 +397,10 @@ impl<'a> ArrowFunctionConverter<'a> {
}
// Function body
Ancestor::FunctionBody(func) => {
return if self.is_async_only() && *func.r#async()
&& matches!(
ancestors.next().unwrap(),
Ancestor::MethodDefinitionValue(_) | Ancestor::ObjectPropertyValue(_)
return if self.is_async_only()
&& *func.r#async()
&& Self::is_class_method_like_ancestor(
ancestors.next().unwrap()
) {
Some(func.scope_id().get().unwrap())
} else {
Expand Down Expand Up @@ -449,6 +449,18 @@ impl<'a> ArrowFunctionConverter<'a> {
))
}

/// Check whether the given [`Ancestor`] is a class method-like node.
fn is_class_method_like_ancestor(ancestor: Ancestor) -> bool {
match ancestor {
// `class A { async foo() {} }`
Ancestor::MethodDefinitionValue(_) => true,
// Only `({ async foo() {} })` does not include non-method like `({ async foo: function() {} })`,
// because it's just a property with a function value
Ancestor::ObjectPropertyValue(property) => *property.method(),
_ => false,
}
}

/// Insert `var _this = this;` at the top of the statements.
fn insert_this_var_statement_at_the_top_of_statements(
statements: &mut ArenaVec<'a, Statement<'a>>,
Expand Down
18 changes: 13 additions & 5 deletions crates/oxc_transformer/src/es2017/async_to_generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,11 +133,7 @@ impl<'a, 'ctx> Traverse<'a> for AsyncToGenerator<'a, 'ctx> {
fn exit_function(&mut self, func: &mut Function<'a>, ctx: &mut TraverseCtx<'a>) {
if func.r#async
&& !func.is_typescript_syntax()
&& matches!(
ctx.parent(),
// `class A { async foo() {} }` | `({ async foo() {} })`
Ancestor::MethodDefinitionValue(_) | Ancestor::PropertyDefinitionValue(_)
)
&& AsyncGeneratorExecutor::is_class_method_like_ancestor(ctx.parent())
{
self.executor.transform_function_for_method_definition(func, ctx);
}
Expand Down Expand Up @@ -698,6 +694,18 @@ impl<'a, 'ctx> AsyncGeneratorExecutor<'a, 'ctx> {
)
}

/// Check whether the given [`Ancestor`] is a class method-like node.
pub(crate) fn is_class_method_like_ancestor(ancestor: Ancestor) -> bool {
match ancestor {
// `class A { async foo() {} }`
Ancestor::MethodDefinitionValue(_) => true,
// Only `({ async foo() {} })` does not include non-method like `({ async foo: function() {} })`,
// because it's just a property with a function value
Ancestor::ObjectPropertyValue(property) => *property.method(),
_ => false,
}
}

/// Checks if the function length is affected by the parameters.
///
/// TODO: Needs to handle `ignoreFunctionLength` assumption.
Expand Down
2 changes: 1 addition & 1 deletion tasks/coverage/snapshots/semantic_babel.snap
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ rebuilt : SymbolId(0): SymbolFlags(FunctionScopedVariable)

tasks/coverage/babel/packages/babel-parser/test/fixtures/es2017/async-functions/15/input.js
semantic error: Symbol flags mismatch for "_asyncToGenerator":
after transform: SymbolId(4): SymbolFlags(Import)
after transform: SymbolId(2): SymbolFlags(Import)
rebuilt : SymbolId(0): SymbolFlags(FunctionScopedVariable)

tasks/coverage/babel/packages/babel-parser/test/fixtures/es2017/async-functions/16/input.js
Expand Down
23 changes: 16 additions & 7 deletions tasks/coverage/snapshots/semantic_test262.snap
Original file line number Diff line number Diff line change
Expand Up @@ -3814,12 +3814,12 @@ rebuilt : SymbolId(0): SymbolFlags(FunctionScopedVariable)

tasks/coverage/test262/test/language/eval-code/direct/async-meth-a-preceding-parameter-is-named-arguments-declare-arguments-and-assign.js
semantic error: Symbol flags mismatch for "_asyncToGenerator":
after transform: SymbolId(7): SymbolFlags(Import)
after transform: SymbolId(5): SymbolFlags(Import)
rebuilt : SymbolId(0): SymbolFlags(FunctionScopedVariable)

tasks/coverage/test262/test/language/eval-code/direct/async-meth-a-preceding-parameter-is-named-arguments-declare-arguments.js
semantic error: Symbol flags mismatch for "_asyncToGenerator":
after transform: SymbolId(7): SymbolFlags(Import)
after transform: SymbolId(5): SymbolFlags(Import)
rebuilt : SymbolId(0): SymbolFlags(FunctionScopedVariable)

tasks/coverage/test262/test/language/eval-code/direct/async-meth-fn-body-cntns-arguments-func-decl-declare-arguments-and-assign.js
Expand Down Expand Up @@ -20368,7 +20368,16 @@ after transform: SymbolId(12): SymbolFlags(Import)
rebuilt : SymbolId(2): SymbolFlags(FunctionScopedVariable)

tasks/coverage/test262/test/language/expressions/object/method-definition/async-meth-dflt-params-abrupt.js
semantic error: Symbol flags mismatch for "_asyncToGenerator":
semantic error: Scope children mismatch:
after transform: ScopeId(6): [ScopeId(1)]
rebuilt : ScopeId(1): [ScopeId(2), ScopeId(3)]
Scope parent mismatch:
after transform: ScopeId(2): Some(ScopeId(1))
rebuilt : ScopeId(2): Some(ScopeId(1))
Scope children mismatch:
after transform: ScopeId(1): [ScopeId(2)]
rebuilt : ScopeId(3): []
Symbol flags mismatch for "_asyncToGenerator":
after transform: SymbolId(5): SymbolFlags(Import)
rebuilt : SymbolId(0): SymbolFlags(FunctionScopedVariable)

Expand All @@ -20389,7 +20398,7 @@ rebuilt : SymbolId(0): SymbolFlags(FunctionScopedVariable)

tasks/coverage/test262/test/language/expressions/object/method-definition/async-meth-dflt-params-ref-prior.js
semantic error: Symbol flags mismatch for "_asyncToGenerator":
after transform: SymbolId(9): SymbolFlags(Import)
after transform: SymbolId(7): SymbolFlags(Import)
rebuilt : SymbolId(0): SymbolFlags(FunctionScopedVariable)

tasks/coverage/test262/test/language/expressions/object/method-definition/async-meth-dflt-params-ref-self.js
Expand All @@ -20399,7 +20408,7 @@ rebuilt : SymbolId(0): SymbolFlags(FunctionScopedVariable)

tasks/coverage/test262/test/language/expressions/object/method-definition/async-meth-dflt-params-trailing-comma.js
semantic error: Symbol flags mismatch for "_asyncToGenerator":
after transform: SymbolId(7): SymbolFlags(Import)
after transform: SymbolId(5): SymbolFlags(Import)
rebuilt : SymbolId(0): SymbolFlags(FunctionScopedVariable)

tasks/coverage/test262/test/language/expressions/object/method-definition/async-meth-eval-var-scope-syntax-err.js
Expand All @@ -20409,12 +20418,12 @@ rebuilt : SymbolId(0): SymbolFlags(FunctionScopedVariable)

tasks/coverage/test262/test/language/expressions/object/method-definition/async-meth-params-trailing-comma-multiple.js
semantic error: Symbol flags mismatch for "_asyncToGenerator":
after transform: SymbolId(8): SymbolFlags(Import)
after transform: SymbolId(5): SymbolFlags(Import)
rebuilt : SymbolId(0): SymbolFlags(FunctionScopedVariable)

tasks/coverage/test262/test/language/expressions/object/method-definition/async-meth-params-trailing-comma-single.js
semantic error: Symbol flags mismatch for "_asyncToGenerator":
after transform: SymbolId(6): SymbolFlags(Import)
after transform: SymbolId(4): SymbolFlags(Import)
rebuilt : SymbolId(0): SymbolFlags(FunctionScopedVariable)

tasks/coverage/test262/test/language/expressions/object/method-definition/async-returns-async-arrow-returns-arguments-from-parent-function.js
Expand Down
Loading

0 comments on commit 293d072

Please sign in to comment.