Skip to content

Commit 2b93227

Browse files
committed
Support template literals in rename and find all references
1 parent c604676 commit 2b93227

File tree

7 files changed

+75
-6
lines changed

7 files changed

+75
-6
lines changed

src/compiler/utilities.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3220,18 +3220,24 @@ namespace ts {
32203220
}
32213221

32223222
/**
3223-
* Strip off existed single quotes or double quotes from a given string
3223+
* Strip off existed surrounding single quotes, double quotes, or backticks from a given string
32243224
*
32253225
* @return non-quoted string
32263226
*/
32273227
export function stripQuotes(name: string) {
32283228
const length = name.length;
3229-
if (length >= 2 && name.charCodeAt(0) === name.charCodeAt(length - 1) && startsWithQuote(name)) {
3229+
if (length >= 2 && name.charCodeAt(0) === name.charCodeAt(length - 1) && isQuoteOrBacktick(name.charCodeAt(0))) {
32303230
return name.substring(1, length - 1);
32313231
}
32323232
return name;
32333233
}
32343234

3235+
function isQuoteOrBacktick(charCode: number) {
3236+
return charCode === CharacterCodes.singleQuote ||
3237+
charCode === CharacterCodes.doubleQuote ||
3238+
charCode === CharacterCodes.backtick;
3239+
}
3240+
32353241
export function startsWithQuote(name: string): boolean {
32363242
return isSingleOrDoubleQuote(name.charCodeAt(0));
32373243
}

src/services/findAllReferences.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -448,7 +448,7 @@ namespace ts.FindAllReferences {
448448
function getTextSpan(node: Node, sourceFile: SourceFile, endNode?: Node): TextSpan {
449449
let start = node.getStart(sourceFile);
450450
let end = (endNode || node).getEnd();
451-
if (node.kind === SyntaxKind.StringLiteral) {
451+
if (isStringLiteralLike(node)) {
452452
Debug.assert(endNode === undefined);
453453
start += 1;
454454
end -= 1;
@@ -1234,8 +1234,9 @@ namespace ts.FindAllReferences.Core {
12341234
case SyntaxKind.Identifier:
12351235
return (node as Identifier).text.length === searchSymbolName.length;
12361236

1237+
case SyntaxKind.NoSubstitutionTemplateLiteral:
12371238
case SyntaxKind.StringLiteral: {
1238-
const str = node as StringLiteral;
1239+
const str = node as StringLiteralLike;
12391240
return (isLiteralNameOfPropertyDeclarationOrIndexAccess(str) || isNameOfModuleDeclaration(node) || isExpressionOfExternalModuleImportEqualsDeclaration(node) || (isCallExpression(node.parent) && isBindableObjectDefinePropertyCall(node.parent) && node.parent.arguments[1] === node)) &&
12401241
str.text.length === searchSymbolName.length;
12411242
}

src/services/rename.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ namespace ts.Rename {
8181
function createTriggerSpanForNode(node: Node, sourceFile: SourceFile) {
8282
let start = node.getStart(sourceFile);
8383
let width = node.getWidth(sourceFile);
84-
if (node.kind === SyntaxKind.StringLiteral) {
84+
if (isStringLiteralLike(node)) {
8585
// Exclude the quotes
8686
start += 1;
8787
width -= 2;
@@ -93,6 +93,7 @@ namespace ts.Rename {
9393
switch (node.kind) {
9494
case SyntaxKind.Identifier:
9595
case SyntaxKind.StringLiteral:
96+
case SyntaxKind.NoSubstitutionTemplateLiteral:
9697
case SyntaxKind.ThisKeyword:
9798
return true;
9899
case SyntaxKind.NumericLiteral:

src/services/services.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2227,6 +2227,7 @@ namespace ts {
22272227
function getContainingObjectLiteralElementWorker(node: Node): ObjectLiteralElement | undefined {
22282228
switch (node.kind) {
22292229
case SyntaxKind.StringLiteral:
2230+
case SyntaxKind.NoSubstitutionTemplateLiteral:
22302231
case SyntaxKind.NumericLiteral:
22312232
if (node.parent.kind === SyntaxKind.ComputedPropertyName) {
22322233
return isObjectLiteralElement(node.parent.parent) ? node.parent.parent : undefined;

src/services/utilities.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ namespace ts {
267267
isFunctionLike(node.parent) && (<FunctionLikeDeclaration>node.parent).name === node;
268268
}
269269

270-
export function isLiteralNameOfPropertyDeclarationOrIndexAccess(node: StringLiteral | NumericLiteral): boolean {
270+
export function isLiteralNameOfPropertyDeclarationOrIndexAccess(node: StringLiteral | NumericLiteral | NoSubstitutionTemplateLiteral): boolean {
271271
switch (node.parent.kind) {
272272
case SyntaxKind.PropertyDeclaration:
273273
case SyntaxKind.PropertySignature:
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/// <reference path='fourslash.ts' />
2+
3+
// @Filename: a.ts
4+
////interface Obj {
5+
//// [|[`[|{| "contextRangeIndex": 0 |}num|]`]: number;|]
6+
//// [|['[|{| "contextRangeIndex": 2 |}bool|]']: boolean;|]
7+
////}
8+
////
9+
////let o: Obj = {
10+
//// [|[`[|{| "contextRangeIndex": 4 |}num|]`]: 0|],
11+
//// [|['[|{| "contextRangeIndex": 6 |}bool|]']: true|],
12+
////};
13+
////
14+
////o = {
15+
//// [|['[|{| "contextRangeIndex": 8 |}num|]']: 1|],
16+
//// [|[`[|{| "contextRangeIndex": 10 |}bool|]`]: false|],
17+
////};
18+
////
19+
////o.[|num|];
20+
////o['[|num|]'];
21+
////o["[|num|]"];
22+
////o[`[|num|]`];
23+
////
24+
////o.[|bool|];
25+
////o['[|bool|]'];
26+
////o["[|bool|]"];
27+
////o[`[|bool|]`];
28+
////
29+
////export { o };
30+
31+
// @allowJs: true
32+
// @Filename: b.js
33+
////import { o as obj } from './a';
34+
////
35+
////obj.[|num|];
36+
////obj[`[|num|]`];
37+
////
38+
////obj.[|bool|];
39+
////obj[`[|bool|]`];
40+
41+
verify.rangesWithSameTextAreRenameLocations("num");
42+
verify.rangesWithSameTextAreRenameLocations("bool");
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/// <reference path='fourslash.ts' />
2+
3+
// @allowJs: true
4+
// @Filename: a.js
5+
////let obj = {};
6+
////
7+
////Object.defineProperty(obj, `[|prop|]`, { value: 0 });
8+
////
9+
////obj = {
10+
//// [|[`[|{| "contextRangeIndex": 1 |}prop|]`]: 1|]
11+
////};
12+
////
13+
////obj.[|prop|];
14+
////obj['[|prop|]'];
15+
////obj["[|prop|]"];
16+
////obj[`[|prop|]`];
17+
18+
verify.rangesWithSameTextAreRenameLocations('prop');

0 commit comments

Comments
 (0)