Skip to content

Commit 04d7355

Browse files
author
Andy Hanson
committed
Treat NoSubstitutionTemplateLiteral like StringLiteral in more places
1 parent 01f6093 commit 04d7355

14 files changed

+45
-46
lines changed

src/compiler/binder.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ namespace ts {
259259
if (name.kind === SyntaxKind.ComputedPropertyName) {
260260
const nameExpression = name.expression;
261261
// treat computed property names where expression is string/numeric literal as just string/numeric literal
262-
if (isStringOrNumericLiteral(nameExpression)) {
262+
if (isStringOrNumericLiteralLike(nameExpression)) {
263263
return escapeLeadingUnderscores(nameExpression.text);
264264
}
265265

src/compiler/checker.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4442,7 +4442,7 @@ namespace ts {
44424442
}
44434443

44444444
function isComputedNonLiteralName(name: PropertyName): boolean {
4445-
return name.kind === SyntaxKind.ComputedPropertyName && !isStringOrNumericLiteral(name.expression);
4445+
return name.kind === SyntaxKind.ComputedPropertyName && !isStringOrNumericLiteralLike(name.expression);
44464446
}
44474447

44484448
function getRestType(source: Type, properties: PropertyName[], symbol: Symbol | undefined): Type {
@@ -13715,7 +13715,7 @@ namespace ts {
1371513715
case SyntaxKind.Identifier:
1371613716
return idText(name);
1371713717
case SyntaxKind.ComputedPropertyName:
13718-
return isStringOrNumericLiteral(name.expression) ? name.expression.text : undefined;
13718+
return isStringOrNumericLiteralLike(name.expression) ? name.expression.text : undefined;
1371913719
case SyntaxKind.StringLiteral:
1372013720
case SyntaxKind.NumericLiteral:
1372113721
return name.text;

src/compiler/parser.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4465,7 +4465,7 @@ namespace ts {
44654465
}
44664466
else {
44674467
const argument = allowInAnd(parseExpression);
4468-
if (isStringOrNumericLiteral(argument)) {
4468+
if (isStringOrNumericLiteralLike(argument)) {
44694469
argument.text = internIdentifier(argument.text);
44704470
}
44714471
indexedAccess.argumentExpression = argument;

src/compiler/transformers/destructuring.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,7 @@ namespace ts {
447447
const argumentExpression = ensureIdentifier(flattenContext, visitNode(propertyName.expression, flattenContext.visitor), /*reuseIdentifierExpressions*/ false, /*location*/ propertyName);
448448
return createElementAccess(value, argumentExpression);
449449
}
450-
else if (isStringOrNumericLiteral(propertyName)) {
450+
else if (isStringOrNumericLiteralLike(propertyName)) {
451451
const argumentExpression = getSynthesizedClone(propertyName);
452452
argumentExpression.text = argumentExpression.text;
453453
return createElementAccess(value, argumentExpression);

src/compiler/utilities.ts

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -767,9 +767,9 @@ namespace ts {
767767
case SyntaxKind.NumericLiteral:
768768
return escapeLeadingUnderscores(name.text);
769769
case SyntaxKind.ComputedPropertyName:
770-
return isStringOrNumericLiteral(name.expression) ? escapeLeadingUnderscores(name.expression.text) : undefined!; // TODO: GH#18217 Almost all uses of this assume the result to be defined!
770+
return isStringOrNumericLiteralLike(name.expression) ? escapeLeadingUnderscores(name.expression.text) : undefined!; // TODO: GH#18217 Almost all uses of this assume the result to be defined!
771771
default:
772-
Debug.assertNever(name);
772+
return Debug.assertNever(name);
773773
}
774774
}
775775

@@ -2566,6 +2566,10 @@ namespace ts {
25662566
|| kind === SyntaxKind.NumericLiteral;
25672567
}
25682568

2569+
export function isStringOrNumericLiteralLike(node: Node): node is StringLiteralLike | NumericLiteral {
2570+
return isStringOrNumericLiteral(node) || isNoSubstitutionTemplateLiteral(node);
2571+
}
2572+
25692573
/**
25702574
* A declaration has a dynamic name if both of the following are true:
25712575
* 1. The declaration has a computed property name
@@ -2580,7 +2584,7 @@ namespace ts {
25802584

25812585
export function isDynamicName(name: DeclarationName): boolean {
25822586
return name.kind === SyntaxKind.ComputedPropertyName &&
2583-
!isStringOrNumericLiteral(name.expression) &&
2587+
!isStringOrNumericLiteralLike(name.expression) &&
25842588
!isWellKnownSymbolSyntactically(name.expression);
25852589
}
25862590

@@ -2593,24 +2597,25 @@ namespace ts {
25932597
return isPropertyAccessExpression(node) && isESSymbolIdentifier(node.expression);
25942598
}
25952599

2596-
export function getPropertyNameForPropertyNameNode(name: DeclarationName): __String | undefined {
2597-
if (name.kind === SyntaxKind.Identifier) {
2598-
return name.escapedText;
2599-
}
2600-
if (name.kind === SyntaxKind.StringLiteral || name.kind === SyntaxKind.NumericLiteral) {
2601-
return escapeLeadingUnderscores(name.text);
2602-
}
2603-
if (name.kind === SyntaxKind.ComputedPropertyName) {
2604-
const nameExpression = name.expression;
2605-
if (isWellKnownSymbolSyntactically(nameExpression)) {
2606-
return getPropertyNameForKnownSymbolName(idText((<PropertyAccessExpression>nameExpression).name));
2607-
}
2608-
else if (nameExpression.kind === SyntaxKind.StringLiteral || nameExpression.kind === SyntaxKind.NumericLiteral) {
2609-
return escapeLeadingUnderscores((<LiteralExpression>nameExpression).text);
2610-
}
2600+
export function getPropertyNameForPropertyNameNode(name: PropertyName): __String | undefined {
2601+
switch (name.kind) {
2602+
case SyntaxKind.Identifier:
2603+
return name.escapedText;
2604+
case SyntaxKind.StringLiteral:
2605+
case SyntaxKind.NumericLiteral:
2606+
return escapeLeadingUnderscores(name.text);
2607+
case SyntaxKind.ComputedPropertyName:
2608+
const nameExpression = name.expression;
2609+
if (isWellKnownSymbolSyntactically(nameExpression)) {
2610+
return getPropertyNameForKnownSymbolName(idText((<PropertyAccessExpression>nameExpression).name));
2611+
}
2612+
else if (isStringOrNumericLiteralLike(nameExpression)) {
2613+
return escapeLeadingUnderscores(nameExpression.text);
2614+
}
2615+
return undefined;
2616+
default:
2617+
return Debug.assertNever(name);
26112618
}
2612-
2613-
return undefined;
26142619
}
26152620

26162621
export type PropertyNameLiteral = Identifier | StringLiteralLike | NumericLiteral;
@@ -3326,9 +3331,9 @@ namespace ts {
33263331
}
33273332
else {
33283333
forEach(declarations, (member: Declaration) => {
3329-
if ((member.kind === SyntaxKind.GetAccessor || member.kind === SyntaxKind.SetAccessor)
3334+
if (isAccessor(member)
33303335
&& hasModifier(member, ModifierFlags.Static) === hasModifier(accessor, ModifierFlags.Static)) {
3331-
const memberName = getPropertyNameForPropertyNameNode((member as NamedDeclaration).name!);
3336+
const memberName = getPropertyNameForPropertyNameNode(member.name);
33323337
const accessorName = getPropertyNameForPropertyNameNode(accessor.name);
33333338
if (memberName === accessorName) {
33343339
if (!firstAccessor) {

src/services/navigationBar.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,7 @@ namespace ts.NavigationBar {
416416
}
417417

418418
const declName = getNameOfDeclaration(<Declaration>node);
419-
if (declName) {
419+
if (declName && isPropertyName(declName)) {
420420
return unescapeLeadingUnderscores(getPropertyNameForPropertyNameNode(declName)!); // TODO: GH#18217
421421
}
422422
switch (node.kind) {

src/services/rename.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ namespace ts.Rename {
2929
if (isStringLiteralLike(node) && tryGetImportFromModuleSpecifier(node)) return undefined;
3030

3131
const kind = SymbolDisplay.getSymbolKind(typeChecker, symbol, node);
32-
const specifierName = (isImportOrExportSpecifierName(node) || isStringOrNumericLiteral(node) && node.parent.kind === SyntaxKind.ComputedPropertyName)
32+
const specifierName = (isImportOrExportSpecifierName(node) || isStringOrNumericLiteralLike(node) && node.parent.kind === SyntaxKind.ComputedPropertyName)
3333
? stripQuotes(getTextOfIdentifierOrLiteral(node))
3434
: undefined;
3535
const displayName = specifierName || typeChecker.symbolToString(symbol);

src/services/services.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2142,7 +2142,7 @@ namespace ts {
21422142
function initializeNameTable(sourceFile: SourceFile): void {
21432143
const nameTable = sourceFile.nameTable = createUnderscoreEscapedMap<number>();
21442144
sourceFile.forEachChild(function walk(node) {
2145-
if (isIdentifier(node) && node.escapedText || isStringOrNumericLiteral(node) && literalIsName(node)) {
2145+
if (isIdentifier(node) && node.escapedText || isStringOrNumericLiteralLike(node) && literalIsName(node)) {
21462146
const text = getEscapedTextOfIdentifierOrLiteral(node);
21472147
nameTable.set(text, nameTable.get(text) === undefined ? node.pos : -1);
21482148
}
@@ -2162,7 +2162,7 @@ namespace ts {
21622162
* then we want 'something' to be in the name table. Similarly, if we have
21632163
* "a['propname']" then we want to store "propname" in the name table.
21642164
*/
2165-
function literalIsName(node: StringLiteral | NumericLiteral): boolean {
2165+
function literalIsName(node: StringLiteralLike | NumericLiteral): boolean {
21662166
return isDeclarationName(node) ||
21672167
node.parent.kind === SyntaxKind.ExternalModuleReference ||
21682168
isArgumentOfElementAccessExpression(node) ||

src/services/utilities.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1240,7 +1240,7 @@ namespace ts {
12401240
export function getNameFromPropertyName(name: PropertyName): string | undefined {
12411241
return name.kind === SyntaxKind.ComputedPropertyName
12421242
// treat computed property names where expression is string/numeric literal as just string/numeric literal
1243-
? isStringOrNumericLiteral(name.expression) ? name.expression.text : undefined
1243+
? isStringOrNumericLiteralLike(name.expression) ? name.expression.text : undefined
12441244
: getTextOfIdentifierOrLiteral(name);
12451245
}
12461246

tests/baselines/reference/computedPropertyNames11_ES5.types

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ var a: any;
99
>a : any
1010

1111
var v = {
12-
>v : { [x: string]: any; [x: number]: any; [""]: any; readonly [0]: number; }
13-
>{ get [s]() { return 0; }, set [n](v) { }, get [s + s]() { return 0; }, set [s + n](v) { }, get [+s]() { return 0; }, set [""](v) { }, get [0]() { return 0; }, set [a](v) { }, get [<any>true]() { return 0; }, set [`hello bye`](v) { }, get [`hello ${a} bye`]() { return 0; }} : { [x: string]: any; [x: number]: any; [""]: any; readonly [0]: number; }
12+
>v : { [x: string]: any; [x: number]: any; [""]: any; readonly [0]: number; [`hello bye`]: any; }
13+
>{ get [s]() { return 0; }, set [n](v) { }, get [s + s]() { return 0; }, set [s + n](v) { }, get [+s]() { return 0; }, set [""](v) { }, get [0]() { return 0; }, set [a](v) { }, get [<any>true]() { return 0; }, set [`hello bye`](v) { }, get [`hello ${a} bye`]() { return 0; }} : { [x: string]: any; [x: number]: any; [""]: any; readonly [0]: number; [`hello bye`]: any; }
1414

1515
get [s]() { return 0; },
1616
>[s] : number

tests/baselines/reference/computedPropertyNames11_ES6.types

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ var a: any;
99
>a : any
1010

1111
var v = {
12-
>v : { [x: string]: any; [x: number]: any; [""]: any; readonly [0]: number; }
13-
>{ get [s]() { return 0; }, set [n](v) { }, get [s + s]() { return 0; }, set [s + n](v) { }, get [+s]() { return 0; }, set [""](v) { }, get [0]() { return 0; }, set [a](v) { }, get [<any>true]() { return 0; }, set [`hello bye`](v) { }, get [`hello ${a} bye`]() { return 0; }} : { [x: string]: any; [x: number]: any; [""]: any; readonly [0]: number; }
12+
>v : { [x: string]: any; [x: number]: any; [""]: any; readonly [0]: number; [`hello bye`]: any; }
13+
>{ get [s]() { return 0; }, set [n](v) { }, get [s + s]() { return 0; }, set [s + n](v) { }, get [+s]() { return 0; }, set [""](v) { }, get [0]() { return 0; }, set [a](v) { }, get [<any>true]() { return 0; }, set [`hello bye`](v) { }, get [`hello ${a} bye`]() { return 0; }} : { [x: string]: any; [x: number]: any; [""]: any; readonly [0]: number; [`hello bye`]: any; }
1414

1515
get [s]() { return 0; },
1616
>[s] : number

tests/baselines/reference/computedPropertyNames12_ES5.errors.txt

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,10 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES5.ts(8,
55
tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES5.ts(9,5): error TS1166: A computed property name in a class property declaration must refer to an expression whose type is a literal type or a 'unique symbol' type.
66
tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES5.ts(12,5): error TS1166: A computed property name in a class property declaration must refer to an expression whose type is a literal type or a 'unique symbol' type.
77
tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES5.ts(13,12): error TS1166: A computed property name in a class property declaration must refer to an expression whose type is a literal type or a 'unique symbol' type.
8-
tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES5.ts(14,5): error TS1166: A computed property name in a class property declaration must refer to an expression whose type is a literal type or a 'unique symbol' type.
98
tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES5.ts(15,12): error TS1166: A computed property name in a class property declaration must refer to an expression whose type is a literal type or a 'unique symbol' type.
109

1110

12-
==== tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES5.ts (9 errors) ====
11+
==== tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES5.ts (8 errors) ====
1312
var s: string;
1413
var n: number;
1514
var a: any;
@@ -38,8 +37,6 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES5.ts(15
3837
~~~~~~~~~~~
3938
!!! error TS1166: A computed property name in a class property declaration must refer to an expression whose type is a literal type or a 'unique symbol' type.
4039
[`hello bye`] = 0;
41-
~~~~~~~~~~~~~
42-
!!! error TS1166: A computed property name in a class property declaration must refer to an expression whose type is a literal type or a 'unique symbol' type.
4340
static [`hello ${a} bye`] = 0
4441
~~~~~~~~~~~~~~~~~~
4542
!!! error TS1166: A computed property name in a class property declaration must refer to an expression whose type is a literal type or a 'unique symbol' type.

tests/baselines/reference/computedPropertyNames12_ES6.errors.txt

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,10 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES6.ts(8,
55
tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES6.ts(9,5): error TS1166: A computed property name in a class property declaration must refer to an expression whose type is a literal type or a 'unique symbol' type.
66
tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES6.ts(12,5): error TS1166: A computed property name in a class property declaration must refer to an expression whose type is a literal type or a 'unique symbol' type.
77
tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES6.ts(13,12): error TS1166: A computed property name in a class property declaration must refer to an expression whose type is a literal type or a 'unique symbol' type.
8-
tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES6.ts(14,5): error TS1166: A computed property name in a class property declaration must refer to an expression whose type is a literal type or a 'unique symbol' type.
98
tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES6.ts(15,12): error TS1166: A computed property name in a class property declaration must refer to an expression whose type is a literal type or a 'unique symbol' type.
109

1110

12-
==== tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES6.ts (9 errors) ====
11+
==== tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES6.ts (8 errors) ====
1312
var s: string;
1413
var n: number;
1514
var a: any;
@@ -38,8 +37,6 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES6.ts(15
3837
~~~~~~~~~~~
3938
!!! error TS1166: A computed property name in a class property declaration must refer to an expression whose type is a literal type or a 'unique symbol' type.
4039
[`hello bye`] = 0;
41-
~~~~~~~~~~~~~
42-
!!! error TS1166: A computed property name in a class property declaration must refer to an expression whose type is a literal type or a 'unique symbol' type.
4340
static [`hello ${a} bye`] = 0
4441
~~~~~~~~~~~~~~~~~~
4542
!!! error TS1166: A computed property name in a class property declaration must refer to an expression whose type is a literal type or a 'unique symbol' type.

tests/baselines/reference/computerPropertiesInES5ShouldBeTransformed.types

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
=== tests/cases/compiler/computerPropertiesInES5ShouldBeTransformed.ts ===
22
const b = ({ [`key`]: renamed }) => renamed;
3-
>b : ({ [`key`]: renamed }: {}) => any
4-
>({ [`key`]: renamed }) => renamed : ({ [`key`]: renamed }: {}) => any
3+
>b : ({ [`key`]: renamed }: { key: any; }) => any
4+
>({ [`key`]: renamed }) => renamed : ({ [`key`]: renamed }: { key: any; }) => any
55
>`key` : "key"
66
>renamed : any
77
>renamed : any

0 commit comments

Comments
 (0)