disentangle the meaning of SymbolLinks.target (#47098)

This commit is contained in:
LowR
2022-04-08 07:40:39 +09:00
committed by GitHub
parent f4b99ea47c
commit b45cf0d694
6 changed files with 331 additions and 13 deletions

View File

@@ -3116,27 +3116,27 @@ namespace ts {
function resolveAlias(symbol: Symbol): Symbol {
Debug.assert((symbol.flags & SymbolFlags.Alias) !== 0, "Should only get Alias here.");
const links = getSymbolLinks(symbol);
if (!links.target) {
links.target = resolvingSymbol;
if (!links.aliasTarget) {
links.aliasTarget = resolvingSymbol;
const node = getDeclarationOfAliasSymbol(symbol);
if (!node) return Debug.fail();
const target = getTargetOfAliasDeclaration(node);
if (links.target === resolvingSymbol) {
links.target = target || unknownSymbol;
if (links.aliasTarget === resolvingSymbol) {
links.aliasTarget = target || unknownSymbol;
}
else {
error(node, Diagnostics.Circular_definition_of_import_alias_0, symbolToString(symbol));
}
}
else if (links.target === resolvingSymbol) {
links.target = unknownSymbol;
else if (links.aliasTarget === resolvingSymbol) {
links.aliasTarget = unknownSymbol;
}
return links.target;
return links.aliasTarget;
}
function tryResolveAlias(symbol: Symbol): Symbol | undefined {
const links = getSymbolLinks(symbol);
if (links.target !== resolvingSymbol) {
if (links.aliasTarget !== resolvingSymbol) {
return resolveAlias(symbol);
}
@@ -31748,7 +31748,7 @@ namespace ts {
const newSymbol = createSymbol(SymbolFlags.Alias, InternalSymbolName.Default);
newSymbol.parent = originalSymbol;
newSymbol.nameType = getStringLiteralType("default");
newSymbol.target = resolveSymbol(symbol);
newSymbol.aliasTarget = resolveSymbol(symbol);
memberTable.set(InternalSymbolName.Default, newSymbol);
return createAnonymousType(anonymousSymbol, memberTable, emptyArray, emptyArray, emptyArray);
}
@@ -42271,11 +42271,11 @@ namespace ts {
const { leftSpread, rightSpread, syntheticOrigin } = symbol as TransientSymbol;
return leftSpread ? [leftSpread, rightSpread!]
: syntheticOrigin ? [syntheticOrigin]
: singleElementArray(tryGetAliasTarget(symbol));
: singleElementArray(tryGetTarget(symbol));
}
return undefined;
}
function tryGetAliasTarget(symbol: Symbol): Symbol | undefined {
function tryGetTarget(symbol: Symbol): Symbol | undefined {
let target: Symbol | undefined;
let next: Symbol | undefined = symbol;
while (next = getSymbolLinks(next).target) {
@@ -42527,7 +42527,7 @@ namespace ts {
if (links?.referenced) {
return true;
}
const target = getSymbolLinks(symbol!).target; // TODO: GH#18217
const target = getSymbolLinks(symbol!).aliasTarget; // TODO: GH#18217
if (target && getEffectiveModifierFlags(node) & ModifierFlags.Export &&
target.flags & SymbolFlags.Value &&
(shouldPreserveConstEnums(compilerOptions) || !isConstEnumOrConstEnumOnlyModule(target))) {

View File

@@ -4943,7 +4943,8 @@ namespace ts {
/* @internal */
export interface SymbolLinks {
immediateTarget?: Symbol; // Immediate target of an alias. May be another alias. Do not access directly, use `checker.getImmediateAliasedSymbol` instead.
target?: Symbol; // Resolved (non-alias) target of an alias
aliasTarget?: Symbol, // Resolved (non-alias) target of an alias
target?: Symbol; // Original version of an instantiated symbol
type?: Type; // Type of value symbol
writeType?: Type; // Type of value symbol in write contexts
nameType?: Type; // Type associated with a late-bound symbol

View File

@@ -0,0 +1,84 @@
//// [tests/cases/compiler/spreadExpressionContextualTypeWithNamespace.ts] ////
//// [spreadExpressionContextualTypeWithNamespace_0.ts]
// Repro from #44179 with some modification
function func() {}
class klass {}
const obj = { x: true };
export { func, klass, obj };
export function exportedDirectly() {}
//// [spreadExpressionContextualTypeWithNamespace_1.ts]
import * as stuff from "./spreadExpressionContextualTypeWithNamespace_0";
stuff.func;
stuff.klass;
stuff.obj;
stuff.exportedDirectly;
function getStuff<T>() {
const thing = { ...stuff };
thing.func;
thing.klass;
thing.obj;
thing.exportedDirectly;
return thing;
}
getStuff().func;
getStuff().klass;
getStuff().obj;
getStuff().exportedDirectly;
//// [spreadExpressionContextualTypeWithNamespace_0.js]
"use strict";
// Repro from #44179 with some modification
exports.__esModule = true;
exports.exportedDirectly = exports.obj = exports.klass = exports.func = void 0;
function func() { }
exports.func = func;
var klass = /** @class */ (function () {
function klass() {
}
return klass;
}());
exports.klass = klass;
var obj = { x: true };
exports.obj = obj;
function exportedDirectly() { }
exports.exportedDirectly = exportedDirectly;
//// [spreadExpressionContextualTypeWithNamespace_1.js]
"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
exports.__esModule = true;
var stuff = require("./spreadExpressionContextualTypeWithNamespace_0");
stuff.func;
stuff.klass;
stuff.obj;
stuff.exportedDirectly;
function getStuff() {
var thing = __assign({}, stuff);
thing.func;
thing.klass;
thing.obj;
thing.exportedDirectly;
return thing;
}
getStuff().func;
getStuff().klass;
getStuff().obj;
getStuff().exportedDirectly;

View File

@@ -0,0 +1,97 @@
=== tests/cases/compiler/spreadExpressionContextualTypeWithNamespace_0.ts ===
// Repro from #44179 with some modification
function func() {}
>func : Symbol(func, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 0, 0))
class klass {}
>klass : Symbol(klass, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 2, 18))
const obj = { x: true };
>obj : Symbol(obj, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 4, 5))
>x : Symbol(x, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 4, 13))
export { func, klass, obj };
>func : Symbol(func, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 8))
>klass : Symbol(klass, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 14))
>obj : Symbol(obj, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 21))
export function exportedDirectly() {}
>exportedDirectly : Symbol(exportedDirectly, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 28))
=== tests/cases/compiler/spreadExpressionContextualTypeWithNamespace_1.ts ===
import * as stuff from "./spreadExpressionContextualTypeWithNamespace_0";
>stuff : Symbol(stuff, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 0, 6))
stuff.func;
>stuff.func : Symbol(stuff.func, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 8))
>stuff : Symbol(stuff, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 0, 6))
>func : Symbol(stuff.func, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 8))
stuff.klass;
>stuff.klass : Symbol(stuff.klass, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 14))
>stuff : Symbol(stuff, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 0, 6))
>klass : Symbol(stuff.klass, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 14))
stuff.obj;
>stuff.obj : Symbol(stuff.obj, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 21))
>stuff : Symbol(stuff, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 0, 6))
>obj : Symbol(stuff.obj, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 21))
stuff.exportedDirectly;
>stuff.exportedDirectly : Symbol(stuff.exportedDirectly, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 28))
>stuff : Symbol(stuff, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 0, 6))
>exportedDirectly : Symbol(stuff.exportedDirectly, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 28))
function getStuff<T>() {
>getStuff : Symbol(getStuff, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 5, 23))
>T : Symbol(T, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 7, 18))
const thing = { ...stuff };
>thing : Symbol(thing, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 8, 7))
>stuff : Symbol(stuff, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 0, 6))
thing.func;
>thing.func : Symbol(stuff.func, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 8))
>thing : Symbol(thing, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 8, 7))
>func : Symbol(stuff.func, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 8))
thing.klass;
>thing.klass : Symbol(stuff.klass, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 14))
>thing : Symbol(thing, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 8, 7))
>klass : Symbol(stuff.klass, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 14))
thing.obj;
>thing.obj : Symbol(stuff.obj, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 21))
>thing : Symbol(thing, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 8, 7))
>obj : Symbol(stuff.obj, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 21))
thing.exportedDirectly;
>thing.exportedDirectly : Symbol(stuff.exportedDirectly, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 28))
>thing : Symbol(thing, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 8, 7))
>exportedDirectly : Symbol(stuff.exportedDirectly, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 28))
return thing;
>thing : Symbol(thing, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 8, 7))
}
getStuff().func;
>getStuff().func : Symbol(stuff.func, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 8))
>getStuff : Symbol(getStuff, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 5, 23))
>func : Symbol(stuff.func, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 8))
getStuff().klass;
>getStuff().klass : Symbol(stuff.klass, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 14))
>getStuff : Symbol(getStuff, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 5, 23))
>klass : Symbol(stuff.klass, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 14))
getStuff().obj;
>getStuff().obj : Symbol(stuff.obj, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 21))
>getStuff : Symbol(getStuff, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 5, 23))
>obj : Symbol(stuff.obj, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 21))
getStuff().exportedDirectly;
>getStuff().exportedDirectly : Symbol(stuff.exportedDirectly, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 28))
>getStuff : Symbol(getStuff, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 5, 23))
>exportedDirectly : Symbol(stuff.exportedDirectly, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 28))

