diff --git a/src/parser/traverser/expression.ts b/src/parser/traverser/expression.ts index 9ec20f68..a38cd162 100644 --- a/src/parser/traverser/expression.ts +++ b/src/parser/traverser/expression.ts @@ -57,7 +57,13 @@ import {ContextualKeyword} from "../tokenizer/keywords"; import {Scope} from "../tokenizer/state"; import {TokenType, TokenType as tt} from "../tokenizer/types"; import {getNextContextId, isFlowEnabled, isJSXEnabled, isTypeScriptEnabled, state} from "./base"; -import {parseMaybeDefault, parseRest, parseSpread} from "./lval"; +import { + markPriorBindingIdentifier, + parseBindingIdentifier, + parseMaybeDefault, + parseRest, + parseSpread, +} from "./lval"; import { parseBlock, parseClass, @@ -446,14 +452,16 @@ export function parseExprAtom(): boolean { contextualKeyword === ContextualKeyword._async && match(tt.name) ) { - parseIdentifier(); + parseBindingIdentifier(false); expect(tt.arrow); - // let foo = bar => {}; + // let foo = async bar => {}; parseArrowExpression(functionStart, startTokenIndex); return true; } - if (canBeArrow && !canInsertSemicolon() && eat(tt.arrow)) { + if (canBeArrow && !canInsertSemicolon() && match(tt.arrow)) { + markPriorBindingIdentifier(false); + expect(tt.arrow); parseArrowExpression(functionStart, startTokenIndex); return true; } diff --git a/src/parser/traverser/lval.ts b/src/parser/traverser/lval.ts index 9302146f..b3985e25 100644 --- a/src/parser/traverser/lval.ts +++ b/src/parser/traverser/lval.ts @@ -28,8 +28,15 @@ export function parseRest(isBlockScope: boolean): void { parseBindingAtom(isBlockScope); } -export function parseBindingIdentifier(): void { +export function parseBindingIdentifier(isBlockScope: boolean): void { parseIdentifier(); + markPriorBindingIdentifier(isBlockScope); +} + +export function markPriorBindingIdentifier(isBlockScope: boolean): void { + state.tokens[state.tokens.length - 1].identifierRole = isBlockScope + ? IdentifierRole.BlockScopedDeclaration + : IdentifierRole.FunctionScopedDeclaration; } // Parses lvalue (assignable) atom. @@ -46,10 +53,7 @@ export function parseBindingAtom(isBlockScope: boolean): void { case tt._yield: case tt.name: { state.type = tt.name; - parseBindingIdentifier(); - state.tokens[state.tokens.length - 1].identifierRole = isBlockScope - ? IdentifierRole.BlockScopedDeclaration - : IdentifierRole.FunctionScopedDeclaration; + parseBindingIdentifier(isBlockScope); return; } diff --git a/src/parser/traverser/statement.ts b/src/parser/traverser/statement.ts index b1c95fda..2ba225bd 100644 --- a/src/parser/traverser/statement.ts +++ b/src/parser/traverser/statement.ts @@ -568,8 +568,7 @@ export function parseFunction( if (!isStatement) { nameScopeStartTokenIndex = state.tokens.length; } - parseBindingIdentifier(); - state.tokens[state.tokens.length - 1].identifierRole = IdentifierRole.FunctionScopedDeclaration; + parseBindingIdentifier(false); } const startTokenIndex = state.tokens.length; diff --git a/test/imports-test.ts b/test/imports-test.ts index 02d006d7..620cd999 100644 --- a/test/imports-test.ts +++ b/test/imports-test.ts @@ -1125,4 +1125,40 @@ module.exports = exports.default; {transforms: ["imports", "typescript"]}, ); }); + + it("properly handles shadowing for simple arrow functions", () => { + assertResult( + ` + import a from 'a'; + const f = a => { + a(); + }; + `, + `"use strict";${IMPORT_DEFAULT_PREFIX} + + const f = a => { + a(); + }; + `, + {transforms: ["imports", "typescript"]}, + ); + }); + + it("properly handles shadowing for simple async arrow functions", () => { + assertResult( + ` + import a from 'a'; + const f = async a => { + a(); + }; + `, + `"use strict";${IMPORT_DEFAULT_PREFIX} + + const f = async a => { + a(); + }; + `, + {transforms: ["imports", "typescript"]}, + ); + }); });