Always resolve the first identifier of computed property name to get the symbol and track it

Fixes #24798
This commit is contained in:
Sheetal Nandi 2018-06-08 13:57:25 -07:00
parent 855c3a6d4f
commit 5d70d9223c
9 changed files with 331 additions and 3 deletions

View File

@ -3533,9 +3533,13 @@ namespace ts {
context.enclosingDeclaration = undefined;
if (getCheckFlags(propertySymbol) & CheckFlags.Late) {
const decl = first(propertySymbol.declarations);
const name = hasLateBindableName(decl) && resolveEntityName(decl.name.expression, SymbolFlags.Value);
if (name && context.tracker.trackSymbol) {
context.tracker.trackSymbol(name, saveEnclosingDeclaration, SymbolFlags.Value);
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);
}
}
}
const propertyName = symbolToName(propertySymbol, context, SymbolFlags.Value, /*expectsIdentifier*/ true);

View File

@ -0,0 +1,46 @@
//// [tests/cases/compiler/declarationEmitWithDefaultAsComputedName.ts] ////
//// [other.ts]
type Experiment<Name> = {
name: Name;
};
declare const createExperiment: <Name extends string>(
options: Experiment<Name>
) => Experiment<Name>;
export default createExperiment({
name: "foo"
});
//// [main.ts]
import other from "./other";
export const obj = {
[other.name]: 1,
};
//// [other.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = createExperiment({
name: "foo"
});
//// [main.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var _a;
var other_1 = require("./other");
exports.obj = (_a = {},
_a[other_1.default.name] = 1,
_a);
//// [other.d.ts]
declare type Experiment<Name> = {
name: Name;
};
declare const _default: Experiment<"foo">;
export default _default;
//// [main.d.ts]
import other from "./other";
export declare const obj: {
[other.name]: number;
};

View File

@ -0,0 +1,45 @@
=== tests/cases/compiler/other.ts ===
type Experiment<Name> = {
>Experiment : Symbol(Experiment, Decl(other.ts, 0, 0))
>Name : Symbol(Name, Decl(other.ts, 0, 16))
name: Name;
>name : Symbol(name, Decl(other.ts, 0, 25))
>Name : Symbol(Name, Decl(other.ts, 0, 16))
};
declare const createExperiment: <Name extends string>(
>createExperiment : Symbol(createExperiment, Decl(other.ts, 3, 13))
>Name : Symbol(Name, Decl(other.ts, 3, 33))
options: Experiment<Name>
>options : Symbol(options, Decl(other.ts, 3, 54))
>Experiment : Symbol(Experiment, Decl(other.ts, 0, 0))
>Name : Symbol(Name, Decl(other.ts, 3, 33))
) => Experiment<Name>;
>Experiment : Symbol(Experiment, Decl(other.ts, 0, 0))
>Name : Symbol(Name, Decl(other.ts, 3, 33))
export default createExperiment({
>createExperiment : Symbol(createExperiment, Decl(other.ts, 3, 13))
name: "foo"
>name : Symbol(name, Decl(other.ts, 6, 33))
});
=== tests/cases/compiler/main.ts ===
import other from "./other";
>other : Symbol(other, Decl(main.ts, 0, 6))
export const obj = {
>obj : Symbol(obj, Decl(main.ts, 1, 12))
[other.name]: 1,
>[other.name] : Symbol([other.name], Decl(main.ts, 1, 20))
>other.name : Symbol(name, Decl(other.ts, 0, 25))
>other : Symbol(other, Decl(main.ts, 0, 6))
>name : Symbol(name, Decl(other.ts, 0, 25))
};

View File

@ -0,0 +1,50 @@
=== tests/cases/compiler/other.ts ===
type Experiment<Name> = {
>Experiment : Experiment<Name>
>Name : Name
name: Name;
>name : Name
>Name : Name
};
declare const createExperiment: <Name extends string>(
>createExperiment : <Name extends string>(options: Experiment<Name>) => Experiment<Name>
>Name : Name
options: Experiment<Name>
>options : Experiment<Name>
>Experiment : Experiment<Name>
>Name : Name
) => Experiment<Name>;
>Experiment : Experiment<Name>
>Name : Name
export default createExperiment({
>createExperiment({ name: "foo"}) : Experiment<"foo">
>createExperiment : <Name extends string>(options: Experiment<Name>) => Experiment<Name>
>{ name: "foo"} : { name: "foo"; }
name: "foo"
>name : "foo"
>"foo" : "foo"
});
=== tests/cases/compiler/main.ts ===
import other from "./other";
>other : { name: "foo"; }
export const obj = {
>obj : { [other.name]: number; }
>{ [other.name]: 1,} : { [other.name]: number; }
[other.name]: 1,
>[other.name] : number
>other.name : "foo"
>other : { name: "foo"; }
>name : "foo"
>1 : 1
};

View File

