Non-latebound computed property names should print as their underlying name type (#29084)

This commit is contained in:
Wesley Wigham 2018-12-18 17:02:34 -08:00 committed by GitHub
parent fd7fd133e2
commit d23effc200
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 134 additions and 11 deletions

View File

@ -4426,6 +4426,22 @@ namespace ts {
return location.kind === SyntaxKind.SourceFile || isAmbientModule(location);
}
function getNameOfSymbolFromNameType(symbol: Symbol, context?: NodeBuilderContext) {
const nameType = symbol.nameType;
if (nameType) {
if (nameType.flags & TypeFlags.StringOrNumberLiteral) {
const name = "" + (<StringLiteralType | NumberLiteralType>nameType).value;
if (!isIdentifierText(name, compilerOptions.target) && !isNumericLiteralName(name)) {
return `"${escapeString(name, CharacterCodes.doubleQuote)}"`;
}
return name;
}
if (nameType.flags & TypeFlags.UniqueESSymbol) {
return `[${getNameOfSymbolAsWritten((<UniqueESSymbolType>nameType).symbol, context)}]`;
}
}
}
/**
* Gets a human-readable name for a symbol.
* Should *not* be used for the right-hand side of a `.` -- use `symbolName(symbol)` for that instead.
@ -4450,6 +4466,13 @@ namespace ts {
if (isCallExpression(declaration) && isBindableObjectDefinePropertyCall(declaration)) {
return symbolName(symbol);
}
if (isComputedPropertyName(name) && !(getCheckFlags(symbol) & CheckFlags.Late) && symbol.nameType && symbol.nameType.flags & TypeFlags.StringOrNumberLiteral) {
// Computed property name isn't late bound, but has a well-known name type - use name type to generate a symbol name
const result = getNameOfSymbolFromNameType(symbol, context);
if (result !== undefined) {
return result;
}
}
return declarationNameToString(name);
}
if (declaration.parent && declaration.parent.kind === SyntaxKind.VariableDeclaration) {
@ -4465,16 +4488,8 @@ namespace ts {
return declaration.kind === SyntaxKind.ClassExpression ? "(Anonymous class)" : "(Anonymous function)";
}
}
const nameType = symbol.nameType;
if (nameType) {
if (nameType.flags & TypeFlags.StringLiteral && !isIdentifierText((<StringLiteralType>nameType).value, compilerOptions.target)) {
return `"${escapeString((<StringLiteralType>nameType).value, CharacterCodes.doubleQuote)}"`;
}
if (nameType && nameType.flags & TypeFlags.UniqueESSymbol) {
return `[${getNameOfSymbolAsWritten((<UniqueESSymbolType>nameType).symbol, context)}]`;
}
}
return symbolName(symbol);
const name = getNameOfSymbolFromNameType(symbol, context);
return name !== undefined ? name : symbolName(symbol);
}
function isDeclarationVisible(node: Node): boolean {

View File

@ -0,0 +1,44 @@
//// [tests/cases/compiler/declarationEmitComputedNameConstEnumAlias.ts] ////
//// [EnumExample.ts]
enum EnumExample {
TEST = 'TEST',
}
export default EnumExample;
//// [index.ts]
import EnumExample from './EnumExample';
export default {
[EnumExample.TEST]: {},
};
//// [EnumExample.js]
"use strict";
exports.__esModule = true;
var EnumExample;
(function (EnumExample) {
EnumExample["TEST"] = "TEST";
})(EnumExample || (EnumExample = {}));
exports["default"] = EnumExample;
//// [index.js]
"use strict";
exports.__esModule = true;
var _a;
var EnumExample_1 = require("./EnumExample");
exports["default"] = (_a = {},
_a[EnumExample_1["default"].TEST] = {},
_a);
//// [EnumExample.d.ts]
declare enum EnumExample {
TEST = "TEST"
}
export default EnumExample;
//// [index.d.ts]
declare const _default: {
TEST: {};
};
export default _default;

View File

@ -0,0 +1,23 @@
=== tests/cases/compiler/EnumExample.ts ===
enum EnumExample {
>EnumExample : Symbol(EnumExample, Decl(EnumExample.ts, 0, 0))
TEST = 'TEST',
>TEST : Symbol(EnumExample.TEST, Decl(EnumExample.ts, 0, 18))
}
export default EnumExample;
>EnumExample : Symbol(EnumExample, Decl(EnumExample.ts, 0, 0))
=== tests/cases/compiler/index.ts ===
import EnumExample from './EnumExample';
>EnumExample : Symbol(EnumExample, Decl(index.ts, 0, 6))
export default {
[EnumExample.TEST]: {},
>[EnumExample.TEST] : Symbol([EnumExample.TEST], Decl(index.ts, 2, 16))
>EnumExample.TEST : Symbol(EnumExample.TEST, Decl(EnumExample.ts, 0, 18))
>EnumExample : Symbol(EnumExample, Decl(index.ts, 0, 6))
>TEST : Symbol(EnumExample.TEST, Decl(EnumExample.ts, 0, 18))
};

View File

@ -0,0 +1,27 @@
=== tests/cases/compiler/EnumExample.ts ===
enum EnumExample {
>EnumExample : EnumExample
TEST = 'TEST',
>TEST : EnumExample.TEST
>'TEST' : "TEST"
}
export default EnumExample;
>EnumExample : EnumExample
=== tests/cases/compiler/index.ts ===
import EnumExample from './EnumExample';
>EnumExample : typeof EnumExample
export default {
>{ [EnumExample.TEST]: {},} : { [EnumExample.TEST]: {}; }
[EnumExample.TEST]: {},
>[EnumExample.TEST] : {}
>EnumExample.TEST : EnumExample
>EnumExample : typeof EnumExample
>TEST : EnumExample
>{} : {}
};

View File

@ -1,6 +1,6 @@
=== tests/cases/conformance/parser/ecmascript6/ComputedPropertyNames/parserComputedPropertyName35.ts ===
var x = {
>x : { [0, 1]: {}; }
>x : { 1: {}; }
>{ [0, 1]: { }} : { [0, 1]: {}; }
[0, 1]: { }

View File

@ -0,0 +1,14 @@
// @declaration: true
// @filename: EnumExample.ts
enum EnumExample {
TEST = 'TEST',
}
export default EnumExample;
// @filename: index.ts
import EnumExample from './EnumExample';
export default {
[EnumExample.TEST]: {},
};