Skip to content

Commit b45cf0d

Browse files
authored
disentangle the meaning of SymbolLinks.target (#47098)
1 parent f4b99ea commit b45cf0d

File tree

6 files changed

+331
-13
lines changed

6 files changed

+331
-13
lines changed

src/compiler/checker.ts

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3116,27 +3116,27 @@ namespace ts {
31163116
function resolveAlias(symbol: Symbol): Symbol {
31173117
Debug.assert((symbol.flags & SymbolFlags.Alias) !== 0, "Should only get Alias here.");
31183118
const links = getSymbolLinks(symbol);
3119-
if (!links.target) {
3120-
links.target = resolvingSymbol;
3119+
if (!links.aliasTarget) {
3120+
links.aliasTarget = resolvingSymbol;
31213121
const node = getDeclarationOfAliasSymbol(symbol);
31223122
if (!node) return Debug.fail();
31233123
const target = getTargetOfAliasDeclaration(node);
3124-
if (links.target === resolvingSymbol) {
3125-
links.target = target || unknownSymbol;
3124+
if (links.aliasTarget === resolvingSymbol) {
3125+
links.aliasTarget = target || unknownSymbol;
31263126
}
31273127
else {
31283128
error(node, Diagnostics.Circular_definition_of_import_alias_0, symbolToString(symbol));
31293129
}
31303130
}
3131-
else if (links.target === resolvingSymbol) {
3132-
links.target = unknownSymbol;
3131+
else if (links.aliasTarget === resolvingSymbol) {
3132+
links.aliasTarget = unknownSymbol;
31333133
}
3134-
return links.target;
3134+
return links.aliasTarget;
31353135
}
31363136

31373137
function tryResolveAlias(symbol: Symbol): Symbol | undefined {
31383138
const links = getSymbolLinks(symbol);
3139-
if (links.target !== resolvingSymbol) {
3139+
if (links.aliasTarget !== resolvingSymbol) {
31403140
return resolveAlias(symbol);
31413141
}
31423142

@@ -31748,7 +31748,7 @@ namespace ts {
3174831748
const newSymbol = createSymbol(SymbolFlags.Alias, InternalSymbolName.Default);
3174931749
newSymbol.parent = originalSymbol;
3175031750
newSymbol.nameType = getStringLiteralType("default");
31751-
newSymbol.target = resolveSymbol(symbol);
31751+
newSymbol.aliasTarget = resolveSymbol(symbol);
3175231752
memberTable.set(InternalSymbolName.Default, newSymbol);
3175331753
return createAnonymousType(anonymousSymbol, memberTable, emptyArray, emptyArray, emptyArray);
3175431754
}
@@ -42271,11 +42271,11 @@ namespace ts {
4227142271
const { leftSpread, rightSpread, syntheticOrigin } = symbol as TransientSymbol;
4227242272
return leftSpread ? [leftSpread, rightSpread!]
4227342273
: syntheticOrigin ? [syntheticOrigin]
42274-
: singleElementArray(tryGetAliasTarget(symbol));
42274+
: singleElementArray(tryGetTarget(symbol));
4227542275
}
4227642276
return undefined;
4227742277
}
42278-
function tryGetAliasTarget(symbol: Symbol): Symbol | undefined {
42278+
function tryGetTarget(symbol: Symbol): Symbol | undefined {
4227942279
let target: Symbol | undefined;
4228042280
let next: Symbol | undefined = symbol;
4228142281
while (next = getSymbolLinks(next).target) {
@@ -42527,7 +42527,7 @@ namespace ts {
4252742527
if (links?.referenced) {
4252842528
return true;
4252942529
}
42530-
const target = getSymbolLinks(symbol!).target; // TODO: GH#18217
42530+
const target = getSymbolLinks(symbol!).aliasTarget; // TODO: GH#18217
4253142531
if (target && getEffectiveModifierFlags(node) & ModifierFlags.Export &&
4253242532
target.flags & SymbolFlags.Value &&
4253342533
(shouldPreserveConstEnums(compilerOptions) || !isConstEnumOrConstEnumOnlyModule(target))) {

src/compiler/types.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4943,7 +4943,8 @@ namespace ts {
49434943
/* @internal */
49444944
export interface SymbolLinks {
49454945
immediateTarget?: Symbol; // Immediate target of an alias. May be another alias. Do not access directly, use `checker.getImmediateAliasedSymbol` instead.
4946-
target?: Symbol; // Resolved (non-alias) target of an alias
4946+
aliasTarget?: Symbol, // Resolved (non-alias) target of an alias
4947+
target?: Symbol; // Original version of an instantiated symbol
49474948
type?: Type; // Type of value symbol
49484949
writeType?: Type; // Type of value symbol in write contexts
49494950
nameType?: Type; // Type associated with a late-bound symbol
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
//// [tests/cases/compiler/spreadExpressionContextualTypeWithNamespace.ts] ////
2+
3+
//// [spreadExpressionContextualTypeWithNamespace_0.ts]
4+
// Repro from #44179 with some modification
5+
6+
function func() {}
7+
class klass {}
8+
const obj = { x: true };
9+
10+
export { func, klass, obj };
11+
12+
export function exportedDirectly() {}
13+
14+
//// [spreadExpressionContextualTypeWithNamespace_1.ts]
15+
import * as stuff from "./spreadExpressionContextualTypeWithNamespace_0";
16+
17+
stuff.func;
18+
stuff.klass;
19+
stuff.obj;
20+
stuff.exportedDirectly;
21+
22+
function getStuff<T>() {
23+
const thing = { ...stuff };
24+
thing.func;
25+
thing.klass;
26+
thing.obj;
27+
thing.exportedDirectly;
28+
return thing;
29+
}
30+
31+
getStuff().func;
32+
getStuff().klass;
33+
getStuff().obj;
34+
getStuff().exportedDirectly;
35+
36+
37+
//// [spreadExpressionContextualTypeWithNamespace_0.js]
38+
"use strict";
39+
// Repro from #44179 with some modification
40+
exports.__esModule = true;
41+
exports.exportedDirectly = exports.obj = exports.klass = exports.func = void 0;
42+
function func() { }
43+
exports.func = func;
44+
var klass = /** @class */ (function () {
45+
function klass() {
46+
}
47+
return klass;
48+
}());
49+
exports.klass = klass;
50+
var obj = { x: true };
51+
exports.obj = obj;
52+
function exportedDirectly() { }
53+
exports.exportedDirectly = exportedDirectly;
54+
//// [spreadExpressionContextualTypeWithNamespace_1.js]
55+
"use strict";
56+
var __assign = (this && this.__assign) || function () {
57+
__assign = Object.assign || function(t) {
58+
for (var s, i = 1, n = arguments.length; i < n; i++) {
59+
s = arguments[i];
60+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
61+
t[p] = s[p];
62+
}
63+
return t;
64+
};
65+
return __assign.apply(this, arguments);
66+
};
67+
exports.__esModule = true;
68+
var stuff = require("./spreadExpressionContextualTypeWithNamespace_0");
69+
stuff.func;
70+
stuff.klass;
71+
stuff.obj;
72+
stuff.exportedDirectly;
73+
function getStuff() {
74+
var thing = __assign({}, stuff);
75+
thing.func;
76+
thing.klass;
77+
thing.obj;
78+
thing.exportedDirectly;
79+
return thing;
80+
}
81+
getStuff().func;
82+
getStuff().klass;
83+
getStuff().obj;
84+
getStuff().exportedDirectly;
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
=== tests/cases/compiler/spreadExpressionContextualTypeWithNamespace_0.ts ===
2+
// Repro from #44179 with some modification
3+
4+
function func() {}
5+
>func : Symbol(func, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 0, 0))
6+
7+
class klass {}
8+
>klass : Symbol(klass, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 2, 18))
9+
10+
const obj = { x: true };
11+
>obj : Symbol(obj, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 4, 5))
12+
>x : Symbol(x, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 4, 13))
13+
14+
export { func, klass, obj };
15+
>func : Symbol(func, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 8))
16+
>klass : Symbol(klass, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 14))
17+
>obj : Symbol(obj, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 21))
18+
19+
export function exportedDirectly() {}
20+
>exportedDirectly : Symbol(exportedDirectly, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 28))
21+
22+
=== tests/cases/compiler/spreadExpressionContextualTypeWithNamespace_1.ts ===
23+
import * as stuff from "./spreadExpressionContextualTypeWithNamespace_0";
24+
>stuff : Symbol(stuff, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 0, 6))
25+
26+
stuff.func;
27+
>stuff.func : Symbol(stuff.func, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 8))
28+
>stuff : Symbol(stuff, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 0, 6))
29+
>func : Symbol(stuff.func, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 8))
30+
31+
stuff.klass;
32+
>stuff.klass : Symbol(stuff.klass, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 14))
33+
>stuff : Symbol(stuff, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 0, 6))
34+
>klass : Symbol(stuff.klass, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 14))
35+
36+
stuff.obj;
37+
>stuff.obj : Symbol(stuff.obj, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 21))
38+
>stuff : Symbol(stuff, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 0, 6))
39+
>obj : Symbol(stuff.obj, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 21))
40+
41+
stuff.exportedDirectly;
42+
>stuff.exportedDirectly : Symbol(stuff.exportedDirectly, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 28))
43+
>stuff : Symbol(stuff, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 0, 6))
44+
>exportedDirectly : Symbol(stuff.exportedDirectly, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 28))
45+
46+
function getStuff<T>() {
47+
>getStuff : Symbol(getStuff, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 5, 23))
48+
>T : Symbol(T, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 7, 18))
49+
50+
const thing = { ...stuff };
51+
>thing : Symbol(thing, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 8, 7))
52+
>stuff : Symbol(stuff, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 0, 6))
53+
54+
thing.func;
55+
>thing.func : Symbol(stuff.func, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 8))
56+
>thing : Symbol(thing, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 8, 7))
57+
>func : Symbol(stuff.func, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 8))
58+
59+
thing.klass;
60+
>thing.klass : Symbol(stuff.klass, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 14))
61+
>thing : Symbol(thing, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 8, 7))
62+
>klass : Symbol(stuff.klass, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 14))
63+
64+
thing.obj;
65+
>thing.obj : Symbol(stuff.obj, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 21))
66+
>thing : Symbol(thing, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 8, 7))
67+
>obj : Symbol(stuff.obj, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 21))
68+
69+
thing.exportedDirectly;
70+
>thing.exportedDirectly : Symbol(stuff.exportedDirectly, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 28))
71+
>thing : Symbol(thing, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 8, 7))
72+
>exportedDirectly : Symbol(stuff.exportedDirectly, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 28))
73+
74+
return thing;
75+
>thing : Symbol(thing, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 8, 7))
76+
}
77+
78+
getStuff().func;
79+
>getStuff().func : Symbol(stuff.func, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 8))
80+
>getStuff : Symbol(getStuff, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 5, 23))
81+
>func : Symbol(stuff.func, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 8))
82+
83+
getStuff().klass;
84+
>getStuff().klass : Symbol(stuff.klass, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 14))
85+
>getStuff : Symbol(getStuff, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 5, 23))
86+
>klass : Symbol(stuff.klass, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 14))
87+
88+
getStuff().obj;
89+
>getStuff().obj : Symbol(stuff.obj, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 21))
90+
>getStuff : Symbol(getStuff, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 5, 23))
91+
>obj : Symbol(stuff.obj, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 21))
92+
93+
getStuff().exportedDirectly;
94+
>getStuff().exportedDirectly : Symbol(stuff.exportedDirectly, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 28))
95+
>getStuff : Symbol(getStuff, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 5, 23))
96+
>exportedDirectly : Symbol(stuff.exportedDirectly, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 28))
97+
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
=== tests/cases/compiler/spreadExpressionContextualTypeWithNamespace_0.ts ===
2+
// Repro from #44179 with some modification
3+
4+
function func() {}
5+
>func : () => void
6+
7+
class klass {}
8+
>klass : klass
9+
10+
const obj = { x: true };
11+
>obj : { x: boolean; }
12+
>{ x: true } : { x: boolean; }
13+
>x : boolean
14+
>true : true
15+
16+
export { func, klass, obj };
17+
>func : () => void
18+
>klass : typeof klass
19+
>obj : { x: boolean; }
20+
21+
export function exportedDirectly() {}
22+
>exportedDirectly : () => void
23+
24+
=== tests/cases/compiler/spreadExpressionContextualTypeWithNamespace_1.ts ===
25+
import * as stuff from "./spreadExpressionContextualTypeWithNamespace_0";
26+
>stuff : typeof stuff
27+
28+
stuff.func;
29+
>stuff.func : () => void
30+
>stuff : typeof stuff
31+
>func : () => void
32+
33+
stuff.klass;
34+
>stuff.klass : typeof stuff.klass
35+
>stuff : typeof stuff
36+
>klass : typeof stuff.klass
37+
38+
stuff.obj;
39+
>stuff.obj : { x: boolean; }
40+
>stuff : typeof stuff
41+
>obj : { x: boolean; }
42+
43+
stuff.exportedDirectly;
44+
>stuff.exportedDirectly : () => void
45+
>stuff : typeof stuff
46+
>exportedDirectly : () => void
47+
48+
function getStuff<T>() {
49+
>getStuff : <T>() => { exportedDirectly(): void; func: () => void; klass: typeof stuff.klass; obj: { x: boolean; }; }
50+
51+
const thing = { ...stuff };
52+
>thing : { exportedDirectly(): void; func: () => void; klass: typeof stuff.klass; obj: { x: boolean; }; }
53+
>{ ...stuff } : { exportedDirectly(): void; func: () => void; klass: typeof stuff.klass; obj: { x: boolean; }; }
54+
>stuff : typeof stuff
55+
56+
thing.func;
57+
>thing.func : () => void
58+
>thing : { exportedDirectly(): void; func: () => void; klass: typeof stuff.klass; obj: { x: boolean; }; }
59+
>func : () => void
60+
61+
thing.klass;
62+
>thing.klass : typeof stuff.klass
63+
>thing : { exportedDirectly(): void; func: () => void; klass: typeof stuff.klass; obj: { x: boolean; }; }
64+
>klass : typeof stuff.klass
65+
66+
thing.obj;
67+
>thing.obj : { x: boolean; }
68+
>thing : { exportedDirectly(): void; func: () => void; klass: typeof stuff.klass; obj: { x: boolean; }; }
69+
>obj : { x: boolean; }
70+
71+
thing.exportedDirectly;
72+
>thing.exportedDirectly : () => void
73+
>thing : { exportedDirectly(): void; func: () => void; klass: typeof stuff.klass; obj: { x: boolean; }; }
74+
>exportedDirectly : () => void
75+
76+
return thing;
77+
>thing : { exportedDirectly(): void; func: () => void; klass: typeof stuff.klass; obj: { x: boolean; }; }
78+
}
79+
80+
getStuff().func;
81+
>getStuff().func : () => void
82+
>getStuff() : { exportedDirectly(): void; func: () => void; klass: typeof stuff.klass; obj: { x: boolean; }; }
83+
>getStuff : <T>() => { exportedDirectly(): void; func: () => void; klass: typeof stuff.klass; obj: { x: boolean; }; }
84+
>func : () => void
85+
86+
getStuff().klass;
87+
>getStuff().klass : typeof stuff.klass
88+
>getStuff() : { exportedDirectly(): void; func: () => void; klass: typeof stuff.klass; obj: { x: boolean; }; }
89+
>getStuff : <T>() => { exportedDirectly(): void; func: () => void; klass: typeof stuff.klass; obj: { x: boolean; }; }
90+
>klass : typeof stuff.klass
91+
92+
getStuff().obj;
93+
>getStuff().obj : { x: boolean; }
94+
>getStuff() : { exportedDirectly(): void; func: () => void; klass: typeof stuff.klass; obj: { x: boolean; }; }
95+
>getStuff : <T>() => { exportedDirectly(): void; func: () => void; klass: typeof stuff.klass; obj: { x: boolean; }; }
96+
>obj : { x: boolean; }
97+
98+
getStuff().exportedDirectly;
99+
>getStuff().exportedDirectly : () => void
100+
>getStuff() : { exportedDirectly(): void; func: () => void; klass: typeof stuff.klass; obj: { x: boolean; }; }
101+
>getStuff : <T>() => { exportedDirectly(): void; func: () => void; klass: typeof stuff.klass; obj: { x: boolean; }; }
102+
>exportedDirectly : () => void
103+
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// @filename: spreadExpressionContextualTypeWithNamespace_0.ts
2+
3+
// Repro from #44179 with some modification
4+
5+
function func() {}
6+
class klass {}
7+
const obj = { x: true };
8+
9+
export { func, klass, obj };
10+
11+
export function exportedDirectly() {}
12+
13+
// @filename: spreadExpressionContextualTypeWithNamespace_1.ts
14+
import * as stuff from "./spreadExpressionContextualTypeWithNamespace_0";
15+
16+
stuff.func;
17+
stuff.klass;
18+
stuff.obj;
19+
stuff.exportedDirectly;
20+
21+
function getStuff<T>() {
22+
const thing = { ...stuff };
23+
thing.func;
24+
thing.klass;
25+
thing.obj;
26+
thing.exportedDirectly;
27+
return thing;
28+
}
29+
30+
getStuff().func;
31+
getStuff().klass;
32+
getStuff().obj;
33+
getStuff().exportedDirectly;

0 commit comments

Comments
 (0)