From dd1ef88d016dc40a145eafc0a1169e7f0a4a9ebe Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Tue, 6 Apr 2021 17:07:35 -0700 Subject: [PATCH] Use control flow to type CommonJS exports (#42751) * Allow redeclaring CommonJS alias with initial undefined This allows us to read our own output, plus the times when people manually write exactly the same pattern. Fixes #40555 * Use control flow to type commonjs exports 1. Could probably use a *lot* more tests. 2. getTypeOfAlias redoes some work from resolveAlias because it needs to not resolve the alias completely, just to its export. * fix lint, improve jsdoc * Add tests, improve+fix control flow 1. Update the module.exports test to match the exports ones. 2. Add a test of evolving commonjs type. 3. Add a test of assignment as last statement. (1) exposed a bug that required a better synthetic reference. (3) exposed a bug that was most easily fixed by giving source files a `endFlowNode` like functions and setting it in the binder. * fix lint --- src/compiler/binder.ts | 1 + src/compiler/checker.ts | 45 +++++++++--- src/compiler/types.ts | 1 + .../moduleExportDuplicateAlias.errors.txt | 20 +++--- .../reference/moduleExportDuplicateAlias.js | 20 +++++- .../moduleExportDuplicateAlias.symbols | 33 +++++++-- .../moduleExportDuplicateAlias.types | 31 +++++++-- .../reference/moduleExportDuplicateAlias2.js | 32 +++++++++ .../moduleExportDuplicateAlias2.symbols | 44 ++++++++++++ .../moduleExportDuplicateAlias2.types | 50 ++++++++++++++ .../reference/moduleExportDuplicateAlias3.js | 39 +++++++++++ .../moduleExportDuplicateAlias3.symbols | 57 ++++++++++++++++ .../moduleExportDuplicateAlias3.types | 68 +++++++++++++++++++ .../salsa/moduleExportDuplicateAlias.ts | 9 ++- .../salsa/moduleExportDuplicateAlias2.ts | 14 ++++ .../salsa/moduleExportDuplicateAlias3.ts | 17 +++++ 16 files changed, 450 insertions(+), 31 deletions(-) create mode 100644 tests/baselines/reference/moduleExportDuplicateAlias2.js create mode 100644 tests/baselines/reference/moduleExportDuplicateAlias2.symbols create mode 100644 tests/baselines/reference/moduleExportDuplicateAlias2.types create mode 100644 tests/baselines/reference/moduleExportDuplicateAlias3.js create mode 100644 tests/baselines/reference/moduleExportDuplicateAlias3.symbols create mode 100644 tests/baselines/reference/moduleExportDuplicateAlias3.types create mode 100644 tests/cases/conformance/salsa/moduleExportDuplicateAlias2.ts create mode 100644 tests/cases/conformance/salsa/moduleExportDuplicateAlias3.ts diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index c6a2b14afdf..7038d1121dd 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -683,6 +683,7 @@ namespace ts { } if (node.kind === SyntaxKind.SourceFile) { node.flags |= emitFlags; + (node as SourceFile).endFlowNode = currentFlow; } if (currentReturnTarget) { diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6d85af03e53..2d5db22a565 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2473,7 +2473,7 @@ namespace ts { } function getDeclarationOfAliasSymbol(symbol: Symbol): Declaration | undefined { - return symbol.declarations?.find(isAliasSymbolDeclaration); + return symbol.declarations && findLast(symbol.declarations, isAliasSymbolDeclaration); } /** @@ -8449,6 +8449,23 @@ namespace ts { }; } + /** Create a synthetic property access flow node after the last statement of the file */ + function getFlowTypeFromCommonJSExport(symbol: Symbol) { + const file = getSourceFileOfNode(symbol.declarations![0]); + const accessName = unescapeLeadingUnderscores(symbol.escapedName); + const areAllModuleExports = symbol.declarations!.every(d => isInJSFile(d) && isAccessExpression(d) && isModuleExportsAccessExpression(d.expression)); + const reference = areAllModuleExports + ? factory.createPropertyAccessExpression(factory.createPropertyAccessExpression(factory.createIdentifier("module"), factory.createIdentifier("exports")), accessName) + : factory.createPropertyAccessExpression(factory.createIdentifier("exports"), accessName); + if (areAllModuleExports) { + setParent((reference.expression as PropertyAccessExpression).expression, reference.expression); + } + setParent(reference.expression, reference); + setParent(reference, file); + reference.flowNode = file.endFlowNode; + return getFlowTypeOfReference(reference, autoType, undefinedType); + } + function getFlowTypeInConstructor(symbol: Symbol, constructor: ConstructorDeclaration) { const accessName = startsWith(symbol.escapedName as string, "__#") ? factory.createPrivateIdentifier((symbol.escapedName as string).split("@")[1]) @@ -9186,14 +9203,15 @@ namespace ts { const links = getSymbolLinks(symbol); if (!links.type) { const targetSymbol = resolveAlias(symbol); - + const exportSymbol = symbol.declarations && getTargetOfAliasDeclaration(getDeclarationOfAliasSymbol(symbol)!, /*dontResolveAlias*/ true); // It only makes sense to get the type of a value symbol. If the result of resolving // the alias is not a value, then it has no type. To get the type associated with a // type symbol, call getDeclaredTypeOfSymbol. // This check is important because without it, a call to getTypeOfSymbol could end // up recursively calling getTypeOfAlias, causing a stack overflow. - links.type = targetSymbol.flags & SymbolFlags.Value - ? getTypeOfSymbol(targetSymbol) + links.type = exportSymbol?.declarations && isDuplicatedCommonJSExport(exportSymbol.declarations) && symbol.declarations!.length ? getFlowTypeFromCommonJSExport(exportSymbol) + : isDuplicatedCommonJSExport(symbol.declarations) ? autoType + : targetSymbol.flags & SymbolFlags.Value ? getTypeOfSymbol(targetSymbol) : errorType; } return links.type; @@ -27133,7 +27151,10 @@ namespace ts { // accessor, or optional method. const assignmentKind = getAssignmentTargetKind(node); if (assignmentKind === AssignmentKind.Definite || - prop && !(prop.flags & (SymbolFlags.Variable | SymbolFlags.Property | SymbolFlags.Accessor)) && !(prop.flags & SymbolFlags.Method && propType.flags & TypeFlags.Union)) { + prop && + !(prop.flags & (SymbolFlags.Variable | SymbolFlags.Property | SymbolFlags.Accessor)) + && !(prop.flags & SymbolFlags.Method && propType.flags & TypeFlags.Union) + && !isDuplicatedCommonJSExport(prop.declarations)) { return propType; } if (propType === autoType) { @@ -38154,9 +38175,11 @@ namespace ts { return; } if (exportedDeclarationsCount > 1) { - for (const declaration of declarations!) { - if (isNotOverload(declaration)) { - diagnostics.add(createDiagnosticForNode(declaration, Diagnostics.Cannot_redeclare_exported_variable_0, unescapeLeadingUnderscores(id))); + if (!isDuplicatedCommonJSExport(declarations)) { + for (const declaration of declarations!) { + if (isNotOverload(declaration)) { + diagnostics.add(createDiagnosticForNode(declaration, Diagnostics.Cannot_redeclare_exported_variable_0, unescapeLeadingUnderscores(id))); + } } } } @@ -38166,6 +38189,12 @@ namespace ts { } } + function isDuplicatedCommonJSExport(declarations: Declaration[] | undefined) { + return declarations + && declarations.length > 1 + && declarations.every(d => isInJSFile(d) && isAccessExpression(d) && (isExportsIdentifier(d.expression) || isModuleExportsAccessExpression(d.expression))); + } + function checkSourceElement(node: Node | undefined): void { if (node) { const saveCurrentNode = currentNode; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index defe381d481..8709515aa5a 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3545,6 +3545,7 @@ namespace ts { /* @internal */ localJsxFragmentFactory?: EntityName; /* @internal */ exportedModulesFromDeclarationEmit?: ExportedModulesFromDeclarationEmit; + /* @internal */ endFlowNode?: FlowNode; } /* @internal */ diff --git a/tests/baselines/reference/moduleExportDuplicateAlias.errors.txt b/tests/baselines/reference/moduleExportDuplicateAlias.errors.txt index d216af6f764..e744496c41f 100644 --- a/tests/baselines/reference/moduleExportDuplicateAlias.errors.txt +++ b/tests/baselines/reference/moduleExportDuplicateAlias.errors.txt @@ -1,16 +1,16 @@ -tests/cases/conformance/salsa/moduleExportAliasDuplicateAlias.js(1,1): error TS2323: Cannot redeclare exported variable 'apply'. -tests/cases/conformance/salsa/moduleExportAliasDuplicateAlias.js(3,1): error TS2322: Type '() => void' is not assignable to type 'undefined'. -tests/cases/conformance/salsa/moduleExportAliasDuplicateAlias.js(3,1): error TS2323: Cannot redeclare exported variable 'apply'. +tests/cases/conformance/salsa/moduleExportAliasDuplicateAlias.js(3,1): error TS2722: Cannot invoke an object which is possibly 'undefined'. -==== tests/cases/conformance/salsa/moduleExportAliasDuplicateAlias.js (3 errors) ==== +==== tests/cases/conformance/salsa/test.js (0 errors) ==== + const { apply } = require('./moduleExportAliasDuplicateAlias') + apply() + +==== tests/cases/conformance/salsa/moduleExportAliasDuplicateAlias.js (1 errors) ==== exports.apply = undefined; - ~~~~~~~~~~~~~ -!!! error TS2323: Cannot redeclare exported variable 'apply'. function a() { } + exports.apply() + ~~~~~~~~~~~~~ +!!! error TS2722: Cannot invoke an object which is possibly 'undefined'. exports.apply = a; - ~~~~~~~~~~~~~ -!!! error TS2322: Type '() => void' is not assignable to type 'undefined'. - ~~~~~~~~~~~~~ -!!! error TS2323: Cannot redeclare exported variable 'apply'. + exports.apply() \ No newline at end of file diff --git a/tests/baselines/reference/moduleExportDuplicateAlias.js b/tests/baselines/reference/moduleExportDuplicateAlias.js index 305b19fd68b..f90ff20d565 100644 --- a/tests/baselines/reference/moduleExportDuplicateAlias.js +++ b/tests/baselines/reference/moduleExportDuplicateAlias.js @@ -1,14 +1,32 @@ +//// [tests/cases/conformance/salsa/moduleExportDuplicateAlias.ts] //// + //// [moduleExportAliasDuplicateAlias.js] exports.apply = undefined; function a() { } +exports.apply() exports.apply = a; +exports.apply() + +//// [test.js] +const { apply } = require('./moduleExportAliasDuplicateAlias') +apply() //// [moduleExportAliasDuplicateAlias.js] +"use strict"; exports.apply = undefined; function a() { } +exports.apply(); exports.apply = a; +exports.apply(); +//// [test.js] +"use strict"; +var apply = require('./moduleExportAliasDuplicateAlias').apply; +apply(); //// [moduleExportAliasDuplicateAlias.d.ts] -export { undefined as apply }; +export { a as apply }; +declare function a(): void; +//// [test.d.ts] +export {}; diff --git a/tests/baselines/reference/moduleExportDuplicateAlias.symbols b/tests/baselines/reference/moduleExportDuplicateAlias.symbols index 5c9bfaae375..f8907d2abb8 100644 --- a/tests/baselines/reference/moduleExportDuplicateAlias.symbols +++ b/tests/baselines/reference/moduleExportDuplicateAlias.symbols @@ -1,16 +1,35 @@ +=== tests/cases/conformance/salsa/test.js === +const { apply } = require('./moduleExportAliasDuplicateAlias') +>apply : Symbol(apply, Decl(test.js, 0, 7)) +>require : Symbol(require) +>'./moduleExportAliasDuplicateAlias' : Symbol("tests/cases/conformance/salsa/moduleExportAliasDuplicateAlias", Decl(moduleExportAliasDuplicateAlias.js, 0, 0)) + +apply() +>apply : Symbol(apply, Decl(test.js, 0, 7)) + === tests/cases/conformance/salsa/moduleExportAliasDuplicateAlias.js === exports.apply = undefined; ->exports.apply : Symbol(apply, Decl(moduleExportAliasDuplicateAlias.js, 0, 0), Decl(moduleExportAliasDuplicateAlias.js, 1, 16)) ->exports : Symbol(apply, Decl(moduleExportAliasDuplicateAlias.js, 0, 0), Decl(moduleExportAliasDuplicateAlias.js, 1, 16)) ->apply : Symbol(apply, Decl(moduleExportAliasDuplicateAlias.js, 0, 0), Decl(moduleExportAliasDuplicateAlias.js, 1, 16)) ->undefined : Symbol(apply) +>exports.apply : Symbol(apply, Decl(moduleExportAliasDuplicateAlias.js, 0, 0), Decl(moduleExportAliasDuplicateAlias.js, 2, 15)) +>exports : Symbol(apply, Decl(moduleExportAliasDuplicateAlias.js, 0, 0), Decl(moduleExportAliasDuplicateAlias.js, 2, 15)) +>apply : Symbol(apply, Decl(moduleExportAliasDuplicateAlias.js, 0, 0), Decl(moduleExportAliasDuplicateAlias.js, 2, 15)) +>undefined : Symbol(undefined) function a() { } >a : Symbol(a, Decl(moduleExportAliasDuplicateAlias.js, 0, 26)) +exports.apply() +>exports.apply : Symbol(apply, Decl(moduleExportAliasDuplicateAlias.js, 0, 0), Decl(moduleExportAliasDuplicateAlias.js, 2, 15)) +>exports : Symbol("tests/cases/conformance/salsa/moduleExportAliasDuplicateAlias", Decl(moduleExportAliasDuplicateAlias.js, 0, 0)) +>apply : Symbol(apply, Decl(moduleExportAliasDuplicateAlias.js, 0, 0), Decl(moduleExportAliasDuplicateAlias.js, 2, 15)) + exports.apply = a; ->exports.apply : Symbol(apply, Decl(moduleExportAliasDuplicateAlias.js, 0, 0), Decl(moduleExportAliasDuplicateAlias.js, 1, 16)) ->exports : Symbol(apply, Decl(moduleExportAliasDuplicateAlias.js, 0, 0), Decl(moduleExportAliasDuplicateAlias.js, 1, 16)) ->apply : Symbol(apply, Decl(moduleExportAliasDuplicateAlias.js, 0, 0), Decl(moduleExportAliasDuplicateAlias.js, 1, 16)) +>exports.apply : Symbol(apply, Decl(moduleExportAliasDuplicateAlias.js, 0, 0), Decl(moduleExportAliasDuplicateAlias.js, 2, 15)) +>exports : Symbol(apply, Decl(moduleExportAliasDuplicateAlias.js, 0, 0), Decl(moduleExportAliasDuplicateAlias.js, 2, 15)) +>apply : Symbol(apply, Decl(moduleExportAliasDuplicateAlias.js, 0, 0), Decl(moduleExportAliasDuplicateAlias.js, 2, 15)) >a : Symbol(a, Decl(moduleExportAliasDuplicateAlias.js, 0, 26)) +exports.apply() +>exports.apply : Symbol(apply, Decl(moduleExportAliasDuplicateAlias.js, 0, 0), Decl(moduleExportAliasDuplicateAlias.js, 2, 15)) +>exports : Symbol("tests/cases/conformance/salsa/moduleExportAliasDuplicateAlias", Decl(moduleExportAliasDuplicateAlias.js, 0, 0)) +>apply : Symbol(apply, Decl(moduleExportAliasDuplicateAlias.js, 0, 0), Decl(moduleExportAliasDuplicateAlias.js, 2, 15)) + diff --git a/tests/baselines/reference/moduleExportDuplicateAlias.types b/tests/baselines/reference/moduleExportDuplicateAlias.types index 1c924ac41e6..1ea6ae6082f 100644 --- a/tests/baselines/reference/moduleExportDuplicateAlias.types +++ b/tests/baselines/reference/moduleExportDuplicateAlias.types @@ -1,18 +1,41 @@ +=== tests/cases/conformance/salsa/test.js === +const { apply } = require('./moduleExportAliasDuplicateAlias') +>apply : () => void +>require('./moduleExportAliasDuplicateAlias') : typeof import("tests/cases/conformance/salsa/moduleExportAliasDuplicateAlias") +>require : any +>'./moduleExportAliasDuplicateAlias' : "./moduleExportAliasDuplicateAlias" + +apply() +>apply() : void +>apply : () => void + === tests/cases/conformance/salsa/moduleExportAliasDuplicateAlias.js === exports.apply = undefined; >exports.apply = undefined : undefined ->exports.apply : undefined +>exports.apply : any >exports : typeof import("tests/cases/conformance/salsa/moduleExportAliasDuplicateAlias") ->apply : undefined +>apply : any >undefined : undefined function a() { } >a : () => void -exports.apply = a; ->exports.apply = a : () => void +exports.apply() +>exports.apply() : any >exports.apply : undefined >exports : typeof import("tests/cases/conformance/salsa/moduleExportAliasDuplicateAlias") >apply : undefined + +exports.apply = a; +>exports.apply = a : () => void +>exports.apply : any +>exports : typeof import("tests/cases/conformance/salsa/moduleExportAliasDuplicateAlias") +>apply : any >a : () => void +exports.apply() +>exports.apply() : void +>exports.apply : () => void +>exports : typeof import("tests/cases/conformance/salsa/moduleExportAliasDuplicateAlias") +>apply : () => void + diff --git a/tests/baselines/reference/moduleExportDuplicateAlias2.js b/tests/baselines/reference/moduleExportDuplicateAlias2.js new file mode 100644 index 00000000000..89059dcd4f7 --- /dev/null +++ b/tests/baselines/reference/moduleExportDuplicateAlias2.js @@ -0,0 +1,32 @@ +//// [tests/cases/conformance/salsa/moduleExportDuplicateAlias2.ts] //// + +//// [moduleExportAliasDuplicateAlias.js] +module.exports.apply = undefined; +function a() { } +module.exports.apply = a; +module.exports.apply = a; +module.exports.apply() + +//// [test.js] +const { apply } = require('./moduleExportAliasDuplicateAlias') +apply() + + +//// [moduleExportAliasDuplicateAlias.js] +"use strict"; +module.exports.apply = undefined; +function a() { } +module.exports.apply = a; +module.exports.apply = a; +module.exports.apply(); +//// [test.js] +"use strict"; +var apply = require('./moduleExportAliasDuplicateAlias').apply; +apply(); + + +//// [moduleExportAliasDuplicateAlias.d.ts] +export { a as apply }; +declare function a(): void; +//// [test.d.ts] +export {}; diff --git a/tests/baselines/reference/moduleExportDuplicateAlias2.symbols b/tests/baselines/reference/moduleExportDuplicateAlias2.symbols new file mode 100644 index 00000000000..0419db925b9 --- /dev/null +++ b/tests/baselines/reference/moduleExportDuplicateAlias2.symbols @@ -0,0 +1,44 @@ +=== tests/cases/conformance/salsa/test.js === +const { apply } = require('./moduleExportAliasDuplicateAlias') +>apply : Symbol(apply, Decl(test.js, 0, 7)) +>require : Symbol(require) +>'./moduleExportAliasDuplicateAlias' : Symbol("tests/cases/conformance/salsa/moduleExportAliasDuplicateAlias", Decl(moduleExportAliasDuplicateAlias.js, 0, 0)) + +apply() +>apply : Symbol(apply, Decl(test.js, 0, 7)) + +=== tests/cases/conformance/salsa/moduleExportAliasDuplicateAlias.js === +module.exports.apply = undefined; +>module.exports.apply : Symbol(apply, Decl(moduleExportAliasDuplicateAlias.js, 0, 0), Decl(moduleExportAliasDuplicateAlias.js, 1, 16), Decl(moduleExportAliasDuplicateAlias.js, 2, 25)) +>module.exports : Symbol(apply, Decl(moduleExportAliasDuplicateAlias.js, 0, 0), Decl(moduleExportAliasDuplicateAlias.js, 1, 16), Decl(moduleExportAliasDuplicateAlias.js, 2, 25)) +>module : Symbol(module, Decl(moduleExportAliasDuplicateAlias.js, 0, 0)) +>exports : Symbol(module.exports, Decl(moduleExportAliasDuplicateAlias.js, 0, 0)) +>apply : Symbol(apply, Decl(moduleExportAliasDuplicateAlias.js, 0, 0), Decl(moduleExportAliasDuplicateAlias.js, 1, 16), Decl(moduleExportAliasDuplicateAlias.js, 2, 25)) +>undefined : Symbol(undefined) + +function a() { } +>a : Symbol(a, Decl(moduleExportAliasDuplicateAlias.js, 0, 33)) + +module.exports.apply = a; +>module.exports.apply : Symbol(apply, Decl(moduleExportAliasDuplicateAlias.js, 0, 0), Decl(moduleExportAliasDuplicateAlias.js, 1, 16), Decl(moduleExportAliasDuplicateAlias.js, 2, 25)) +>module.exports : Symbol(apply, Decl(moduleExportAliasDuplicateAlias.js, 0, 0), Decl(moduleExportAliasDuplicateAlias.js, 1, 16), Decl(moduleExportAliasDuplicateAlias.js, 2, 25)) +>module : Symbol(module, Decl(moduleExportAliasDuplicateAlias.js, 0, 0)) +>exports : Symbol(module.exports, Decl(moduleExportAliasDuplicateAlias.js, 0, 0)) +>apply : Symbol(apply, Decl(moduleExportAliasDuplicateAlias.js, 0, 0), Decl(moduleExportAliasDuplicateAlias.js, 1, 16), Decl(moduleExportAliasDuplicateAlias.js, 2, 25)) +>a : Symbol(a, Decl(moduleExportAliasDuplicateAlias.js, 0, 33)) + +module.exports.apply = a; +>module.exports.apply : Symbol(apply, Decl(moduleExportAliasDuplicateAlias.js, 0, 0), Decl(moduleExportAliasDuplicateAlias.js, 1, 16), Decl(moduleExportAliasDuplicateAlias.js, 2, 25)) +>module.exports : Symbol(apply, Decl(moduleExportAliasDuplicateAlias.js, 0, 0), Decl(moduleExportAliasDuplicateAlias.js, 1, 16), Decl(moduleExportAliasDuplicateAlias.js, 2, 25)) +>module : Symbol(module, Decl(moduleExportAliasDuplicateAlias.js, 0, 0)) +>exports : Symbol(module.exports, Decl(moduleExportAliasDuplicateAlias.js, 0, 0)) +>apply : Symbol(apply, Decl(moduleExportAliasDuplicateAlias.js, 0, 0), Decl(moduleExportAliasDuplicateAlias.js, 1, 16), Decl(moduleExportAliasDuplicateAlias.js, 2, 25)) +>a : Symbol(a, Decl(moduleExportAliasDuplicateAlias.js, 0, 33)) + +module.exports.apply() +>module.exports.apply : Symbol(apply, Decl(moduleExportAliasDuplicateAlias.js, 0, 0), Decl(moduleExportAliasDuplicateAlias.js, 1, 16), Decl(moduleExportAliasDuplicateAlias.js, 2, 25)) +>module.exports : Symbol(module.exports, Decl(moduleExportAliasDuplicateAlias.js, 0, 0)) +>module : Symbol(module, Decl(moduleExportAliasDuplicateAlias.js, 0, 0)) +>exports : Symbol(module.exports, Decl(moduleExportAliasDuplicateAlias.js, 0, 0)) +>apply : Symbol(apply, Decl(moduleExportAliasDuplicateAlias.js, 0, 0), Decl(moduleExportAliasDuplicateAlias.js, 1, 16), Decl(moduleExportAliasDuplicateAlias.js, 2, 25)) + diff --git a/tests/baselines/reference/moduleExportDuplicateAlias2.types b/tests/baselines/reference/moduleExportDuplicateAlias2.types new file mode 100644 index 00000000000..26d810b48b7 --- /dev/null +++ b/tests/baselines/reference/moduleExportDuplicateAlias2.types @@ -0,0 +1,50 @@ +=== tests/cases/conformance/salsa/test.js === +const { apply } = require('./moduleExportAliasDuplicateAlias') +>apply : () => void +>require('./moduleExportAliasDuplicateAlias') : typeof import("tests/cases/conformance/salsa/moduleExportAliasDuplicateAlias") +>require : any +>'./moduleExportAliasDuplicateAlias' : "./moduleExportAliasDuplicateAlias" + +apply() +>apply() : void +>apply : () => void + +=== tests/cases/conformance/salsa/moduleExportAliasDuplicateAlias.js === +module.exports.apply = undefined; +>module.exports.apply = undefined : undefined +>module.exports.apply : any +>module.exports : typeof module.exports +>module : { exports: typeof module.exports; } +>exports : typeof module.exports +>apply : any +>undefined : undefined + +function a() { } +>a : () => void + +module.exports.apply = a; +>module.exports.apply = a : () => void +>module.exports.apply : any +>module.exports : typeof module.exports +>module : { exports: typeof module.exports; } +>exports : typeof module.exports +>apply : any +>a : () => void + +module.exports.apply = a; +>module.exports.apply = a : () => void +>module.exports.apply : any +>module.exports : typeof module.exports +>module : { exports: typeof module.exports; } +>exports : typeof module.exports +>apply : any +>a : () => void + +module.exports.apply() +>module.exports.apply() : void +>module.exports.apply : () => void +>module.exports : typeof module.exports +>module : { exports: typeof module.exports; } +>exports : typeof module.exports +>apply : () => void + diff --git a/tests/baselines/reference/moduleExportDuplicateAlias3.js b/tests/baselines/reference/moduleExportDuplicateAlias3.js new file mode 100644 index 00000000000..666744dc4cd --- /dev/null +++ b/tests/baselines/reference/moduleExportDuplicateAlias3.js @@ -0,0 +1,39 @@ +//// [tests/cases/conformance/salsa/moduleExportDuplicateAlias3.ts] //// + +//// [moduleExportAliasDuplicateAlias.js] +exports.apply = undefined; +exports.apply = undefined; +function a() { } +exports.apply = a; +exports.apply() +exports.apply = 'ok' +var OK = exports.apply.toUpperCase() +exports.apply = 1 + +//// [test.js] +const { apply } = require('./moduleExportAliasDuplicateAlias') +const result = apply.toFixed() + + +//// [moduleExportAliasDuplicateAlias.js] +"use strict"; +exports.apply = undefined; +exports.apply = undefined; +function a() { } +exports.apply = a; +exports.apply(); +exports.apply = 'ok'; +var OK = exports.apply.toUpperCase(); +exports.apply = 1; +//// [test.js] +"use strict"; +var apply = require('./moduleExportAliasDuplicateAlias').apply; +var result = apply.toFixed(); + + +//// [moduleExportAliasDuplicateAlias.d.ts] +export var apply: string | number | typeof a | undefined; +export { a as apply }; +declare function a(): void; +//// [test.d.ts] +export {}; diff --git a/tests/baselines/reference/moduleExportDuplicateAlias3.symbols b/tests/baselines/reference/moduleExportDuplicateAlias3.symbols new file mode 100644 index 00000000000..8c8d2642287 --- /dev/null +++ b/tests/baselines/reference/moduleExportDuplicateAlias3.symbols @@ -0,0 +1,57 @@ +=== tests/cases/conformance/salsa/test.js === +const { apply } = require('./moduleExportAliasDuplicateAlias') +>apply : Symbol(apply, Decl(test.js, 0, 7)) +>require : Symbol(require) +>'./moduleExportAliasDuplicateAlias' : Symbol("tests/cases/conformance/salsa/moduleExportAliasDuplicateAlias", Decl(moduleExportAliasDuplicateAlias.js, 0, 0)) + +const result = apply.toFixed() +>result : Symbol(result, Decl(test.js, 1, 5)) +>apply.toFixed : Symbol(Number.toFixed, Decl(lib.es5.d.ts, --, --)) +>apply : Symbol(apply, Decl(test.js, 0, 7)) +>toFixed : Symbol(Number.toFixed, Decl(lib.es5.d.ts, --, --)) + +=== tests/cases/conformance/salsa/moduleExportAliasDuplicateAlias.js === +exports.apply = undefined; +>exports.apply : Symbol(apply, Decl(moduleExportAliasDuplicateAlias.js, 0, 0), Decl(moduleExportAliasDuplicateAlias.js, 0, 26), Decl(moduleExportAliasDuplicateAlias.js, 2, 16), Decl(moduleExportAliasDuplicateAlias.js, 4, 15), Decl(moduleExportAliasDuplicateAlias.js, 6, 36)) +>exports : Symbol(apply, Decl(moduleExportAliasDuplicateAlias.js, 0, 0), Decl(moduleExportAliasDuplicateAlias.js, 0, 26), Decl(moduleExportAliasDuplicateAlias.js, 2, 16), Decl(moduleExportAliasDuplicateAlias.js, 4, 15), Decl(moduleExportAliasDuplicateAlias.js, 6, 36)) +>apply : Symbol(apply, Decl(moduleExportAliasDuplicateAlias.js, 0, 0), Decl(moduleExportAliasDuplicateAlias.js, 0, 26), Decl(moduleExportAliasDuplicateAlias.js, 2, 16), Decl(moduleExportAliasDuplicateAlias.js, 4, 15), Decl(moduleExportAliasDuplicateAlias.js, 6, 36)) +>undefined : Symbol(undefined) + +exports.apply = undefined; +>exports.apply : Symbol(apply, Decl(moduleExportAliasDuplicateAlias.js, 0, 0), Decl(moduleExportAliasDuplicateAlias.js, 0, 26), Decl(moduleExportAliasDuplicateAlias.js, 2, 16), Decl(moduleExportAliasDuplicateAlias.js, 4, 15), Decl(moduleExportAliasDuplicateAlias.js, 6, 36)) +>exports : Symbol(apply, Decl(moduleExportAliasDuplicateAlias.js, 0, 0), Decl(moduleExportAliasDuplicateAlias.js, 0, 26), Decl(moduleExportAliasDuplicateAlias.js, 2, 16), Decl(moduleExportAliasDuplicateAlias.js, 4, 15), Decl(moduleExportAliasDuplicateAlias.js, 6, 36)) +>apply : Symbol(apply, Decl(moduleExportAliasDuplicateAlias.js, 0, 0), Decl(moduleExportAliasDuplicateAlias.js, 0, 26), Decl(moduleExportAliasDuplicateAlias.js, 2, 16), Decl(moduleExportAliasDuplicateAlias.js, 4, 15), Decl(moduleExportAliasDuplicateAlias.js, 6, 36)) +>undefined : Symbol(undefined) + +function a() { } +>a : Symbol(a, Decl(moduleExportAliasDuplicateAlias.js, 1, 26)) + +exports.apply = a; +>exports.apply : Symbol(apply, Decl(moduleExportAliasDuplicateAlias.js, 0, 0), Decl(moduleExportAliasDuplicateAlias.js, 0, 26), Decl(moduleExportAliasDuplicateAlias.js, 2, 16), Decl(moduleExportAliasDuplicateAlias.js, 4, 15), Decl(moduleExportAliasDuplicateAlias.js, 6, 36)) +>exports : Symbol(apply, Decl(moduleExportAliasDuplicateAlias.js, 0, 0), Decl(moduleExportAliasDuplicateAlias.js, 0, 26), Decl(moduleExportAliasDuplicateAlias.js, 2, 16), Decl(moduleExportAliasDuplicateAlias.js, 4, 15), Decl(moduleExportAliasDuplicateAlias.js, 6, 36)) +>apply : Symbol(apply, Decl(moduleExportAliasDuplicateAlias.js, 0, 0), Decl(moduleExportAliasDuplicateAlias.js, 0, 26), Decl(moduleExportAliasDuplicateAlias.js, 2, 16), Decl(moduleExportAliasDuplicateAlias.js, 4, 15), Decl(moduleExportAliasDuplicateAlias.js, 6, 36)) +>a : Symbol(a, Decl(moduleExportAliasDuplicateAlias.js, 1, 26)) + +exports.apply() +>exports.apply : Symbol(apply, Decl(moduleExportAliasDuplicateAlias.js, 0, 0), Decl(moduleExportAliasDuplicateAlias.js, 0, 26), Decl(moduleExportAliasDuplicateAlias.js, 2, 16), Decl(moduleExportAliasDuplicateAlias.js, 4, 15), Decl(moduleExportAliasDuplicateAlias.js, 6, 36)) +>exports : Symbol("tests/cases/conformance/salsa/moduleExportAliasDuplicateAlias", Decl(moduleExportAliasDuplicateAlias.js, 0, 0)) +>apply : Symbol(apply, Decl(moduleExportAliasDuplicateAlias.js, 0, 0), Decl(moduleExportAliasDuplicateAlias.js, 0, 26), Decl(moduleExportAliasDuplicateAlias.js, 2, 16), Decl(moduleExportAliasDuplicateAlias.js, 4, 15), Decl(moduleExportAliasDuplicateAlias.js, 6, 36)) + +exports.apply = 'ok' +>exports.apply : Symbol(apply, Decl(moduleExportAliasDuplicateAlias.js, 0, 0), Decl(moduleExportAliasDuplicateAlias.js, 0, 26), Decl(moduleExportAliasDuplicateAlias.js, 2, 16), Decl(moduleExportAliasDuplicateAlias.js, 4, 15), Decl(moduleExportAliasDuplicateAlias.js, 6, 36)) +>exports : Symbol(apply, Decl(moduleExportAliasDuplicateAlias.js, 0, 0), Decl(moduleExportAliasDuplicateAlias.js, 0, 26), Decl(moduleExportAliasDuplicateAlias.js, 2, 16), Decl(moduleExportAliasDuplicateAlias.js, 4, 15), Decl(moduleExportAliasDuplicateAlias.js, 6, 36)) +>apply : Symbol(apply, Decl(moduleExportAliasDuplicateAlias.js, 0, 0), Decl(moduleExportAliasDuplicateAlias.js, 0, 26), Decl(moduleExportAliasDuplicateAlias.js, 2, 16), Decl(moduleExportAliasDuplicateAlias.js, 4, 15), Decl(moduleExportAliasDuplicateAlias.js, 6, 36)) + +var OK = exports.apply.toUpperCase() +>OK : Symbol(OK, Decl(moduleExportAliasDuplicateAlias.js, 6, 3)) +>exports.apply.toUpperCase : Symbol(String.toUpperCase, Decl(lib.es5.d.ts, --, --)) +>exports.apply : Symbol(apply, Decl(moduleExportAliasDuplicateAlias.js, 0, 0), Decl(moduleExportAliasDuplicateAlias.js, 0, 26), Decl(moduleExportAliasDuplicateAlias.js, 2, 16), Decl(moduleExportAliasDuplicateAlias.js, 4, 15), Decl(moduleExportAliasDuplicateAlias.js, 6, 36)) +>exports : Symbol("tests/cases/conformance/salsa/moduleExportAliasDuplicateAlias", Decl(moduleExportAliasDuplicateAlias.js, 0, 0)) +>apply : Symbol(apply, Decl(moduleExportAliasDuplicateAlias.js, 0, 0), Decl(moduleExportAliasDuplicateAlias.js, 0, 26), Decl(moduleExportAliasDuplicateAlias.js, 2, 16), Decl(moduleExportAliasDuplicateAlias.js, 4, 15), Decl(moduleExportAliasDuplicateAlias.js, 6, 36)) +>toUpperCase : Symbol(String.toUpperCase, Decl(lib.es5.d.ts, --, --)) + +exports.apply = 1 +>exports.apply : Symbol(apply, Decl(moduleExportAliasDuplicateAlias.js, 0, 0), Decl(moduleExportAliasDuplicateAlias.js, 0, 26), Decl(moduleExportAliasDuplicateAlias.js, 2, 16), Decl(moduleExportAliasDuplicateAlias.js, 4, 15), Decl(moduleExportAliasDuplicateAlias.js, 6, 36)) +>exports : Symbol(apply, Decl(moduleExportAliasDuplicateAlias.js, 0, 0), Decl(moduleExportAliasDuplicateAlias.js, 0, 26), Decl(moduleExportAliasDuplicateAlias.js, 2, 16), Decl(moduleExportAliasDuplicateAlias.js, 4, 15), Decl(moduleExportAliasDuplicateAlias.js, 6, 36)) +>apply : Symbol(apply, Decl(moduleExportAliasDuplicateAlias.js, 0, 0), Decl(moduleExportAliasDuplicateAlias.js, 0, 26), Decl(moduleExportAliasDuplicateAlias.js, 2, 16), Decl(moduleExportAliasDuplicateAlias.js, 4, 15), Decl(moduleExportAliasDuplicateAlias.js, 6, 36)) + diff --git a/tests/baselines/reference/moduleExportDuplicateAlias3.types b/tests/baselines/reference/moduleExportDuplicateAlias3.types new file mode 100644 index 00000000000..e0c71bdfd46 --- /dev/null +++ b/tests/baselines/reference/moduleExportDuplicateAlias3.types @@ -0,0 +1,68 @@ +=== tests/cases/conformance/salsa/test.js === +const { apply } = require('./moduleExportAliasDuplicateAlias') +>apply : number +>require('./moduleExportAliasDuplicateAlias') : typeof import("tests/cases/conformance/salsa/moduleExportAliasDuplicateAlias") +>require : any +>'./moduleExportAliasDuplicateAlias' : "./moduleExportAliasDuplicateAlias" + +const result = apply.toFixed() +>result : string +>apply.toFixed() : string +>apply.toFixed : (fractionDigits?: number | undefined) => string +>apply : number +>toFixed : (fractionDigits?: number | undefined) => string + +=== tests/cases/conformance/salsa/moduleExportAliasDuplicateAlias.js === +exports.apply = undefined; +>exports.apply = undefined : undefined +>exports.apply : string | number | (() => void) | undefined +>exports : typeof import("tests/cases/conformance/salsa/moduleExportAliasDuplicateAlias") +>apply : string | number | (() => void) | undefined +>undefined : undefined + +exports.apply = undefined; +>exports.apply = undefined : undefined +>exports.apply : string | number | (() => void) | undefined +>exports : typeof import("tests/cases/conformance/salsa/moduleExportAliasDuplicateAlias") +>apply : string | number | (() => void) | undefined +>undefined : undefined + +function a() { } +>a : () => void + +exports.apply = a; +>exports.apply = a : () => void +>exports.apply : string | number | (() => void) | undefined +>exports : typeof import("tests/cases/conformance/salsa/moduleExportAliasDuplicateAlias") +>apply : string | number | (() => void) | undefined +>a : () => void + +exports.apply() +>exports.apply() : void +>exports.apply : () => void +>exports : typeof import("tests/cases/conformance/salsa/moduleExportAliasDuplicateAlias") +>apply : () => void + +exports.apply = 'ok' +>exports.apply = 'ok' : "ok" +>exports.apply : string | number | (() => void) | undefined +>exports : typeof import("tests/cases/conformance/salsa/moduleExportAliasDuplicateAlias") +>apply : string | number | (() => void) | undefined +>'ok' : "ok" + +var OK = exports.apply.toUpperCase() +>OK : string +>exports.apply.toUpperCase() : string +>exports.apply.toUpperCase : () => string +>exports.apply : string +>exports : typeof import("tests/cases/conformance/salsa/moduleExportAliasDuplicateAlias") +>apply : string +>toUpperCase : () => string + +exports.apply = 1 +>exports.apply = 1 : 1 +>exports.apply : string | number | (() => void) | undefined +>exports : typeof import("tests/cases/conformance/salsa/moduleExportAliasDuplicateAlias") +>apply : string | number | (() => void) | undefined +>1 : 1 + diff --git a/tests/cases/conformance/salsa/moduleExportDuplicateAlias.ts b/tests/cases/conformance/salsa/moduleExportDuplicateAlias.ts index 32e1a8a1ac7..b46f0e2445c 100644 --- a/tests/cases/conformance/salsa/moduleExportDuplicateAlias.ts +++ b/tests/cases/conformance/salsa/moduleExportDuplicateAlias.ts @@ -1,7 +1,14 @@ // @checkJs: true +// @strict: true // @declaration: true -// @filename: moduleExportAliasDuplicateAlias.js // @outdir: out +// @filename: moduleExportAliasDuplicateAlias.js exports.apply = undefined; function a() { } +exports.apply() exports.apply = a; +exports.apply() + +// @filename: test.js +const { apply } = require('./moduleExportAliasDuplicateAlias') +apply() diff --git a/tests/cases/conformance/salsa/moduleExportDuplicateAlias2.ts b/tests/cases/conformance/salsa/moduleExportDuplicateAlias2.ts new file mode 100644 index 00000000000..27f724d97be --- /dev/null +++ b/tests/cases/conformance/salsa/moduleExportDuplicateAlias2.ts @@ -0,0 +1,14 @@ +// @checkJs: true +// @strict: true +// @declaration: true +// @outdir: out +// @filename: moduleExportAliasDuplicateAlias.js +module.exports.apply = undefined; +function a() { } +module.exports.apply = a; +module.exports.apply = a; +module.exports.apply() + +// @filename: test.js +const { apply } = require('./moduleExportAliasDuplicateAlias') +apply() diff --git a/tests/cases/conformance/salsa/moduleExportDuplicateAlias3.ts b/tests/cases/conformance/salsa/moduleExportDuplicateAlias3.ts new file mode 100644 index 00000000000..7f78af66e31 --- /dev/null +++ b/tests/cases/conformance/salsa/moduleExportDuplicateAlias3.ts @@ -0,0 +1,17 @@ +// @checkJs: true +// @strict: true +// @declaration: true +// @filename: moduleExportAliasDuplicateAlias.js +// @outdir: out +exports.apply = undefined; +exports.apply = undefined; +function a() { } +exports.apply = a; +exports.apply() +exports.apply = 'ok' +var OK = exports.apply.toUpperCase() +exports.apply = 1 + +// @filename: test.js +const { apply } = require('./moduleExportAliasDuplicateAlias') +const result = apply.toFixed()