From 9f5090cec7e1b27f0a030312b1d25d34daae7047 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 16 Apr 2019 12:22:42 -0700 Subject: [PATCH 1/4] Test case for #30891 --- src/testRunner/tsconfig.json | 1 + src/testRunner/unittests/tsbuild/helpers.ts | 12 +- .../unittests/tsbuild/lateBoundSymbol.ts | 47 ++++++++ ...s-merged-and-contains-late-bound-member.js | 13 +++ ...s-merged-and-contains-late-bound-member.js | 106 ++++++++++++++++++ tests/projects/lateBoundSymbol/src/hkt.ts | 1 + tests/projects/lateBoundSymbol/src/main.ts | 11 ++ tests/projects/lateBoundSymbol/tsconfig.json | 9 ++ 8 files changed, 197 insertions(+), 3 deletions(-) create mode 100644 src/testRunner/unittests/tsbuild/lateBoundSymbol.ts create mode 100644 tests/baselines/reference/tsbuild/lateBoundSymbol/incremental-declaration-doesnt-change/interface-is-merged-and-contains-late-bound-member.js create mode 100644 tests/baselines/reference/tsbuild/lateBoundSymbol/initial-Build/interface-is-merged-and-contains-late-bound-member.js create mode 100644 tests/projects/lateBoundSymbol/src/hkt.ts create mode 100644 tests/projects/lateBoundSymbol/src/main.ts create mode 100644 tests/projects/lateBoundSymbol/tsconfig.json diff --git a/src/testRunner/tsconfig.json b/src/testRunner/tsconfig.json index d3ea4744e8a..6b73324e2f7 100644 --- a/src/testRunner/tsconfig.json +++ b/src/testRunner/tsconfig.json @@ -92,6 +92,7 @@ "unittests/tsbuild/amdModulesWithOut.ts", "unittests/tsbuild/emptyFiles.ts", "unittests/tsbuild/graphOrdering.ts", + "unittests/tsbuild/lateBoundSymbol.ts", "unittests/tsbuild/missingExtendedFile.ts", "unittests/tsbuild/outFile.ts", "unittests/tsbuild/referencesWithRootDirInParent.ts", diff --git a/src/testRunner/unittests/tsbuild/helpers.ts b/src/testRunner/unittests/tsbuild/helpers.ts index 6915dd5d3b7..589ba7a3021 100644 --- a/src/testRunner/unittests/tsbuild/helpers.ts +++ b/src/testRunner/unittests/tsbuild/helpers.ts @@ -285,8 +285,10 @@ Mismatch Actual(path, actual, expected): ${JSON.stringify(arrayFrom(mapDefinedIt let newFs: vfs.FileSystem; let actualReadFileMap: Map; let host: fakes.SolutionBuilderHost; + let beforeBuildTime: number; + let afterBuildTime: number; before(() => { - assert.equal(fs.statSync(lastProjectOutputJs).mtimeMs, firstBuildTime, "First build timestamp is correct"); + beforeBuildTime = fs.statSync(lastProjectOutputJs).mtimeMs; tick(); newFs = fs.shadow(); tick(); @@ -298,14 +300,18 @@ Mismatch Actual(path, actual, expected): ${JSON.stringify(arrayFrom(mapDefinedIt expectedBuildInfoFilesForSectionBaselines, modifyFs: incrementalModifyFs, })); - assert.equal(newFs.statSync(lastProjectOutputJs).mtimeMs, time(), "Second build timestamp is correct"); + afterBuildTime = newFs.statSync(lastProjectOutputJs).mtimeMs; }); after(() => { newFs = undefined!; actualReadFileMap = undefined!; host = undefined!; }); - if (!baselineOnly) { + it("verify build output times", () => { + assert.equal(beforeBuildTime, firstBuildTime, "First build timestamp is correct"); + assert.equal(afterBuildTime, time(), "Second build timestamp is correct"); + }); + if (!baselineOnly || verifyDiagnostics) { it(`verify diagnostics`, () => { host.assertDiagnosticMessages(...(incrementalExpectedDiagnostics || emptyArray)); }); diff --git a/src/testRunner/unittests/tsbuild/lateBoundSymbol.ts b/src/testRunner/unittests/tsbuild/lateBoundSymbol.ts new file mode 100644 index 00000000000..ff9f1fc7c7a --- /dev/null +++ b/src/testRunner/unittests/tsbuild/lateBoundSymbol.ts @@ -0,0 +1,47 @@ +namespace ts { + describe("unittests:: tsbuild:: lateBoundSymbol:: interface is merged and contains late bound member", () => { + let projFs: vfs.FileSystem; + const { time, tick } = getTime(); + before(() => { + projFs = loadProjectFromDisk("tests/projects/lateBoundSymbol", time); + }); + after(() => { + projFs = undefined!; // Release the contents + }); + + verifyTsbuildOutput({ + scenario: "interface is merged and contains late bound member", + projFs: () => projFs, + time, + tick, + proj: "lateBoundSymbol", + rootNames: ["/src/tsconfig.json"], + expectedMapFileNames: emptyArray, + lastProjectOutputJs: "/src/src/main.js", + outputFiles: [ + "/src/src/hkt.js", + "/src/src/main.js", + "/src/tsconfig.tsbuildinfo", + ], + initialBuild: { + modifyFs: noop, + expectedDiagnostics: [ + getExpectedDiagnosticForProjectsInBuild("src/tsconfig.json"), + [Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, "src/tsconfig.json", "src/src/hkt.js"], + [Diagnostics.Building_project_0, "/src/tsconfig.json"] + ] + }, + incrementalDtsUnchangedBuild: { + modifyFs: fs => replaceText(fs, "/src/src/main.ts", "const x = 10;", ""), + expectedDiagnostics: [ + getExpectedDiagnosticForProjectsInBuild("src/tsconfig.json"), + [Diagnostics.Project_0_is_out_of_date_because_oldest_output_1_is_older_than_newest_input_2, "src/tsconfig.json", "src/src/hkt.js", "src/src/main.ts"], + [Diagnostics.Building_project_0, "/src/tsconfig.json"], + [Diagnostics.Updating_unchanged_output_timestamps_of_project_0, "/src/tsconfig.json"] + ] + }, + baselineOnly: true, + verifyDiagnostics: true + }); + }); +} diff --git a/tests/baselines/reference/tsbuild/lateBoundSymbol/incremental-declaration-doesnt-change/interface-is-merged-and-contains-late-bound-member.js b/tests/baselines/reference/tsbuild/lateBoundSymbol/incremental-declaration-doesnt-change/interface-is-merged-and-contains-late-bound-member.js new file mode 100644 index 00000000000..3e5da585c7c --- /dev/null +++ b/tests/baselines/reference/tsbuild/lateBoundSymbol/incremental-declaration-doesnt-change/interface-is-merged-and-contains-late-bound-member.js @@ -0,0 +1,13 @@ +//// [/src/src/main.ts] +import { HKT } from "./hkt"; + +const sym = Symbol(); + +declare module "./hkt" { + interface HKT { + [sym]: { a: T } + } +} + +type A = HKT[typeof sym]; + diff --git a/tests/baselines/reference/tsbuild/lateBoundSymbol/initial-Build/interface-is-merged-and-contains-late-bound-member.js b/tests/baselines/reference/tsbuild/lateBoundSymbol/initial-Build/interface-is-merged-and-contains-late-bound-member.js new file mode 100644 index 00000000000..e30b62fcca8 --- /dev/null +++ b/tests/baselines/reference/tsbuild/lateBoundSymbol/initial-Build/interface-is-merged-and-contains-late-bound-member.js @@ -0,0 +1,106 @@ +//// [/src/src/hkt.js] +"use strict"; +exports.__esModule = true; + + +//// [/src/src/main.js] +"use strict"; +exports.__esModule = true; +var sym = Symbol(); +var x = 10; + + +//// [/src/tsconfig.tsbuildinfo] +{ + "program": { + "fileInfos": { + "/lib/lib.es5.d.ts": { + "version": "/lib/lib.es5.d.ts", + "signature": "/lib/lib.es5.d.ts" + }, + "/lib/lib.es2015.d.ts": { + "version": "/lib/lib.es2015.d.ts", + "signature": "/lib/lib.es2015.d.ts" + }, + "/lib/lib.es2015.core.d.ts": { + "version": "/lib/lib.es2015.core.d.ts", + "signature": "/lib/lib.es2015.core.d.ts" + }, + "/lib/lib.es2015.collection.d.ts": { + "version": "/lib/lib.es2015.collection.d.ts", + "signature": "/lib/lib.es2015.collection.d.ts" + }, + "/lib/lib.es2015.generator.d.ts": { + "version": "/lib/lib.es2015.generator.d.ts", + "signature": "/lib/lib.es2015.generator.d.ts" + }, + "/lib/lib.es2015.iterable.d.ts": { + "version": "/lib/lib.es2015.iterable.d.ts", + "signature": "/lib/lib.es2015.iterable.d.ts" + }, + "/lib/lib.es2015.promise.d.ts": { + "version": "/lib/lib.es2015.promise.d.ts", + "signature": "/lib/lib.es2015.promise.d.ts" + }, + "/lib/lib.es2015.proxy.d.ts": { + "version": "/lib/lib.es2015.proxy.d.ts", + "signature": "/lib/lib.es2015.proxy.d.ts" + }, + "/lib/lib.es2015.reflect.d.ts": { + "version": "/lib/lib.es2015.reflect.d.ts", + "signature": "/lib/lib.es2015.reflect.d.ts" + }, + "/lib/lib.es2015.symbol.d.ts": { + "version": "/lib/lib.es2015.symbol.d.ts", + "signature": "/lib/lib.es2015.symbol.d.ts" + }, + "/lib/lib.es2015.symbol.wellknown.d.ts": { + "version": "/lib/lib.es2015.symbol.wellknown.d.ts", + "signature": "/lib/lib.es2015.symbol.wellknown.d.ts" + }, + "/src/src/hkt.ts": { + "version": "675797797", + "signature": "2373810515" + }, + "/src/src/main.ts": { + "version": "-28387946490", + "signature": "-7779857705" + } + }, + "options": { + "rootDir": "/src/src", + "lib": [ + "lib.es2015.d.ts" + ], + "incremental": true, + "configFilePath": "/src/tsconfig.json" + }, + "referencedMap": { + "/src/src/main.ts": [ + "/src/src/hkt.ts" + ] + }, + "exportedModulesMap": { + "/src/src/main.ts": [ + "/src/src/hkt.ts" + ] + }, + "semanticDiagnosticsPerFile": [ + "/lib/lib.es2015.collection.d.ts", + "/lib/lib.es2015.core.d.ts", + "/lib/lib.es2015.d.ts", + "/lib/lib.es2015.generator.d.ts", + "/lib/lib.es2015.iterable.d.ts", + "/lib/lib.es2015.promise.d.ts", + "/lib/lib.es2015.proxy.d.ts", + "/lib/lib.es2015.reflect.d.ts", + "/lib/lib.es2015.symbol.d.ts", + "/lib/lib.es2015.symbol.wellknown.d.ts", + "/lib/lib.es5.d.ts", + "/src/src/hkt.ts", + "/src/src/main.ts" + ] + }, + "version": "FakeTSVersion" +} + diff --git a/tests/projects/lateBoundSymbol/src/hkt.ts b/tests/projects/lateBoundSymbol/src/hkt.ts new file mode 100644 index 00000000000..2b844a9ab79 --- /dev/null +++ b/tests/projects/lateBoundSymbol/src/hkt.ts @@ -0,0 +1 @@ +export interface HKT { } \ No newline at end of file diff --git a/tests/projects/lateBoundSymbol/src/main.ts b/tests/projects/lateBoundSymbol/src/main.ts new file mode 100644 index 00000000000..e5b5fcc6daa --- /dev/null +++ b/tests/projects/lateBoundSymbol/src/main.ts @@ -0,0 +1,11 @@ +import { HKT } from "./hkt"; + +const sym = Symbol(); + +declare module "./hkt" { + interface HKT { + [sym]: { a: T } + } +} +const x = 10; +type A = HKT[typeof sym]; \ No newline at end of file diff --git a/tests/projects/lateBoundSymbol/tsconfig.json b/tests/projects/lateBoundSymbol/tsconfig.json new file mode 100644 index 00000000000..78bf9e23f00 --- /dev/null +++ b/tests/projects/lateBoundSymbol/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "rootDir": "src", + "lib": [ + "es2015" + ], + "incremental": true + } +} \ No newline at end of file From 3c676087158a98efc365e0c434b80242716f40f7 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 16 Apr 2019 12:36:07 -0700 Subject: [PATCH 2/4] When interfaces are merged, always ensure that the parent symbol of the late bound member symbol is declared symbol containing the node. Ensure that resolvedMembers adds the late bound symbol even when its resolved sunce lateBoundMember may or may not be added to resolved members depending on when its checked Fixes #30891 --- src/compiler/checker.ts | 15 ++- ...s-merged-and-contains-late-bound-member.js | 100 ++++++++++++++++++ 2 files changed, 112 insertions(+), 3 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0cb40d8541a..5c2745ab3e7 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6607,12 +6607,11 @@ namespace ts { * unique symbol type which we can then use as the name of the member. This allows users * to define custom symbols that can be used in the members of an object type. * - * @param parent The containing symbol for the member. * @param earlySymbols The early-bound symbols of the parent. * @param lateSymbols The late-bound symbols of the parent. * @param decl The member to bind. */ - function lateBindMember(parent: Symbol, earlySymbols: SymbolTable | undefined, lateSymbols: SymbolTable, decl: LateBoundDeclaration) { + function lateBindMember(earlySymbols: SymbolTable | undefined, lateSymbols: SymbolTable, decl: LateBoundDeclaration) { Debug.assert(!!decl.symbol, "The member is expected to have a symbol."); const links = getNodeLinks(decl); if (!links.resolvedSymbol) { @@ -6643,6 +6642,7 @@ namespace ts { } lateSymbol.nameType = type; addDeclarationToLateBoundSymbol(lateSymbol, decl, symbolFlags); + const parent = getSymbolOfNode(decl.parent); if (lateSymbol.parent) { Debug.assert(lateSymbol.parent === parent, "Existing symbol parent should match new one"); } @@ -6652,6 +6652,15 @@ namespace ts { return links.resolvedSymbol = lateSymbol; } } + else { + const type = checkComputedPropertyName(decl.name); + if (isTypeUsableAsPropertyName(type)) { + const memberName = getPropertyNameFromType(type); + if (!lateSymbols.has(memberName)) { + lateSymbols.set(memberName, links.resolvedSymbol); + } + } + } return links.resolvedSymbol; } @@ -6675,7 +6684,7 @@ namespace ts { if (members) { for (const member of members) { if (isStatic === hasStaticModifier(member) && hasLateBindableName(member)) { - lateBindMember(symbol, earlySymbols, lateSymbols, member); + lateBindMember(earlySymbols, lateSymbols, member); } } } diff --git a/tests/baselines/reference/tsbuild/lateBoundSymbol/incremental-declaration-doesnt-change/interface-is-merged-and-contains-late-bound-member.js b/tests/baselines/reference/tsbuild/lateBoundSymbol/incremental-declaration-doesnt-change/interface-is-merged-and-contains-late-bound-member.js index 3e5da585c7c..89748694bbc 100644 --- a/tests/baselines/reference/tsbuild/lateBoundSymbol/incremental-declaration-doesnt-change/interface-is-merged-and-contains-late-bound-member.js +++ b/tests/baselines/reference/tsbuild/lateBoundSymbol/incremental-declaration-doesnt-change/interface-is-merged-and-contains-late-bound-member.js @@ -1,3 +1,9 @@ +//// [/src/src/main.js] +"use strict"; +exports.__esModule = true; +var sym = Symbol(); + + //// [/src/src/main.ts] import { HKT } from "./hkt"; @@ -11,3 +17,97 @@ declare module "./hkt" { type A = HKT[typeof sym]; +//// [/src/tsconfig.tsbuildinfo] +{ + "program": { + "fileInfos": { + "/lib/lib.es5.d.ts": { + "version": "/lib/lib.es5.d.ts", + "signature": "/lib/lib.es5.d.ts" + }, + "/lib/lib.es2015.d.ts": { + "version": "/lib/lib.es2015.d.ts", + "signature": "/lib/lib.es2015.d.ts" + }, + "/lib/lib.es2015.core.d.ts": { + "version": "/lib/lib.es2015.core.d.ts", + "signature": "/lib/lib.es2015.core.d.ts" + }, + "/lib/lib.es2015.collection.d.ts": { + "version": "/lib/lib.es2015.collection.d.ts", + "signature": "/lib/lib.es2015.collection.d.ts" + }, + "/lib/lib.es2015.generator.d.ts": { + "version": "/lib/lib.es2015.generator.d.ts", + "signature": "/lib/lib.es2015.generator.d.ts" + }, + "/lib/lib.es2015.iterable.d.ts": { + "version": "/lib/lib.es2015.iterable.d.ts", + "signature": "/lib/lib.es2015.iterable.d.ts" + }, + "/lib/lib.es2015.promise.d.ts": { + "version": "/lib/lib.es2015.promise.d.ts", + "signature": "/lib/lib.es2015.promise.d.ts" + }, + "/lib/lib.es2015.proxy.d.ts": { + "version": "/lib/lib.es2015.proxy.d.ts", + "signature": "/lib/lib.es2015.proxy.d.ts" + }, + "/lib/lib.es2015.reflect.d.ts": { + "version": "/lib/lib.es2015.reflect.d.ts", + "signature": "/lib/lib.es2015.reflect.d.ts" + }, + "/lib/lib.es2015.symbol.d.ts": { + "version": "/lib/lib.es2015.symbol.d.ts", + "signature": "/lib/lib.es2015.symbol.d.ts" + }, + "/lib/lib.es2015.symbol.wellknown.d.ts": { + "version": "/lib/lib.es2015.symbol.wellknown.d.ts", + "signature": "/lib/lib.es2015.symbol.wellknown.d.ts" + }, + "/src/src/hkt.ts": { + "version": "675797797", + "signature": "2373810515" + }, + "/src/src/main.ts": { + "version": "-27494779858", + "signature": "-7779857705" + } + }, + "options": { + "rootDir": "/src/src", + "lib": [ + "lib.es2015.d.ts" + ], + "incremental": true, + "configFilePath": "/src/tsconfig.json" + }, + "referencedMap": { + "/src/src/main.ts": [ + "/src/src/hkt.ts" + ] + }, + "exportedModulesMap": { + "/src/src/main.ts": [ + "/src/src/hkt.ts" + ] + }, + "semanticDiagnosticsPerFile": [ + "/lib/lib.es2015.collection.d.ts", + "/lib/lib.es2015.core.d.ts", + "/lib/lib.es2015.d.ts", + "/lib/lib.es2015.generator.d.ts", + "/lib/lib.es2015.iterable.d.ts", + "/lib/lib.es2015.promise.d.ts", + "/lib/lib.es2015.proxy.d.ts", + "/lib/lib.es2015.reflect.d.ts", + "/lib/lib.es2015.symbol.d.ts", + "/lib/lib.es2015.symbol.wellknown.d.ts", + "/lib/lib.es5.d.ts", + "/src/src/hkt.ts", + "/src/src/main.ts" + ] + }, + "version": "FakeTSVersion" +} + From 3af78ae77a2db85e6955b0a26216965737036317 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 16 Apr 2019 12:22:42 -0700 Subject: [PATCH 3/4] Revert and always use merged symbol to get members of late bound symbol Fixes #30891 --- src/compiler/checker.ts | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 5c2745ab3e7..b8ac6aeaf50 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6607,11 +6607,12 @@ namespace ts { * unique symbol type which we can then use as the name of the member. This allows users * to define custom symbols that can be used in the members of an object type. * + * @param parent The containing symbol for the member. * @param earlySymbols The early-bound symbols of the parent. * @param lateSymbols The late-bound symbols of the parent. * @param decl The member to bind. */ - function lateBindMember(earlySymbols: SymbolTable | undefined, lateSymbols: SymbolTable, decl: LateBoundDeclaration) { + function lateBindMember(parent: Symbol, earlySymbols: SymbolTable | undefined, lateSymbols: SymbolTable, decl: LateBoundDeclaration) { Debug.assert(!!decl.symbol, "The member is expected to have a symbol."); const links = getNodeLinks(decl); if (!links.resolvedSymbol) { @@ -6642,7 +6643,6 @@ namespace ts { } lateSymbol.nameType = type; addDeclarationToLateBoundSymbol(lateSymbol, decl, symbolFlags); - const parent = getSymbolOfNode(decl.parent); if (lateSymbol.parent) { Debug.assert(lateSymbol.parent === parent, "Existing symbol parent should match new one"); } @@ -6652,15 +6652,6 @@ namespace ts { return links.resolvedSymbol = lateSymbol; } } - else { - const type = checkComputedPropertyName(decl.name); - if (isTypeUsableAsPropertyName(type)) { - const memberName = getPropertyNameFromType(type); - if (!lateSymbols.has(memberName)) { - lateSymbols.set(memberName, links.resolvedSymbol); - } - } - } return links.resolvedSymbol; } @@ -6684,7 +6675,7 @@ namespace ts { if (members) { for (const member of members) { if (isStatic === hasStaticModifier(member) && hasLateBindableName(member)) { - lateBindMember(earlySymbols, lateSymbols, member); + lateBindMember(symbol, earlySymbols, lateSymbols, member); } } } @@ -6718,11 +6709,12 @@ namespace ts { const links = getSymbolLinks(symbol); if (!links.lateSymbol && some(symbol.declarations, hasLateBindableName)) { // force late binding of members/exports. This will set the late-bound symbol + const parent = getMergedSymbol(symbol.parent)!; if (some(symbol.declarations, hasStaticModifier)) { - getExportsOfSymbol(symbol.parent!); + getExportsOfSymbol(parent); } else { - getMembersOfSymbol(symbol.parent!); + getMembersOfSymbol(parent); } } return links.lateSymbol || (links.lateSymbol = symbol); From d919f2c113da9a18140577d1278508fe522ba0f7 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Wed, 17 Apr 2019 15:13:09 -0700 Subject: [PATCH 4/4] Add test for #28334 --- ...olAssignmentOnGlobalAugmentationSuceeds.js | 18 ++++++++++++ ...ignmentOnGlobalAugmentationSuceeds.symbols | 29 +++++++++++++++++++ ...ssignmentOnGlobalAugmentationSuceeds.types | 28 ++++++++++++++++++ ...olAssignmentOnGlobalAugmentationSuceeds.ts | 13 +++++++++ 4 files changed, 88 insertions(+) create mode 100644 tests/baselines/reference/uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.js create mode 100644 tests/baselines/reference/uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.symbols create mode 100644 tests/baselines/reference/uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.types create mode 100644 tests/cases/compiler/uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.ts diff --git a/tests/baselines/reference/uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.js b/tests/baselines/reference/uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.js new file mode 100644 index 00000000000..bfb6f0a29c7 --- /dev/null +++ b/tests/baselines/reference/uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.js @@ -0,0 +1,18 @@ +//// [uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.ts] +const FOO_SYMBOL = Symbol('Foo'); + +declare global { + interface Promise { + [FOO_SYMBOL]?: number; + } +} + +export function foo(p: Promise) { + p[FOO_SYMBOL] = 3; +} + +//// [uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.js] +const FOO_SYMBOL = Symbol('Foo'); +export function foo(p) { + p[FOO_SYMBOL] = 3; +} diff --git a/tests/baselines/reference/uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.symbols b/tests/baselines/reference/uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.symbols new file mode 100644 index 00000000000..17af30e8fac --- /dev/null +++ b/tests/baselines/reference/uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.symbols @@ -0,0 +1,29 @@ +=== tests/cases/compiler/uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.ts === +const FOO_SYMBOL = Symbol('Foo'); +>FOO_SYMBOL : Symbol(FOO_SYMBOL, Decl(uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.ts, 0, 5)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + +declare global { +>global : Symbol(global, Decl(uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.ts, 0, 33)) + + interface Promise { +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.ts, 2, 16)) +>T : Symbol(T, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.ts, 3, 22)) + + [FOO_SYMBOL]?: number; +>[FOO_SYMBOL] : Symbol(Promise[FOO_SYMBOL], Decl(uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.ts, 3, 26)) +>FOO_SYMBOL : Symbol(FOO_SYMBOL, Decl(uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.ts, 0, 5)) + } +} + +export function foo(p: Promise) { +>foo : Symbol(foo, Decl(uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.ts, 6, 1)) +>T : Symbol(T, Decl(uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.ts, 8, 20)) +>p : Symbol(p, Decl(uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.ts, 8, 23)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.ts, 2, 16)) +>T : Symbol(T, Decl(uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.ts, 8, 20)) + + p[FOO_SYMBOL] = 3; +>p : Symbol(p, Decl(uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.ts, 8, 23)) +>FOO_SYMBOL : Symbol(FOO_SYMBOL, Decl(uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.ts, 0, 5)) +} diff --git a/tests/baselines/reference/uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.types b/tests/baselines/reference/uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.types new file mode 100644 index 00000000000..62dcc0607ae --- /dev/null +++ b/tests/baselines/reference/uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.types @@ -0,0 +1,28 @@ +=== tests/cases/compiler/uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.ts === +const FOO_SYMBOL = Symbol('Foo'); +>FOO_SYMBOL : unique symbol +>Symbol('Foo') : unique symbol +>Symbol : SymbolConstructor +>'Foo' : "Foo" + +declare global { +>global : any + + interface Promise { + [FOO_SYMBOL]?: number; +>[FOO_SYMBOL] : number | undefined +>FOO_SYMBOL : unique symbol + } +} + +export function foo(p: Promise) { +>foo : (p: Promise) => void +>p : Promise + + p[FOO_SYMBOL] = 3; +>p[FOO_SYMBOL] = 3 : 3 +>p[FOO_SYMBOL] : number | undefined +>p : Promise +>FOO_SYMBOL : unique symbol +>3 : 3 +} diff --git a/tests/cases/compiler/uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.ts b/tests/cases/compiler/uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.ts new file mode 100644 index 00000000000..f79c2a36e86 --- /dev/null +++ b/tests/cases/compiler/uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.ts @@ -0,0 +1,13 @@ +// @strict: true +// @target: es6 +const FOO_SYMBOL = Symbol('Foo'); + +declare global { + interface Promise { + [FOO_SYMBOL]?: number; + } +} + +export function foo(p: Promise) { + p[FOO_SYMBOL] = 3; +} \ No newline at end of file