@ -0,0 +1,46 @@
//// [tests/cases/compiler/declarationEmitWithDefaultAsComputedName2.ts] ////
//// [other.ts]
type Experiment<Name> = {
name: Name;
};
declare const createExperiment: <Name extends string>(
options: Experiment<Name>
) => Experiment<Name>;
export default createExperiment({
name: "foo"
});
//// [main.ts]
import * as other2 from "./other";
export const obj = {
[other2.default.name]: 1
};
//// [other.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = createExperiment({
name: "foo"
});
//// [main.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var _a;
var other2 = require("./other");
exports.obj = (_a = {},
_a[other2.default.name] = 1,
_a);
//// [other.d.ts]
declare type Experiment<Name> = {
name: Name;
};
declare const _default: Experiment<"foo">;
export default _default;
//// [main.d.ts]
import * as other2 from "./other";
export declare const obj: {
[other2.default.name]: number;
};

View File

@ -0,0 +1,47 @@
=== tests/cases/compiler/other.ts ===
type Experiment<Name> = {
>Experiment : Symbol(Experiment, Decl(other.ts, 0, 0))
>Name : Symbol(Name, Decl(other.ts, 0, 16))
name: Name;
>name : Symbol(name, Decl(other.ts, 0, 25))
>Name : Symbol(Name, Decl(other.ts, 0, 16))
};
declare const createExperiment: <Name extends string>(
>createExperiment : Symbol(createExperiment, Decl(other.ts, 3, 13))
>Name : Symbol(Name, Decl(other.ts, 3, 33))
options: Experiment<Name>
>options : Symbol(options, Decl(other.ts, 3, 54))
>Experiment : Symbol(Experiment, Decl(other.ts, 0, 0))
>Name : Symbol(Name, Decl(other.ts, 3, 33))
) => Experiment<Name>;
>Experiment : Symbol(Experiment, Decl(other.ts, 0, 0))
>Name : Symbol(Name, Decl(other.ts, 3, 33))
export default createExperiment({
>createExperiment : Symbol(createExperiment, Decl(other.ts, 3, 13))
name: "foo"
>name : Symbol(name, Decl(other.ts, 6, 33))
});
=== tests/cases/compiler/main.ts ===
import * as other2 from "./other";
>other2 : Symbol(other2, Decl(main.ts, 0, 6))
export const obj = {
>obj : Symbol(obj, Decl(main.ts, 1, 12))
[other2.default.name]: 1
>[other2.default.name] : Symbol([other2.default.name], Decl(main.ts, 1, 20))
>other2.default.name : Symbol(name, Decl(other.ts, 0, 25))
>other2.default : Symbol(other2.default, Decl(other.ts, 5, 22))
>other2 : Symbol(other2, Decl(main.ts, 0, 6))
>default : Symbol(other2.default, Decl(other.ts, 5, 22))
>name : Symbol(name, Decl(other.ts, 0, 25))
};

View File

@ -0,0 +1,52 @@
=== tests/cases/compiler/other.ts ===
type Experiment<Name> = {
>Experiment : Experiment<Name>
>Name : Name
name: Name;
>name : Name
>Name : Name
};
declare const createExperiment: <Name extends string>(
>createExperiment : <Name extends string>(options: Experiment<Name>) => Experiment<Name>
>Name : Name
options: Experiment<Name>
>options : Experiment<Name>
>Experiment : Experiment<Name>
>Name : Name
) => Experiment<Name>;
>Experiment : Experiment<Name>
>Name : Name
export default createExperiment({
>createExperiment({ name: "foo"}) : Experiment<"foo">
>createExperiment : <Name extends string>(options: Experiment<Name>) => Experiment<Name>
>{ name: "foo"} : { name: "foo"; }
name: "foo"
>name : "foo"
>"foo" : "foo"
});
=== tests/cases/compiler/main.ts ===
import * as other2 from "./other";
>other2 : typeof other2
export const obj = {
>obj : { [other2.default.name]: number; }
>{ [other2.default.name]: 1} : { [other2.default.name]: number; }
[other2.default.name]: 1
>[other2.default.name] : number
>other2.default.name : "foo"
>other2.default : { name: "foo"; }
>other2 : typeof other2
>default : { name: "foo"; }
>name : "foo"
>1 : 1
};

View File

@ -0,0 +1,19 @@
// @declaration: true
// @target: es5
// @filename: other.ts
type Experiment<Name> = {
name: Name;
};
declare const createExperiment: <Name extends string>(
options: Experiment<Name>
) => Experiment<Name>;
export default createExperiment({
name: "foo"
});
// @filename: main.ts
import other from "./other";
export const obj = {
[other.name]: 1,
};

View File

@ -0,0 +1,19 @@
// @declaration: true
// @target: es5
// @filename: other.ts
type Experiment<Name> = {
name: Name;
};
declare const createExperiment: <Name extends string>(
options: Experiment<Name>
) => Experiment<Name>;
export default createExperiment({
name: "foo"
});
// @filename: main.ts
import * as other2 from "./other";
export const obj = {
[other2.default.name]: 1
};