View File

@@ -0,0 +1,103 @@
=== tests/cases/compiler/spreadExpressionContextualTypeWithNamespace_0.ts ===
// Repro from #44179 with some modification
function func() {}
>func : () => void
class klass {}
>klass : klass
const obj = { x: true };
>obj : { x: boolean; }
>{ x: true } : { x: boolean; }
>x : boolean
>true : true
export { func, klass, obj };
>func : () => void
>klass : typeof klass
>obj : { x: boolean; }
export function exportedDirectly() {}
>exportedDirectly : () => void
=== tests/cases/compiler/spreadExpressionContextualTypeWithNamespace_1.ts ===
import * as stuff from "./spreadExpressionContextualTypeWithNamespace_0";
>stuff : typeof stuff
stuff.func;
>stuff.func : () => void
>stuff : typeof stuff
>func : () => void
stuff.klass;
>stuff.klass : typeof stuff.klass
>stuff : typeof stuff
>klass : typeof stuff.klass
stuff.obj;
>stuff.obj : { x: boolean; }
>stuff : typeof stuff
>obj : { x: boolean; }
stuff.exportedDirectly;
>stuff.exportedDirectly : () => void
>stuff : typeof stuff
>exportedDirectly : () => void
function getStuff<T>() {
>getStuff : <T>() => { exportedDirectly(): void; func: () => void; klass: typeof stuff.klass; obj: { x: boolean; }; }
const thing = { ...stuff };
>thing : { exportedDirectly(): void; func: () => void; klass: typeof stuff.klass; obj: { x: boolean; }; }
>{ ...stuff } : { exportedDirectly(): void; func: () => void; klass: typeof stuff.klass; obj: { x: boolean; }; }
>stuff : typeof stuff
thing.func;
>thing.func : () => void
>thing : { exportedDirectly(): void; func: () => void; klass: typeof stuff.klass; obj: { x: boolean; }; }
>func : () => void
thing.klass;
>thing.klass : typeof stuff.klass
>thing : { exportedDirectly(): void; func: () => void; klass: typeof stuff.klass; obj: { x: boolean; }; }
>klass : typeof stuff.klass
thing.obj;
>thing.obj : { x: boolean; }
>thing : { exportedDirectly(): void; func: () => void; klass: typeof stuff.klass; obj: { x: boolean; }; }
>obj : { x: boolean; }
thing.exportedDirectly;
>thing.exportedDirectly : () => void
>thing : { exportedDirectly(): void; func: () => void; klass: typeof stuff.klass; obj: { x: boolean; }; }
>exportedDirectly : () => void
return thing;
>thing : { exportedDirectly(): void; func: () => void; klass: typeof stuff.klass; obj: { x: boolean; }; }
}
getStuff().func;
>getStuff().func : () => void
>getStuff() : { exportedDirectly(): void; func: () => void; klass: typeof stuff.klass; obj: { x: boolean; }; }
>getStuff : <T>() => { exportedDirectly(): void; func: () => void; klass: typeof stuff.klass; obj: { x: boolean; }; }
>func : () => void
getStuff().klass;
>getStuff().klass : typeof stuff.klass
>getStuff() : { exportedDirectly(): void; func: () => void; klass: typeof stuff.klass; obj: { x: boolean; }; }
>getStuff : <T>() => { exportedDirectly(): void; func: () => void; klass: typeof stuff.klass; obj: { x: boolean; }; }
>klass : typeof stuff.klass
getStuff().obj;
>getStuff().obj : { x: boolean; }
>getStuff() : { exportedDirectly(): void; func: () => void; klass: typeof stuff.klass; obj: { x: boolean; }; }
>getStuff : <T>() => { exportedDirectly(): void; func: () => void; klass: typeof stuff.klass; obj: { x: boolean; }; }
>obj : { x: boolean; }
getStuff().exportedDirectly;
>getStuff().exportedDirectly : () => void
>getStuff() : { exportedDirectly(): void; func: () => void; klass: typeof stuff.klass; obj: { x: boolean; }; }
>getStuff : <T>() => { exportedDirectly(): void; func: () => void; klass: typeof stuff.klass; obj: { x: boolean; }; }
>exportedDirectly : () => void

View File

@@ -0,0 +1,33 @@
// @filename: spreadExpressionContextualTypeWithNamespace_0.ts
// Repro from #44179 with some modification
function func() {}
class klass {}
const obj = { x: true };
export { func, klass, obj };
export function exportedDirectly() {}
// @filename: spreadExpressionContextualTypeWithNamespace_1.ts
import * as stuff from "./spreadExpressionContextualTypeWithNamespace_0";
stuff.func;
stuff.klass;
stuff.obj;
stuff.exportedDirectly;
function getStuff<T>() {
const thing = { ...stuff };
thing.func;
thing.klass;
thing.obj;
thing.exportedDirectly;
return thing;
}
getStuff().func;
getStuff().klass;
getStuff().obj;
getStuff().exportedDirectly;