diff --git a/internal/transformers/estransforms/async.go b/internal/transformers/estransforms/async.go index fc1d56992c0..f4138496755 100644 --- a/internal/transformers/estransforms/async.go +++ b/internal/transformers/estransforms/async.go @@ -30,9 +30,6 @@ type asyncTransformer struct { enclosingFunctionParameterNames *collections.Set[string] lexicalArguments lexicalArgumentsInfo - parentNode *ast.Node - currentNode *ast.Node - asyncBodyVisitor *ast.NodeVisitor fallbackNodeVisitor *ast.NodeVisitor } @@ -111,7 +108,10 @@ func (tx *asyncTransformer) fallbackVisitor(node *ast.Node) *ast.Node { ast.KindVariableDeclaration: // fall through to visitEachChild case ast.KindIdentifier: - if tx.lexicalArguments.binding != nil && node.Text() == "arguments" && !isNameOfPropertyAccessOrAssignment(tx.parentNode, node) { + if tx.lexicalArguments.binding != nil && + node.Text() == "arguments" && + !ast.IsIdentifierName(node) && + !ast.IsLabelName(node) { tx.lexicalArguments.used = true return tx.lexicalArguments.binding } @@ -119,23 +119,11 @@ func (tx *asyncTransformer) fallbackVisitor(node *ast.Node) *ast.Node { return tx.fallbackNodeVisitor.VisitEachChild(node) } -func (tx *asyncTransformer) descendInto(node *ast.Node) func() { - savedParent := tx.parentNode - tx.parentNode = tx.currentNode - tx.currentNode = node - return func() { tx.currentNode = tx.parentNode; tx.parentNode = savedParent } -} - func (tx *asyncTransformer) visitFallback(node *ast.Node) *ast.Node { - cleanup := tx.descendInto(node) - defer cleanup() return tx.fallbackVisitor(node) } func (tx *asyncTransformer) visit(node *ast.Node) *ast.Node { - cleanup := tx.descendInto(node) - defer cleanup() - if node.SubtreeFacts()&(ast.SubtreeContainsAnyAwait|ast.SubtreeContainsAwait) == 0 { return tx.fallbackVisitor(node) } @@ -965,12 +953,6 @@ func (tx *asyncTransformer) getOriginalIfFunctionLike(node *ast.Node) *ast.Node return node } -func isNameOfPropertyAccessOrAssignment(parent *ast.Node, node *ast.Node) bool { - return parent != nil && - (ast.IsPropertyAccessExpression(parent) || ast.IsPropertyAssignment(parent)) && - parent.Name() == node -} - // isSimpleParameterList checks if every parameter has no initializer and an Identifier name. func isSimpleParameterList(params []*ast.Node) bool { for _, param := range params { diff --git a/testdata/baselines/reference/compiler/asyncDestructuringArgumentsProperty.js b/testdata/baselines/reference/compiler/asyncDestructuringArgumentsProperty.js new file mode 100644 index 00000000000..8dfdbbdc4a5 --- /dev/null +++ b/testdata/baselines/reference/compiler/asyncDestructuringArgumentsProperty.js @@ -0,0 +1,26 @@ +//// [tests/cases/compiler/asyncDestructuringArgumentsProperty.ts] //// + +//// [asyncDestructuringArgumentsProperty.ts] +async function f() { + const { arguments: args } = await { arguments: 42 }; + return args; +} + + +//// [asyncDestructuringArgumentsProperty.js] +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +function f() { + return __awaiter(this, void 0, void 0, function* () { + const { arguments: args } = yield { arguments: 42 }; + return args; + }); +} diff --git a/testdata/baselines/reference/compiler/asyncDestructuringArgumentsProperty.symbols b/testdata/baselines/reference/compiler/asyncDestructuringArgumentsProperty.symbols new file mode 100644 index 00000000000..b36b9d30c07 --- /dev/null +++ b/testdata/baselines/reference/compiler/asyncDestructuringArgumentsProperty.symbols @@ -0,0 +1,15 @@ +//// [tests/cases/compiler/asyncDestructuringArgumentsProperty.ts] //// + +=== asyncDestructuringArgumentsProperty.ts === +async function f() { +>f : Symbol(f, Decl(asyncDestructuringArgumentsProperty.ts, 0, 0)) + + const { arguments: args } = await { arguments: 42 }; +>arguments : Symbol(arguments, Decl(asyncDestructuringArgumentsProperty.ts, 1, 37)) +>args : Symbol(args, Decl(asyncDestructuringArgumentsProperty.ts, 1, 9)) +>arguments : Symbol(arguments, Decl(asyncDestructuringArgumentsProperty.ts, 1, 37)) + + return args; +>args : Symbol(args, Decl(asyncDestructuringArgumentsProperty.ts, 1, 9)) +} + diff --git a/testdata/baselines/reference/compiler/asyncDestructuringArgumentsProperty.types b/testdata/baselines/reference/compiler/asyncDestructuringArgumentsProperty.types new file mode 100644 index 00000000000..c563b782d02 --- /dev/null +++ b/testdata/baselines/reference/compiler/asyncDestructuringArgumentsProperty.types @@ -0,0 +1,18 @@ +//// [tests/cases/compiler/asyncDestructuringArgumentsProperty.ts] //// + +=== asyncDestructuringArgumentsProperty.ts === +async function f() { +>f : () => Promise + + const { arguments: args } = await { arguments: 42 }; +>arguments : any +>args : number +>await { arguments: 42 } : { arguments: number; } +>{ arguments: 42 } : { arguments: number; } +>arguments : number +>42 : 42 + + return args; +>args : number +} + diff --git a/testdata/baselines/reference/compiler/asyncJsxArgumentsAttributeName.js b/testdata/baselines/reference/compiler/asyncJsxArgumentsAttributeName.js new file mode 100644 index 00000000000..ba01d7dcca5 --- /dev/null +++ b/testdata/baselines/reference/compiler/asyncJsxArgumentsAttributeName.js @@ -0,0 +1,28 @@ +//// [tests/cases/compiler/asyncJsxArgumentsAttributeName.ts] //// + +//// [test.tsx] +declare namespace JSX { + interface IntrinsicElements { div: any; } +} + +async function f() { + return
; +} + + +//// [test.jsx] +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +function f() { + return __awaiter(this, void 0, void 0, function* () { + return
; + }); +} diff --git a/testdata/baselines/reference/compiler/asyncJsxArgumentsAttributeName.symbols b/testdata/baselines/reference/compiler/asyncJsxArgumentsAttributeName.symbols new file mode 100644 index 00000000000..b3c864c9c3f --- /dev/null +++ b/testdata/baselines/reference/compiler/asyncJsxArgumentsAttributeName.symbols @@ -0,0 +1,19 @@ +//// [tests/cases/compiler/asyncJsxArgumentsAttributeName.ts] //// + +=== test.tsx === +declare namespace JSX { +>JSX : Symbol(JSX, Decl(test.tsx, 0, 0)) + + interface IntrinsicElements { div: any; } +>IntrinsicElements : Symbol(IntrinsicElements, Decl(test.tsx, 0, 23)) +>div : Symbol(IntrinsicElements.div, Decl(test.tsx, 1, 31)) +} + +async function f() { +>f : Symbol(f, Decl(test.tsx, 2, 1)) + + return
; +>div : Symbol(JSX.IntrinsicElements.div, Decl(test.tsx, 1, 31)) +>arguments : Symbol(arguments, Decl(test.tsx, 5, 13)) +} + diff --git a/testdata/baselines/reference/compiler/asyncJsxArgumentsAttributeName.types b/testdata/baselines/reference/compiler/asyncJsxArgumentsAttributeName.types new file mode 100644 index 00000000000..de701a409b2 --- /dev/null +++ b/testdata/baselines/reference/compiler/asyncJsxArgumentsAttributeName.types @@ -0,0 +1,18 @@ +//// [tests/cases/compiler/asyncJsxArgumentsAttributeName.ts] //// + +=== test.tsx === +declare namespace JSX { + interface IntrinsicElements { div: any; } +>div : any +} + +async function f() { +>f : () => Promise + + return
; +>
: error +>div : any +>arguments : number +>42 : 42 +} + diff --git a/testdata/tests/cases/compiler/asyncDestructuringArgumentsProperty.ts b/testdata/tests/cases/compiler/asyncDestructuringArgumentsProperty.ts new file mode 100644 index 00000000000..fef3ebaff81 --- /dev/null +++ b/testdata/tests/cases/compiler/asyncDestructuringArgumentsProperty.ts @@ -0,0 +1,6 @@ +// @target: es2015 + +async function f() { + const { arguments: args } = await { arguments: 42 }; + return args; +} diff --git a/testdata/tests/cases/compiler/asyncJsxArgumentsAttributeName.ts b/testdata/tests/cases/compiler/asyncJsxArgumentsAttributeName.ts new file mode 100644 index 00000000000..66e15304dee --- /dev/null +++ b/testdata/tests/cases/compiler/asyncJsxArgumentsAttributeName.ts @@ -0,0 +1,11 @@ +// @target: es2015 +// @jsx: preserve + +// @filename: test.tsx +declare namespace JSX { + interface IntrinsicElements { div: any; } +} + +async function f() { + return
; +}