From c663645c91d71b67be6337cd3d6d65c0b7d0420b Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 1 May 2018 17:24:30 -0700 Subject: [PATCH] Inform getDeclarationSpaces about how an imported exportAssignment may merge (#23816) --- src/compiler/checker.ts | 10 +++++++- ...ortAssignmentImportMergeNoCrash.errors.txt | 24 +++++++++++++++++++ .../exportAssignmentImportMergeNoCrash.js | 24 +++++++++++++++++++ ...exportAssignmentImportMergeNoCrash.symbols | 15 ++++++++++++ .../exportAssignmentImportMergeNoCrash.types | 19 +++++++++++++++ .../exportAssignmentImportMergeNoCrash.ts | 9 +++++++ 6 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/exportAssignmentImportMergeNoCrash.errors.txt create mode 100644 tests/baselines/reference/exportAssignmentImportMergeNoCrash.js create mode 100644 tests/baselines/reference/exportAssignmentImportMergeNoCrash.symbols create mode 100644 tests/baselines/reference/exportAssignmentImportMergeNoCrash.types create mode 100644 tests/cases/compiler/exportAssignmentImportMergeNoCrash.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index dfb1a4c8c4e..e8b31f7c9a4 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -21611,7 +21611,8 @@ namespace ts { ExportType = 1 << 1, ExportNamespace = 1 << 2, } - function getDeclarationSpaces(d: Declaration): DeclarationSpaces { + function getDeclarationSpaces(decl: Declaration): DeclarationSpaces { + let d = decl as Node; switch (d.kind) { case SyntaxKind.InterfaceDeclaration: case SyntaxKind.TypeAliasDeclaration: @@ -21627,6 +21628,13 @@ namespace ts { return DeclarationSpaces.ExportType | DeclarationSpaces.ExportValue; case SyntaxKind.SourceFile: return DeclarationSpaces.ExportType | DeclarationSpaces.ExportValue | DeclarationSpaces.ExportNamespace; + case SyntaxKind.ExportAssignment: + // Export assigned entity name expressions act as aliases and should fall through, otherwise they export values + if (!isEntityNameExpression((d as ExportAssignment).expression)) { + return DeclarationSpaces.ExportValue; + } + d = (d as ExportAssignment).expression; + /* falls through */ // The below options all declare an Alias, which is allowed to merge with other values within the importing module case SyntaxKind.ImportEqualsDeclaration: case SyntaxKind.NamespaceImport: diff --git a/tests/baselines/reference/exportAssignmentImportMergeNoCrash.errors.txt b/tests/baselines/reference/exportAssignmentImportMergeNoCrash.errors.txt new file mode 100644 index 00000000000..12a7586a848 --- /dev/null +++ b/tests/baselines/reference/exportAssignmentImportMergeNoCrash.errors.txt @@ -0,0 +1,24 @@ +tests/cases/compiler/user.ts(1,8): error TS2395: Individual declarations in merged declaration 'Obj' must be all exported or all local. +tests/cases/compiler/user.ts(1,8): error TS2440: Import declaration conflicts with local declaration of 'Obj'. +tests/cases/compiler/user.ts(3,14): error TS2395: Individual declarations in merged declaration 'Obj' must be all exported or all local. +tests/cases/compiler/user.ts(3,25): error TS2448: Block-scoped variable 'Obj' used before its declaration. + + +==== tests/cases/compiler/assignment.ts (0 errors) ==== + export default { + foo: 12 + }; + +==== tests/cases/compiler/user.ts (4 errors) ==== + import Obj from "./assignment"; + ~~~ +!!! error TS2395: Individual declarations in merged declaration 'Obj' must be all exported or all local. + ~~~ +!!! error TS2440: Import declaration conflicts with local declaration of 'Obj'. + + export const Obj = void Obj; + ~~~ +!!! error TS2395: Individual declarations in merged declaration 'Obj' must be all exported or all local. + ~~~ +!!! error TS2448: Block-scoped variable 'Obj' used before its declaration. + \ No newline at end of file diff --git a/tests/baselines/reference/exportAssignmentImportMergeNoCrash.js b/tests/baselines/reference/exportAssignmentImportMergeNoCrash.js new file mode 100644 index 00000000000..a2e0d49d015 --- /dev/null +++ b/tests/baselines/reference/exportAssignmentImportMergeNoCrash.js @@ -0,0 +1,24 @@ +//// [tests/cases/compiler/exportAssignmentImportMergeNoCrash.ts] //// + +//// [assignment.ts] +export default { + foo: 12 +}; + +//// [user.ts] +import Obj from "./assignment"; + +export const Obj = void Obj; + + +//// [assignment.js] +"use strict"; +exports.__esModule = true; +exports["default"] = { + foo: 12 +}; +//// [user.js] +"use strict"; +exports.__esModule = true; +var assignment_1 = require("./assignment"); +exports.Obj = void exports.Obj; diff --git a/tests/baselines/reference/exportAssignmentImportMergeNoCrash.symbols b/tests/baselines/reference/exportAssignmentImportMergeNoCrash.symbols new file mode 100644 index 00000000000..58e80b315d3 --- /dev/null +++ b/tests/baselines/reference/exportAssignmentImportMergeNoCrash.symbols @@ -0,0 +1,15 @@ +=== tests/cases/compiler/assignment.ts === +export default { + foo: 12 +>foo : Symbol(foo, Decl(assignment.ts, 0, 16)) + +}; + +=== tests/cases/compiler/user.ts === +import Obj from "./assignment"; +>Obj : Symbol(Obj, Decl(user.ts, 0, 6), Decl(user.ts, 2, 12)) + +export const Obj = void Obj; +>Obj : Symbol(Obj, Decl(user.ts, 2, 12)) +>Obj : Symbol(Obj, Decl(user.ts, 0, 6), Decl(user.ts, 2, 12)) + diff --git a/tests/baselines/reference/exportAssignmentImportMergeNoCrash.types b/tests/baselines/reference/exportAssignmentImportMergeNoCrash.types new file mode 100644 index 00000000000..49165313420 --- /dev/null +++ b/tests/baselines/reference/exportAssignmentImportMergeNoCrash.types @@ -0,0 +1,19 @@ +=== tests/cases/compiler/assignment.ts === +export default { +>{ foo: 12} : { foo: number; } + + foo: 12 +>foo : number +>12 : 12 + +}; + +=== tests/cases/compiler/user.ts === +import Obj from "./assignment"; +>Obj : { foo: number; } + +export const Obj = void Obj; +>Obj : any +>void Obj : undefined +>Obj : any + diff --git a/tests/cases/compiler/exportAssignmentImportMergeNoCrash.ts b/tests/cases/compiler/exportAssignmentImportMergeNoCrash.ts new file mode 100644 index 00000000000..0ce4792ca9d --- /dev/null +++ b/tests/cases/compiler/exportAssignmentImportMergeNoCrash.ts @@ -0,0 +1,9 @@ +// @filename: assignment.ts +export default { + foo: 12 +}; + +// @filename: user.ts +import Obj from "./assignment"; + +export const Obj = void Obj;