Skip to content

Commit 2a15acb

Browse files
committed
refactor creation of template expression
1 parent 29fc8c3 commit 2a15acb

File tree

34 files changed

+54
-29
lines changed

34 files changed

+54
-29
lines changed

src/services/refactors/convertStringOrTemplateLiteral.ts

Lines changed: 21 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,21 @@ namespace ts.refactor.convertStringOrTemplateLiteral {
1414
const { file, startPosition } = context;
1515
const node = getNodeOrParentOfParentheses(file, startPosition);
1616
const maybeBinary = getParentBinaryExpression(node);
17-
const actions: RefactorActionInfo[] = [];
17+
const refactorInfo: ApplicableRefactorInfo = { name: refactorName, description: refactorDescription, actions: [] };
1818

1919
if ((isBinaryExpression(maybeBinary) || isStringLiteral(maybeBinary)) && isStringConcatenationValid(maybeBinary)) {
20-
actions.push({ name: toTemplateLiteralActionName, description: toTemplateLiteralDescription });
20+
refactorInfo.actions.push({ name: toTemplateLiteralActionName, description: toTemplateLiteralDescription });
21+
return [refactorInfo];
2122
}
2223

2324
const templateLiteral = findAncestor(node, n => isTemplateLiteral(n));
2425

2526
if (templateLiteral && !isTaggedTemplateExpression(templateLiteral.parent)) {
26-
actions.push({ name: toStringConcatenationActionName, description: toStringConcatenationDescription });
27+
refactorInfo.actions.push({ name: toStringConcatenationActionName, description: toStringConcatenationDescription });
28+
return [refactorInfo];
2729
}
2830

29-
return [{ name: refactorName, description: refactorDescription, actions }];
31+
return emptyArray;
3032
}
3133

