mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-04 21:53:42 -06:00
Track late bound names in binding patterns (#26336)
This commit is contained in:
parent
d58b1f664b
commit
d433c6ed05
@ -3552,15 +3552,10 @@ namespace ts {
|
||||
anyType : getTypeOfSymbol(propertySymbol);
|
||||
const saveEnclosingDeclaration = context.enclosingDeclaration;
|
||||
context.enclosingDeclaration = undefined;
|
||||
if (getCheckFlags(propertySymbol) & CheckFlags.Late) {
|
||||
if (context.tracker.trackSymbol && getCheckFlags(propertySymbol) & CheckFlags.Late) {
|
||||
const decl = first(propertySymbol.declarations);
|
||||
if (context.tracker.trackSymbol && hasLateBindableName(decl)) {
|
||||
// get symbol of the first identifier of the entityName
|
||||
const firstIdentifier = getFirstIdentifier(decl.name.expression);
|
||||
const name = resolveName(firstIdentifier, firstIdentifier.escapedText, SymbolFlags.Value | SymbolFlags.ExportValue, /*nodeNotFoundErrorMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ true);
|
||||
if (name) {
|
||||
context.tracker.trackSymbol(name, saveEnclosingDeclaration, SymbolFlags.Value);
|
||||
}
|
||||
if (hasLateBindableName(decl)) {
|
||||
trackComputedName(decl.name, saveEnclosingDeclaration, context);
|
||||
}
|
||||
}
|
||||
const propertyName = symbolToName(propertySymbol, context, SymbolFlags.Value, /*expectsIdentifier*/ true);
|
||||
@ -3770,6 +3765,9 @@ namespace ts {
|
||||
function cloneBindingName(node: BindingName): BindingName {
|
||||
return <BindingName>elideInitializerAndSetEmitFlags(node);
|
||||
function elideInitializerAndSetEmitFlags(node: Node): Node {
|
||||
if (context.tracker.trackSymbol && isComputedPropertyName(node) && isLateBindableName(node)) {
|
||||
trackComputedName(node, context.enclosingDeclaration, context);
|
||||
}
|
||||
const visited = visitEachChild(node, elideInitializerAndSetEmitFlags, nullTransformationContext, /*nodesVisitor*/ undefined, elideInitializerAndSetEmitFlags)!;
|
||||
const clone = nodeIsSynthesized(visited) ? visited : getSynthesizedClone(visited);
|
||||
if (clone.kind === SyntaxKind.BindingElement) {
|
||||
@ -3780,6 +3778,16 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function trackComputedName(node: LateBoundName, enclosingDeclaration: Node | undefined, context: NodeBuilderContext) {
|
||||
if (!context.tracker.trackSymbol) return;
|
||||
// get symbol of the first identifier of the entityName
|
||||
const firstIdentifier = getFirstIdentifier(node.expression);
|
||||
const name = resolveName(firstIdentifier, firstIdentifier.escapedText, SymbolFlags.Value | SymbolFlags.ExportValue, /*nodeNotFoundErrorMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ true);
|
||||
if (name) {
|
||||
context.tracker.trackSymbol(name, enclosingDeclaration, SymbolFlags.Value);
|
||||
}
|
||||
}
|
||||
|
||||
function lookupSymbolChain(symbol: Symbol, context: NodeBuilderContext, meaning: SymbolFlags, yieldModuleSymbol?: boolean) {
|
||||
context.tracker.trackSymbol!(symbol, context.enclosingDeclaration, meaning); // TODO: GH#18217
|
||||
// Try to get qualified name if the symbol is not a type parameter and there is an enclosing declaration.
|
||||
|
||||
@ -0,0 +1,43 @@
|
||||
//// [tests/cases/compiler/declarationEmitComputedNameCausesImportToBePainted.ts] ////
|
||||
|
||||
//// [context.ts]
|
||||
export const Key = Symbol();
|
||||
export interface Context {
|
||||
[Key]: string;
|
||||
}
|
||||
//// [index.ts]
|
||||
import { Key, Context } from "./context";
|
||||
|
||||
export const context: Context = {
|
||||
[Key]: 'bar',
|
||||
}
|
||||
|
||||
export const withContext = ({ [Key]: value }: Context) => value;
|
||||
|
||||
//// [context.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
exports.Key = Symbol();
|
||||
//// [index.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var _a;
|
||||
var context_1 = require("./context");
|
||||
exports.context = (_a = {},
|
||||
_a[context_1.Key] = 'bar',
|
||||
_a);
|
||||
exports.withContext = function (_a) {
|
||||
var _b = context_1.Key, value = _a[_b];
|
||||
return value;
|
||||
};
|
||||
|
||||
|
||||
//// [context.d.ts]
|
||||
export declare const Key: unique symbol;
|
||||
export interface Context {
|
||||
[Key]: string;
|
||||
}
|
||||
//// [index.d.ts]
|
||||
import { Key, Context } from "./context";
|
||||
export declare const context: Context;
|
||||
export declare const withContext: ({ [Key]: value }: Context) => string;
|
||||
@ -0,0 +1,33 @@
|
||||
=== tests/cases/compiler/context.ts ===
|
||||
export const Key = Symbol();
|
||||
>Key : Symbol(Key, Decl(context.ts, 0, 12))
|
||||
>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --))
|
||||
|
||||
export interface Context {
|
||||
>Context : Symbol(Context, Decl(context.ts, 0, 28))
|
||||
|
||||
[Key]: string;
|
||||
>[Key] : Symbol(Context[Key], Decl(context.ts, 1, 26))
|
||||
>Key : Symbol(Key, Decl(context.ts, 0, 12))
|
||||
}
|
||||
=== tests/cases/compiler/index.ts ===
|
||||
import { Key, Context } from "./context";
|
||||
>Key : Symbol(Key, Decl(index.ts, 0, 8))
|
||||
>Context : Symbol(Context, Decl(index.ts, 0, 13))
|
||||
|
||||
export const context: Context = {
|
||||
>context : Symbol(context, Decl(index.ts, 2, 12))
|
||||
>Context : Symbol(Context, Decl(index.ts, 0, 13))
|
||||
|
||||
[Key]: 'bar',
|
||||
>[Key] : Symbol([Key], Decl(index.ts, 2, 33))
|
||||
>Key : Symbol(Key, Decl(index.ts, 0, 8))
|
||||
}
|
||||
|
||||
export const withContext = ({ [Key]: value }: Context) => value;
|
||||
>withContext : Symbol(withContext, Decl(index.ts, 6, 12))
|
||||
>Key : Symbol(Key, Decl(index.ts, 0, 8))
|
||||
>value : Symbol(value, Decl(index.ts, 6, 29))
|
||||
>Context : Symbol(Context, Decl(index.ts, 0, 13))
|
||||
>value : Symbol(value, Decl(index.ts, 6, 29))
|
||||
|
||||
@ -0,0 +1,33 @@
|
||||
=== tests/cases/compiler/context.ts ===
|
||||
export const Key = Symbol();
|
||||
>Key : unique symbol
|
||||
>Symbol() : unique symbol
|
||||
>Symbol : SymbolConstructor
|
||||
|
||||
export interface Context {
|
||||
[Key]: string;
|
||||
>[Key] : string
|
||||
>Key : unique symbol
|
||||
}
|
||||
=== tests/cases/compiler/index.ts ===
|
||||
import { Key, Context } from "./context";
|
||||
>Key : unique symbol
|
||||
>Context : any
|
||||
|
||||
export const context: Context = {
|
||||
>context : Context
|
||||
>{ [Key]: 'bar',} : { [Key]: string; }
|
||||
|
||||
[Key]: 'bar',
|
||||
>[Key] : string
|
||||
>Key : unique symbol
|
||||
>'bar' : "bar"
|
||||
}
|
||||
|
||||
export const withContext = ({ [Key]: value }: Context) => value;
|
||||
>withContext : ({ [Key]: value }: Context) => string
|
||||
>({ [Key]: value }: Context) => value : ({ [Key]: value }: Context) => string
|
||||
>Key : unique symbol
|
||||
>value : string
|
||||
>value : string
|
||||
|
||||
@ -0,0 +1,15 @@
|
||||
// @declaration: true
|
||||
// @lib: es6
|
||||
// @filename: context.ts
|
||||
export const Key = Symbol();
|
||||
export interface Context {
|
||||
[Key]: string;
|
||||
}
|
||||
// @filename: index.ts
|
||||
import { Key, Context } from "./context";
|
||||
|
||||
export const context: Context = {
|
||||
[Key]: 'bar',
|
||||
}
|
||||
|
||||
export const withContext = ({ [Key]: value }: Context) => value;
|
||||
Loading…
x
Reference in New Issue
Block a user