From c670db79d4f61a6f2b22c3aedea28fa6b57dab3a Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Thu, 9 May 2024 11:25:39 -0700 Subject: [PATCH 1/6] Handle exported functions in ExportDeclarations for CJS/AMD/UMD emit --- src/compiler/transformers/utilities.ts | 43 ++++++++++++++++---------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/src/compiler/transformers/utilities.ts b/src/compiler/transformers/utilities.ts index 893460cf7a42f..4a456fa6b3415 100644 --- a/src/compiler/transformers/utilities.ts +++ b/src/compiler/transformers/utilities.ts @@ -256,22 +256,7 @@ export function collectExternalModuleInfo(context: TransformationContext, source case SyntaxKind.FunctionDeclaration: if (hasSyntacticModifier(node, ModifierFlags.Export)) { - exportedFunctions = append(exportedFunctions, node as FunctionDeclaration); - if (hasSyntacticModifier(node, ModifierFlags.Default)) { - // export default function() { } - if (!hasExportDefault) { - multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), context.factory.getDeclarationName(node as FunctionDeclaration)); - hasExportDefault = true; - } - } - else { - // export function x() { } - const name = (node as FunctionDeclaration).name!; - if (!uniqueExports.get(idText(name))) { - multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), name); - uniqueExports.set(idText(name), true); - } - } + addExportedFunctionDeclarartion(node as FunctionDeclaration, /*name*/ undefined, hasSyntacticModifier(node, ModifierFlags.Default)); } break; @@ -317,6 +302,11 @@ export function collectExternalModuleInfo(context: TransformationContext, source || resolver.getReferencedValueDeclaration(name); if (decl) { + if (decl.kind === SyntaxKind.FunctionDeclaration) { + addExportedFunctionDeclarartion(decl as FunctionDeclaration, specifier.name, specifier.name.escapedText === InternalSymbolName.Default); + continue; + } + multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(decl), specifier.name); } @@ -325,6 +315,27 @@ export function collectExternalModuleInfo(context: TransformationContext, source } } } + + function addExportedFunctionDeclarartion(node: FunctionDeclaration, name: Identifier | undefined, isDefault: boolean) { + exportedFunctions = append(exportedFunctions, node); + if (isDefault) { + // export default function() { } + // function x() { } + export { x as default }; + if (!hasExportDefault) { + multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), name ?? context.factory.getDeclarationName(node)); + hasExportDefault = true; + } + } + else { + // export function x() { } + // function x() { } + export { x } + name ??= node.name!; + if (!uniqueExports.get(idText(name))) { + multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), name); + uniqueExports.set(idText(name), true); + } + } + } } function collectExportedVariableInfo(decl: VariableDeclaration | BindingElement, uniqueExports: Map, exportedNames: Identifier[] | undefined, exportedBindings: Identifier[][]) { From 6570b9244c869b24683550026bd7ba2a66d274cd Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Thu, 9 May 2024 11:26:58 -0700 Subject: [PATCH 2/6] Update baselines --- .../reference/assertionFunctionWildcardImport2.js | 2 +- .../reference/declarationEmitInferredTypeAlias2.js | 3 ++- .../reference/declarationsForIndirectTypeAliasReference.js | 2 +- tests/baselines/reference/exportsAndImports1-amd.js | 3 ++- tests/baselines/reference/exportsAndImports1-es6.js | 3 ++- tests/baselines/reference/exportsAndImports1.js | 3 ++- tests/baselines/reference/exportsAndImports3-amd.js | 4 +++- tests/baselines/reference/exportsAndImports3-es6.js | 4 +++- tests/baselines/reference/exportsAndImports3.js | 4 +++- tests/baselines/reference/importNonExportedMember.js | 3 ++- tests/baselines/reference/importNonExportedMember1.js | 2 +- tests/baselines/reference/jsDeclarationsDefault.js | 4 +++- tests/baselines/reference/jsDeclarationsFunctions.js | 7 ++++++- tests/baselines/reference/jsxNamespaceReexports.js | 2 +- ...ModulesAllowJsGeneratedNameCollisions(module=node16).js | 3 ++- ...dulesAllowJsGeneratedNameCollisions(module=nodenext).js | 3 ++- .../nodeModulesGeneratedNameCollisions(module=node16).js | 3 ++- .../nodeModulesGeneratedNameCollisions(module=nodenext).js | 3 ++- tests/baselines/reference/reExportDefaultExport.js | 3 ++- .../spreadExpressionContextualTypeWithNamespace.js | 3 ++- tests/baselines/reference/valuesMergingAcrossModules.js | 2 +- 21 files changed, 45 insertions(+), 21 deletions(-) diff --git a/tests/baselines/reference/assertionFunctionWildcardImport2.js b/tests/baselines/reference/assertionFunctionWildcardImport2.js index ddc8713a11fd5..4d1beeec12f3c 100644 --- a/tests/baselines/reference/assertionFunctionWildcardImport2.js +++ b/tests/baselines/reference/assertionFunctionWildcardImport2.js @@ -23,7 +23,7 @@ function test(obj: string | null): void { //// [asserts.js] "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.isNonNullable = void 0; +exports.isNonNullable = isNonNullable; function isNonNullable(obj) { if (obj === undefined || obj === null) { throw new Error("Must not be a nullable value"); diff --git a/tests/baselines/reference/declarationEmitInferredTypeAlias2.js b/tests/baselines/reference/declarationEmitInferredTypeAlias2.js index 2b4273dda315b..9be3ac16bcdf8 100644 --- a/tests/baselines/reference/declarationEmitInferredTypeAlias2.js +++ b/tests/baselines/reference/declarationEmitInferredTypeAlias2.js @@ -23,7 +23,8 @@ Object.defineProperty(exports, "__esModule", { value: true }); //// [1.js] "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.bar = exports.v = void 0; +exports.v = void 0; +exports.bar = bar; var v = "str" || true; exports.v = v; function bar() { diff --git a/tests/baselines/reference/declarationsForIndirectTypeAliasReference.js b/tests/baselines/reference/declarationsForIndirectTypeAliasReference.js index e356338cf14dc..e16e1dc35efcb 100644 --- a/tests/baselines/reference/declarationsForIndirectTypeAliasReference.js +++ b/tests/baselines/reference/declarationsForIndirectTypeAliasReference.js @@ -39,7 +39,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); //// [a.js] "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.doSome = void 0; +exports.doSome = doSome; var MAP = { a: "a" }; diff --git a/tests/baselines/reference/exportsAndImports1-amd.js b/tests/baselines/reference/exportsAndImports1-amd.js index 4bb4dd61c602e..752885c6cc936 100644 --- a/tests/baselines/reference/exportsAndImports1-amd.js +++ b/tests/baselines/reference/exportsAndImports1-amd.js @@ -37,7 +37,8 @@ export { v, f, C, I, E, D, M, N, T, a }; define(["require", "exports"], function (require, exports) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); - exports.a = exports.M = exports.E = exports.C = exports.f = exports.v = void 0; + exports.a = exports.M = exports.E = exports.C = exports.v = void 0; + exports.f = f; var v = 1; exports.v = v; function f() { } diff --git a/tests/baselines/reference/exportsAndImports1-es6.js b/tests/baselines/reference/exportsAndImports1-es6.js index 0ae74e26e4050..ac5b0421b1c2e 100644 --- a/tests/baselines/reference/exportsAndImports1-es6.js +++ b/tests/baselines/reference/exportsAndImports1-es6.js @@ -36,7 +36,8 @@ export { v, f, C, I, E, D, M, N, T, a }; //// [t1.js] "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.a = exports.M = exports.E = exports.C = exports.f = exports.v = void 0; +exports.a = exports.M = exports.E = exports.C = exports.v = void 0; +exports.f = f; var v = 1; exports.v = v; function f() { } diff --git a/tests/baselines/reference/exportsAndImports1.js b/tests/baselines/reference/exportsAndImports1.js index a8dbd5b01c113..080433308cc4b 100644 --- a/tests/baselines/reference/exportsAndImports1.js +++ b/tests/baselines/reference/exportsAndImports1.js @@ -36,7 +36,8 @@ export { v, f, C, I, E, D, M, N, T, a }; //// [t1.js] "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.a = exports.M = exports.E = exports.C = exports.f = exports.v = void 0; +exports.a = exports.M = exports.E = exports.C = exports.v = void 0; +exports.f = f; var v = 1; exports.v = v; function f() { } diff --git a/tests/baselines/reference/exportsAndImports3-amd.js b/tests/baselines/reference/exportsAndImports3-amd.js index 2e1976b18e86f..21b15d0f4a732 100644 --- a/tests/baselines/reference/exportsAndImports3-amd.js +++ b/tests/baselines/reference/exportsAndImports3-amd.js @@ -37,7 +37,9 @@ export { v, f, C, I, E, D, M, N, T, a }; define(["require", "exports"], function (require, exports) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); - exports.a1 = exports.M1 = exports.E1 = exports.C1 = exports.f1 = exports.v1 = exports.a = exports.M = exports.E = exports.C = exports.v = void 0; + exports.a1 = exports.M1 = exports.E1 = exports.C1 = exports.v1 = exports.a = exports.M = exports.E = exports.C = exports.v = void 0; + exports.f = f; + exports.f1 = f; exports.f = f; exports.f1 = f; exports.v = 1; diff --git a/tests/baselines/reference/exportsAndImports3-es6.js b/tests/baselines/reference/exportsAndImports3-es6.js index e7d5bda14e57f..fd6e52e830363 100644 --- a/tests/baselines/reference/exportsAndImports3-es6.js +++ b/tests/baselines/reference/exportsAndImports3-es6.js @@ -36,7 +36,9 @@ export { v, f, C, I, E, D, M, N, T, a }; //// [t1.js] "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.a1 = exports.M1 = exports.E1 = exports.C1 = exports.f1 = exports.v1 = exports.a = exports.M = exports.E = exports.C = exports.v = void 0; +exports.a1 = exports.M1 = exports.E1 = exports.C1 = exports.v1 = exports.a = exports.M = exports.E = exports.C = exports.v = void 0; +exports.f = f; +exports.f1 = f; exports.f = f; exports.f1 = f; exports.v = 1; diff --git a/tests/baselines/reference/exportsAndImports3.js b/tests/baselines/reference/exportsAndImports3.js index 2714fe2ecaaf8..07c8c4cdae4fe 100644 --- a/tests/baselines/reference/exportsAndImports3.js +++ b/tests/baselines/reference/exportsAndImports3.js @@ -36,7 +36,9 @@ export { v, f, C, I, E, D, M, N, T, a }; //// [t1.js] "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.a1 = exports.M1 = exports.E1 = exports.C1 = exports.f1 = exports.v1 = exports.a = exports.M = exports.E = exports.C = exports.v = void 0; +exports.a1 = exports.M1 = exports.E1 = exports.C1 = exports.v1 = exports.a = exports.M = exports.E = exports.C = exports.v = void 0; +exports.f = f; +exports.f1 = f; exports.f = f; exports.f1 = f; exports.v = 1; diff --git a/tests/baselines/reference/importNonExportedMember.js b/tests/baselines/reference/importNonExportedMember.js index 8db7c1d65349e..9c935d0ac0ea5 100644 --- a/tests/baselines/reference/importNonExportedMember.js +++ b/tests/baselines/reference/importNonExportedMember.js @@ -12,7 +12,8 @@ import { foo, bar } from "./a"; //// [a.js] "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.baz = exports.foo = void 0; +exports.foo = foo; +exports.baz = bar; //// [b.js] "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/tests/baselines/reference/importNonExportedMember1.js b/tests/baselines/reference/importNonExportedMember1.js index f72561c644085..571284f4eb3c0 100644 --- a/tests/baselines/reference/importNonExportedMember1.js +++ b/tests/baselines/reference/importNonExportedMember1.js @@ -12,7 +12,7 @@ import { bar } from "./a"; //// [a.js] "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.foo = void 0; +exports.foo = foo; //// [b.js] "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/tests/baselines/reference/jsDeclarationsDefault.js b/tests/baselines/reference/jsDeclarationsDefault.js index 4c14181fcbf85..aa8d20b744d3e 100644 --- a/tests/baselines/reference/jsDeclarationsDefault.js +++ b/tests/baselines/reference/jsDeclarationsDefault.js @@ -46,7 +46,9 @@ exports.default = 12; //// [index2.js] "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.bar = exports.x = void 0; +exports.x = void 0; +exports.default = foo; +exports.bar = foo; exports.default = foo; exports.bar = foo; function foo() { diff --git a/tests/baselines/reference/jsDeclarationsFunctions.js b/tests/baselines/reference/jsDeclarationsFunctions.js index d8fe4ed52e2f6..28dbc68bc033d 100644 --- a/tests/baselines/reference/jsDeclarationsFunctions.js +++ b/tests/baselines/reference/jsDeclarationsFunctions.js @@ -63,15 +63,20 @@ export function j() {} //// [index.js] "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.jj = exports.ii = exports.h = exports.g = void 0; exports.a = a; exports.b = b; exports.c = c; exports.d = d; exports.e = e; exports.f = f; +exports.g = g; +exports.h = hh; exports.i = i; exports.ii = i; +exports.i = i; +exports.ii = i; +exports.j = j; +exports.jj = j; exports.j = j; exports.jj = j; function a() { } diff --git a/tests/baselines/reference/jsxNamespaceReexports.js b/tests/baselines/reference/jsxNamespaceReexports.js index bb65971d285b4..157c5ce7eb105 100644 --- a/tests/baselines/reference/jsxNamespaceReexports.js +++ b/tests/baselines/reference/jsxNamespaceReexports.js @@ -18,7 +18,7 @@ const content = ; //// [library.js] "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.createElement = void 0; +exports.createElement = createElement; function createElement(element, props) { var children = []; for (var _i = 2; _i < arguments.length; _i++) { diff --git a/tests/baselines/reference/nodeModulesAllowJsGeneratedNameCollisions(module=node16).js b/tests/baselines/reference/nodeModulesAllowJsGeneratedNameCollisions(module=node16).js index 39944c06ff259..30926a25ccde1 100644 --- a/tests/baselines/reference/nodeModulesAllowJsGeneratedNameCollisions(module=node16).js +++ b/tests/baselines/reference/nodeModulesAllowJsGeneratedNameCollisions(module=node16).js @@ -28,7 +28,8 @@ export {require, exports, Object}; //// [index.js] "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.Object = exports.exports = exports.require = exports.__esModule = void 0; +exports.Object = exports.exports = exports.__esModule = void 0; +exports.require = require; // cjs format file function require() { } const exports = {}; diff --git a/tests/baselines/reference/nodeModulesAllowJsGeneratedNameCollisions(module=nodenext).js b/tests/baselines/reference/nodeModulesAllowJsGeneratedNameCollisions(module=nodenext).js index 39944c06ff259..30926a25ccde1 100644 --- a/tests/baselines/reference/nodeModulesAllowJsGeneratedNameCollisions(module=nodenext).js +++ b/tests/baselines/reference/nodeModulesAllowJsGeneratedNameCollisions(module=nodenext).js @@ -28,7 +28,8 @@ export {require, exports, Object}; //// [index.js] "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.Object = exports.exports = exports.require = exports.__esModule = void 0; +exports.Object = exports.exports = exports.__esModule = void 0; +exports.require = require; // cjs format file function require() { } const exports = {}; diff --git a/tests/baselines/reference/nodeModulesGeneratedNameCollisions(module=node16).js b/tests/baselines/reference/nodeModulesGeneratedNameCollisions(module=node16).js index 1572a39c8d770..3b196cd32c98b 100644 --- a/tests/baselines/reference/nodeModulesGeneratedNameCollisions(module=node16).js +++ b/tests/baselines/reference/nodeModulesGeneratedNameCollisions(module=node16).js @@ -28,7 +28,8 @@ export {require, exports, Object}; //// [index.js] "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.Object = exports.exports = exports.require = exports.__esModule = void 0; +exports.Object = exports.exports = exports.__esModule = void 0; +exports.require = require; // cjs format file function require() { } const exports = {}; diff --git a/tests/baselines/reference/nodeModulesGeneratedNameCollisions(module=nodenext).js b/tests/baselines/reference/nodeModulesGeneratedNameCollisions(module=nodenext).js index 1572a39c8d770..3b196cd32c98b 100644 --- a/tests/baselines/reference/nodeModulesGeneratedNameCollisions(module=nodenext).js +++ b/tests/baselines/reference/nodeModulesGeneratedNameCollisions(module=nodenext).js @@ -28,7 +28,8 @@ export {require, exports, Object}; //// [index.js] "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.Object = exports.exports = exports.require = exports.__esModule = void 0; +exports.Object = exports.exports = exports.__esModule = void 0; +exports.require = require; // cjs format file function require() { } const exports = {}; diff --git a/tests/baselines/reference/reExportDefaultExport.js b/tests/baselines/reference/reExportDefaultExport.js index 71ba9c96f931a..3fbcde469b240 100644 --- a/tests/baselines/reference/reExportDefaultExport.js +++ b/tests/baselines/reference/reExportDefaultExport.js @@ -16,7 +16,8 @@ foo(); //// [m1.js] "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.f = void 0; +exports.default = f; +exports.f = f; exports.default = f; exports.f = f; function f() { diff --git a/tests/baselines/reference/spreadExpressionContextualTypeWithNamespace.js b/tests/baselines/reference/spreadExpressionContextualTypeWithNamespace.js index e09a3c117267d..3edec230fe0f8 100644 --- a/tests/baselines/reference/spreadExpressionContextualTypeWithNamespace.js +++ b/tests/baselines/reference/spreadExpressionContextualTypeWithNamespace.js @@ -38,7 +38,8 @@ getStuff().exportedDirectly; "use strict"; // Repro from #44179 with some modification Object.defineProperty(exports, "__esModule", { value: true }); -exports.obj = exports.klass = exports.func = void 0; +exports.obj = exports.klass = void 0; +exports.func = func; exports.exportedDirectly = exportedDirectly; function func() { } var klass = /** @class */ (function () { diff --git a/tests/baselines/reference/valuesMergingAcrossModules.js b/tests/baselines/reference/valuesMergingAcrossModules.js index adf0e145cb497..2f536cb52d330 100644 --- a/tests/baselines/reference/valuesMergingAcrossModules.js +++ b/tests/baselines/reference/valuesMergingAcrossModules.js @@ -22,7 +22,7 @@ A.displayName; //// [a.js] "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.A = void 0; +exports.A = A; function A() { } //// [b.js] "use strict"; From 2d7d90778e41626f970740b984f3c779b6bb284a Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Thu, 9 May 2024 12:50:35 -0700 Subject: [PATCH 3/6] Typo --- src/compiler/transformers/utilities.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/compiler/transformers/utilities.ts b/src/compiler/transformers/utilities.ts index 4a456fa6b3415..3fa648809bd79 100644 --- a/src/compiler/transformers/utilities.ts +++ b/src/compiler/transformers/utilities.ts @@ -256,7 +256,7 @@ export function collectExternalModuleInfo(context: TransformationContext, source case SyntaxKind.FunctionDeclaration: if (hasSyntacticModifier(node, ModifierFlags.Export)) { - addExportedFunctionDeclarartion(node as FunctionDeclaration, /*name*/ undefined, hasSyntacticModifier(node, ModifierFlags.Default)); + addExportedFunctionDeclaration(node as FunctionDeclaration, /*name*/ undefined, hasSyntacticModifier(node, ModifierFlags.Default)); } break; @@ -303,7 +303,7 @@ export function collectExternalModuleInfo(context: TransformationContext, source if (decl) { if (decl.kind === SyntaxKind.FunctionDeclaration) { - addExportedFunctionDeclarartion(decl as FunctionDeclaration, specifier.name, specifier.name.escapedText === InternalSymbolName.Default); + addExportedFunctionDeclaration(decl as FunctionDeclaration, specifier.name, specifier.name.escapedText === InternalSymbolName.Default); continue; } @@ -316,7 +316,7 @@ export function collectExternalModuleInfo(context: TransformationContext, source } } - function addExportedFunctionDeclarartion(node: FunctionDeclaration, name: Identifier | undefined, isDefault: boolean) { + function addExportedFunctionDeclaration(node: FunctionDeclaration, name: Identifier | undefined, isDefault: boolean) { exportedFunctions = append(exportedFunctions, node); if (isDefault) { // export default function() { } From d65145fbe9da3e9212516858fb96d92084356f98 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Thu, 9 May 2024 13:04:20 -0700 Subject: [PATCH 4/6] Fix duplication --- src/compiler/transformers/module/module.ts | 4 ++-- src/compiler/transformers/module/system.ts | 2 +- src/compiler/transformers/utilities.ts | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index 9336c54a40fb6..47a087a772f5a 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -283,7 +283,7 @@ export function transformModule(context: TransformationContext): (x: SourceFile ); } } - if (some(currentModuleInfo.exportedFunctions)) { + if (currentModuleInfo.exportedFunctions) { for (const f of currentModuleInfo.exportedFunctions) { appendExportsOfHoistedDeclaration(statements, f); } @@ -613,7 +613,7 @@ export function transformModule(context: TransformationContext): (x: SourceFile if (some(currentModuleInfo.exportedNames)) { append(statements, factory.createExpressionStatement(reduceLeft(currentModuleInfo.exportedNames, (prev, nextId) => factory.createAssignment(factory.createPropertyAccessExpression(factory.createIdentifier("exports"), factory.createIdentifier(idText(nextId))), prev), factory.createVoidZero() as Expression))); } - if (some(currentModuleInfo.exportedFunctions)) { + if (currentModuleInfo.exportedFunctions) { for (const f of currentModuleInfo.exportedFunctions) { appendExportsOfHoistedDeclaration(statements, f); } diff --git a/src/compiler/transformers/module/system.ts b/src/compiler/transformers/module/system.ts index 5f79baf03fe54..5bb5673ff07fb 100644 --- a/src/compiler/transformers/module/system.ts +++ b/src/compiler/transformers/module/system.ts @@ -433,7 +433,7 @@ export function transformSystemModule(context: TransformationContext): (x: Sourc // this set is used to filter names brought by star expors. // local names set should only be added if we have anything exported - if (!some(moduleInfo.exportedNames) && !some(moduleInfo.exportedFunctions) && moduleInfo.exportSpecifiers.size === 0) { + if (!some(moduleInfo.exportedNames) && !moduleInfo.exportedFunctions?.size && moduleInfo.exportSpecifiers.size === 0) { // no exported declarations (export var ...) or export specifiers (export {x}) // check if we have any non star export declarations. let hasExportDeclarationWithExportClause = false; diff --git a/src/compiler/transformers/utilities.ts b/src/compiler/transformers/utilities.ts index 3fa648809bd79..807aada4427de 100644 --- a/src/compiler/transformers/utilities.ts +++ b/src/compiler/transformers/utilities.ts @@ -105,7 +105,7 @@ export interface ExternalModuleInfo { exportSpecifiers: IdentifierNameMap; // file-local export specifiers by name (no reexports) exportedBindings: Identifier[][]; // exported names of local declarations exportedNames: Identifier[] | undefined; // all exported names in the module, both local and reexported, excluding the names of locally exported function declarations - exportedFunctions: FunctionDeclaration[] | undefined; // all of the top-level exported function declarations + exportedFunctions: Set | undefined; // all of the top-level exported function declarations exportEquals: ExportAssignment | undefined; // an export= declaration if one was present hasExportStarsToExportValues: boolean; // whether this module contains export* } @@ -175,7 +175,7 @@ export function collectExternalModuleInfo(context: TransformationContext, source const exportedBindings: Identifier[][] = []; const uniqueExports = new Map(); let exportedNames: Identifier[] | undefined; - let exportedFunctions: FunctionDeclaration[] | undefined; + let exportedFunctions: Set | undefined; let hasExportDefault = false; let exportEquals: ExportAssignment | undefined; let hasExportStarsToExportValues = false; @@ -317,7 +317,7 @@ export function collectExternalModuleInfo(context: TransformationContext, source } function addExportedFunctionDeclaration(node: FunctionDeclaration, name: Identifier | undefined, isDefault: boolean) { - exportedFunctions = append(exportedFunctions, node); + (exportedFunctions ??= new Set()).add(node); if (isDefault) { // export default function() { } // function x() { } + export { x as default }; From d522648b02de7908cf22cfbd39815cde9b72e636 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Thu, 9 May 2024 13:04:27 -0700 Subject: [PATCH 5/6] Update baselines --- tests/baselines/reference/exportsAndImports3-amd.js | 2 -- tests/baselines/reference/exportsAndImports3-es6.js | 2 -- tests/baselines/reference/exportsAndImports3.js | 2 -- tests/baselines/reference/jsDeclarationsDefault.js | 2 -- tests/baselines/reference/jsDeclarationsFunctions.js | 4 ---- tests/baselines/reference/reExportDefaultExport.js | 2 -- 6 files changed, 14 deletions(-) diff --git a/tests/baselines/reference/exportsAndImports3-amd.js b/tests/baselines/reference/exportsAndImports3-amd.js index 21b15d0f4a732..2c52509189182 100644 --- a/tests/baselines/reference/exportsAndImports3-amd.js +++ b/tests/baselines/reference/exportsAndImports3-amd.js @@ -40,8 +40,6 @@ define(["require", "exports"], function (require, exports) { exports.a1 = exports.M1 = exports.E1 = exports.C1 = exports.v1 = exports.a = exports.M = exports.E = exports.C = exports.v = void 0; exports.f = f; exports.f1 = f; - exports.f = f; - exports.f1 = f; exports.v = 1; exports.v1 = exports.v; function f() { } diff --git a/tests/baselines/reference/exportsAndImports3-es6.js b/tests/baselines/reference/exportsAndImports3-es6.js index fd6e52e830363..50c7f861f7c07 100644 --- a/tests/baselines/reference/exportsAndImports3-es6.js +++ b/tests/baselines/reference/exportsAndImports3-es6.js @@ -39,8 +39,6 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.a1 = exports.M1 = exports.E1 = exports.C1 = exports.v1 = exports.a = exports.M = exports.E = exports.C = exports.v = void 0; exports.f = f; exports.f1 = f; -exports.f = f; -exports.f1 = f; exports.v = 1; exports.v1 = exports.v; function f() { } diff --git a/tests/baselines/reference/exportsAndImports3.js b/tests/baselines/reference/exportsAndImports3.js index 07c8c4cdae4fe..eede925b22a68 100644 --- a/tests/baselines/reference/exportsAndImports3.js +++ b/tests/baselines/reference/exportsAndImports3.js @@ -39,8 +39,6 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.a1 = exports.M1 = exports.E1 = exports.C1 = exports.v1 = exports.a = exports.M = exports.E = exports.C = exports.v = void 0; exports.f = f; exports.f1 = f; -exports.f = f; -exports.f1 = f; exports.v = 1; exports.v1 = exports.v; function f() { } diff --git a/tests/baselines/reference/jsDeclarationsDefault.js b/tests/baselines/reference/jsDeclarationsDefault.js index aa8d20b744d3e..4357bdd55759e 100644 --- a/tests/baselines/reference/jsDeclarationsDefault.js +++ b/tests/baselines/reference/jsDeclarationsDefault.js @@ -49,8 +49,6 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.x = void 0; exports.default = foo; exports.bar = foo; -exports.default = foo; -exports.bar = foo; function foo() { return foo; } diff --git a/tests/baselines/reference/jsDeclarationsFunctions.js b/tests/baselines/reference/jsDeclarationsFunctions.js index 28dbc68bc033d..b9c6f345cbeb9 100644 --- a/tests/baselines/reference/jsDeclarationsFunctions.js +++ b/tests/baselines/reference/jsDeclarationsFunctions.js @@ -73,10 +73,6 @@ exports.g = g; exports.h = hh; exports.i = i; exports.ii = i; -exports.i = i; -exports.ii = i; -exports.j = j; -exports.jj = j; exports.j = j; exports.jj = j; function a() { } diff --git a/tests/baselines/reference/reExportDefaultExport.js b/tests/baselines/reference/reExportDefaultExport.js index 3fbcde469b240..b0a50abe5170f 100644 --- a/tests/baselines/reference/reExportDefaultExport.js +++ b/tests/baselines/reference/reExportDefaultExport.js @@ -18,8 +18,6 @@ foo(); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = f; exports.f = f; -exports.default = f; -exports.f = f; function f() { } //// [m2.js] From 2faeb15abb6ae0dc22d51b571f3a60777b7988ce Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Thu, 9 May 2024 13:10:55 -0700 Subject: [PATCH 6/6] Use a plain set like the other variables returned here --- src/compiler/transformers/module/module.ts | 12 ++++------ src/compiler/transformers/module/system.ts | 28 ++++++++++------------ src/compiler/transformers/utilities.ts | 6 ++--- 3 files changed, 20 insertions(+), 26 deletions(-) diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index 47a087a772f5a..92b214276e533 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -283,10 +283,8 @@ export function transformModule(context: TransformationContext): (x: SourceFile ); } } - if (currentModuleInfo.exportedFunctions) { - for (const f of currentModuleInfo.exportedFunctions) { - appendExportsOfHoistedDeclaration(statements, f); - } + for (const f of currentModuleInfo.exportedFunctions) { + appendExportsOfHoistedDeclaration(statements, f); } append(statements, visitNode(currentModuleInfo.externalHelpersImportDeclaration, topLevelVisitor, isStatement)); @@ -613,10 +611,8 @@ export function transformModule(context: TransformationContext): (x: SourceFile if (some(currentModuleInfo.exportedNames)) { append(statements, factory.createExpressionStatement(reduceLeft(currentModuleInfo.exportedNames, (prev, nextId) => factory.createAssignment(factory.createPropertyAccessExpression(factory.createIdentifier("exports"), factory.createIdentifier(idText(nextId))), prev), factory.createVoidZero() as Expression))); } - if (currentModuleInfo.exportedFunctions) { - for (const f of currentModuleInfo.exportedFunctions) { - appendExportsOfHoistedDeclaration(statements, f); - } + for (const f of currentModuleInfo.exportedFunctions) { + appendExportsOfHoistedDeclaration(statements, f); } // Visit each statement of the module body. diff --git a/src/compiler/transformers/module/system.ts b/src/compiler/transformers/module/system.ts index 5bb5673ff07fb..f03ad63a1c0ca 100644 --- a/src/compiler/transformers/module/system.ts +++ b/src/compiler/transformers/module/system.ts @@ -433,7 +433,7 @@ export function transformSystemModule(context: TransformationContext): (x: Sourc // this set is used to filter names brought by star expors. // local names set should only be added if we have anything exported - if (!some(moduleInfo.exportedNames) && !moduleInfo.exportedFunctions?.size && moduleInfo.exportSpecifiers.size === 0) { + if (!some(moduleInfo.exportedNames) && moduleInfo.exportedFunctions.size === 0 && moduleInfo.exportSpecifiers.size === 0) { // no exported declarations (export var ...) or export specifiers (export {x}) // check if we have any non star export declarations. let hasExportDeclarationWithExportClause = false; @@ -469,21 +469,19 @@ export function transformSystemModule(context: TransformationContext): (x: Sourc } } - if (moduleInfo.exportedFunctions) { - for (const f of moduleInfo.exportedFunctions) { - if (hasSyntacticModifier(f, ModifierFlags.Default)) { - continue; - } - Debug.assert(!!f.name); - - // write name of exported declaration, i.e 'export var x...' - exportedNames.push( - factory.createPropertyAssignment( - factory.createStringLiteralFromNode(f.name), - factory.createTrue(), - ), - ); + for (const f of moduleInfo.exportedFunctions) { + if (hasSyntacticModifier(f, ModifierFlags.Default)) { + continue; } + Debug.assert(!!f.name); + + // write name of exported declaration, i.e 'export var x...' + exportedNames.push( + factory.createPropertyAssignment( + factory.createStringLiteralFromNode(f.name), + factory.createTrue(), + ), + ); } const exportedNamesStorageRef = factory.createUniqueName("exportedNames"); diff --git a/src/compiler/transformers/utilities.ts b/src/compiler/transformers/utilities.ts index 807aada4427de..8f5f2b257a004 100644 --- a/src/compiler/transformers/utilities.ts +++ b/src/compiler/transformers/utilities.ts @@ -105,7 +105,7 @@ export interface ExternalModuleInfo { exportSpecifiers: IdentifierNameMap; // file-local export specifiers by name (no reexports) exportedBindings: Identifier[][]; // exported names of local declarations exportedNames: Identifier[] | undefined; // all exported names in the module, both local and reexported, excluding the names of locally exported function declarations - exportedFunctions: Set | undefined; // all of the top-level exported function declarations + exportedFunctions: Set; // all of the top-level exported function declarations exportEquals: ExportAssignment | undefined; // an export= declaration if one was present hasExportStarsToExportValues: boolean; // whether this module contains export* } @@ -174,8 +174,8 @@ export function collectExternalModuleInfo(context: TransformationContext, source const exportSpecifiers = new IdentifierNameMultiMap(); const exportedBindings: Identifier[][] = []; const uniqueExports = new Map(); + const exportedFunctions = new Set(); let exportedNames: Identifier[] | undefined; - let exportedFunctions: Set | undefined; let hasExportDefault = false; let exportEquals: ExportAssignment | undefined; let hasExportStarsToExportValues = false; @@ -317,7 +317,7 @@ export function collectExternalModuleInfo(context: TransformationContext, source } function addExportedFunctionDeclaration(node: FunctionDeclaration, name: Identifier | undefined, isDefault: boolean) { - (exportedFunctions ??= new Set()).add(node); + exportedFunctions.add(node); if (isDefault) { // export default function() { } // function x() { } + export { x as default };