3234
function getNodeOrParentOfParentheses(file: SourceFile, startPosition: number) {
@@ -137,46 +139,35 @@ namespace ts.refactor.convertStringOrTemplateLiteral {
137139
return { nodes: [node as Expression], containsString: isStringLiteral(node), areOperatorsValid: true };
138140
}
139141

140-
function createHead(nodes: ReadonlyArray<Expression>): [number, TemplateHead] {
141-
let begin = 0;
142+
function concatConsecutiveString(index: number, nodes: ReadonlyArray<Expression>): [number, string] {
142143
let text = "";
143144

144-
while (begin < nodes.length && isStringLiteral(nodes[begin])) {
145-
const next = nodes[begin] as StringLiteral;
146-
text = text + decodeRawString(next.getText());
147-
begin++;
145+
while (index < nodes.length && isStringLiteral(nodes[index])) {
146+
text = text + decodeRawString(nodes[index].getText());
147+
index++;
148148
}
149149

150150
text = escapeText(text);
151-
return [begin, createTemplateHead(text)];
151+
return [index, text];
152152
}
153153

154154
function nodesToTemplate(nodes: ReadonlyArray<Expression>) {
155155
const templateSpans: TemplateSpan[] = [];
156-
const [begin, head] = createHead(nodes);
156+
const [begin, headText] = concatConsecutiveString(0, nodes);
157+
const templateHead = createTemplateHead(headText);
157158

158-
if (begin === nodes.length) {
159-
return createNoSubstitutionTemplateLiteral(head.text);
160-
}
159+
if (begin === nodes.length) return createNoSubstitutionTemplateLiteral(headText);
161160

162161
for (let i = begin; i < nodes.length; i++) {
163-
let current = nodes[i];
164-
let text = "";
165-
166-
while (i + 1 < nodes.length && isStringLiteral(nodes[i + 1])) {
167-
const next = nodes[i + 1] as StringLiteral;
168-
text = text + decodeRawString(next.getText());
169-
i++;
170-
}
162+
const expression = isParenthesizedExpression(nodes[i]) ? (nodes[i] as ParenthesizedExpression).expression : nodes[i];
163+
const [newIndex, subsequentText] = concatConsecutiveString(i + 1, nodes);
164+
i = newIndex - 1;
171165

172-
text = escapeText(text);
173-
const templatePart = i === nodes.length - 1 ? createTemplateTail(text) : createTemplateMiddle(text);
174-
175-
if (isParenthesizedExpression(current)) current = current.expression;
176-
templateSpans.push(createTemplateSpan(current, templatePart));
166+
const templatePart = i === nodes.length - 1 ? createTemplateTail(subsequentText) : createTemplateMiddle(subsequentText);
167+
templateSpans.push(createTemplateSpan(expression, templatePart));
177168
}
178169

179-
return createTemplateExpression(head, templateSpans);
170+
return createTemplateExpression(templateHead, templateSpans);
180171
}
181172

182173
const octalToUnicode = (_match: string, grp: string) => String.fromCharCode(parseInt(grp, 8));
@@ -196,3 +187,4 @@ namespace ts.refactor.convertStringOrTemplateLiteral {
196187
}
197188

198189
}
190+

tests/cases/fourslash/refactorConvertStringOrTemplateLiteral_ToStringAsFnArgument.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ edit.applyRefactor({
1010
newContent:
1111
`console.log("foobar is " + 32 + " years old")`,
1212
});
13+

tests/cases/fourslash/refactorConvertStringOrTemplateLiteral_ToStringAvailability.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,4 @@ verify.not.refactorAvailable("Convert string concatenation or template literal",
2727
goTo.select("p", "o");
2828
verify.refactorAvailable("Convert string concatenation or template literal", "Convert to string concatenation");
2929
verify.not.refactorAvailable("Convert string concatenation or template literal", "Convert to template literal");
30+

tests/cases/fourslash/refactorConvertStringOrTemplateLiteral_ToStringAvailabilityTagged.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,4 @@ verify.not.refactorAvailable("Convert string concatenation or template literal",
1515
goTo.select("v", "u");
1616
verify.not.refactorAvailable("Convert string concatenation or template literal", "Convert to string concatenation");
1717
verify.not.refactorAvailable("Convert string concatenation or template literal", "Convert to template literal");
18+

tests/cases/fourslash/refactorConvertStringOrTemplateLiteral_ToStringBinaryExpr.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ edit.applyRefactor({
1010
newContent:
1111
`const foo = "foobar is " + (42 + 6) + " years old"`,
1212
});
13+

tests/cases/fourslash/refactorConvertStringOrTemplateLiteral_ToStringMultiExpr.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@ edit.applyRefactor({
1414
const name = "Eddy"
1515
const foo = name + " is " + age + " years old"`,
1616
});
17+

tests/cases/fourslash/refactorConvertStringOrTemplateLiteral_ToStringNestedInner.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ edit.applyRefactor({
1212
`const age = 42
1313
const foo = \`foobar is a \${ age < 18 ? 'child' : "grown-up " + (age > 40 ? 'who needs probably assistance' : '') }\``,
1414
});
15+

tests/cases/fourslash/refactorConvertStringOrTemplateLiteral_ToStringNestedInnerNonSub.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ edit.applyRefactor({
1212
`const age = 42
1313
const foo = \`foobar is a \${ "34" }\``,
1414
});
15+

tests/cases/fourslash/refactorConvertStringOrTemplateLiteral_ToStringNestedOuter.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ edit.applyRefactor({
1212
`const age = 42
1313
const foo = "foobar is a " + (age < 18 ? 'child' : \`grown-up \${age > 40 ? 'who needs probaply assistance' : ''}\`)`,
1414
});
15+

tests/cases/fourslash/refactorConvertStringOrTemplateLiteral_ToStringOneExpr.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ edit.applyRefactor({
1212
`const age = 42
1313
const foo = "foobar is " + age + " years old"`,
1414
});
15+

0 commit comments

Comments
 (0)