mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-15 04:43:37 -05:00
Merge pull request #30970 from Microsoft/incrementalLateSymbol
When adding resolvedMembers ensure lateBoundSymbol is added whether it was previously checked or not
This commit is contained in:
@@ -6714,11 +6714,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);
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -285,8 +285,10 @@ Mismatch Actual(path, actual, expected): ${JSON.stringify(arrayFrom(mapDefinedIt
|
||||
let newFs: vfs.FileSystem;
|
||||
let actualReadFileMap: Map<number>;
|
||||
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,13 +300,17 @@ 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!;
|
||||
});
|
||||
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));
|
||||
|
||||
47
src/testRunner/unittests/tsbuild/lateBoundSymbol.ts
Normal file
47
src/testRunner/unittests/tsbuild/lateBoundSymbol.ts
Normal file
@@ -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
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
//// [/src/src/main.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var sym = Symbol();
|
||||
|
||||
|
||||
//// [/src/src/main.ts]
|
||||
import { HKT } from "./hkt";
|
||||
|
||||
const sym = Symbol();
|
||||
|
||||
declare module "./hkt" {
|
||||
interface HKT<T> {
|
||||
[sym]: { a: T }
|
||||
}
|
||||
}
|
||||
|
||||
type A = HKT<number>[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"
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
//// [uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.ts]
|
||||
const FOO_SYMBOL = Symbol('Foo');
|
||||
|
||||
declare global {
|
||||
interface Promise<T> {
|
||||
[FOO_SYMBOL]?: number;
|
||||
}
|
||||
}
|
||||
|
||||
export function foo<T>(p: Promise<T>) {
|
||||
p[FOO_SYMBOL] = 3;
|
||||
}
|
||||
|
||||
//// [uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.js]
|
||||
const FOO_SYMBOL = Symbol('Foo');
|
||||
export function foo(p) {
|
||||
p[FOO_SYMBOL] = 3;
|
||||
}
|
||||
@@ -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<T> {
|
||||
>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<T>(p: Promise<T>) {
|
||||
>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))
|
||||
}
|
||||
@@ -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<T> {
|
||||
[FOO_SYMBOL]?: number;
|
||||
>[FOO_SYMBOL] : number | undefined
|
||||
>FOO_SYMBOL : unique symbol
|
||||
}
|
||||
}
|
||||
|
||||
export function foo<T>(p: Promise<T>) {
|
||||
>foo : <T>(p: Promise<T>) => void
|
||||
>p : Promise<T>
|
||||
|
||||
p[FOO_SYMBOL] = 3;
|
||||
>p[FOO_SYMBOL] = 3 : 3
|
||||
>p[FOO_SYMBOL] : number | undefined
|
||||
>p : Promise<T>
|
||||
>FOO_SYMBOL : unique symbol
|
||||
>3 : 3
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
// @strict: true
|
||||
// @target: es6
|
||||
const FOO_SYMBOL = Symbol('Foo');
|
||||
|
||||
declare global {
|
||||
interface Promise<T> {
|
||||
[FOO_SYMBOL]?: number;
|
||||
}
|
||||
}
|
||||
|
||||
export function foo<T>(p: Promise<T>) {
|
||||
p[FOO_SYMBOL] = 3;
|
||||
}
|
||||
1
tests/projects/lateBoundSymbol/src/hkt.ts
Normal file
1
tests/projects/lateBoundSymbol/src/hkt.ts
Normal file
@@ -0,0 +1 @@
|
||||
export interface HKT<T> { }
|
||||
11
tests/projects/lateBoundSymbol/src/main.ts
Normal file
11
tests/projects/lateBoundSymbol/src/main.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { HKT } from "./hkt";
|
||||
|
||||
const sym = Symbol();
|
||||
|
||||
declare module "./hkt" {
|
||||
interface HKT<T> {
|
||||
[sym]: { a: T }
|
||||
}
|
||||
}
|
||||
const x = 10;
|
||||
type A = HKT<number>[typeof sym];
|
||||
9
tests/projects/lateBoundSymbol/tsconfig.json
Normal file
9
tests/projects/lateBoundSymbol/tsconfig.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"rootDir": "src",
|
||||
"lib": [
|
||||
"es2015"
|
||||
],
|
||||
"incremental": true
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user