Skip to content

Commit 38575dc

Browse files
authored
Fix missing parentheses in inline variable (#54737)
1 parent f762de5 commit 38575dc

File tree

6 files changed

+126
-10
lines changed

6 files changed

+126
-10
lines changed

src/services/refactors/inlineVariable.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ import {
2020
isFunctionLike,
2121
isIdentifier,
2222
isInitializedVariable,
23+
isNumericLiteral,
24+
isObjectLiteralExpression,
25+
isPropertyAccessExpression,
2326
isTypeQueryNode,
2427
isVariableDeclarationInVariableStatement,
2528
isVariableStatement,
@@ -228,7 +231,13 @@ function getReplacementExpression(reference: Node, replacement: Expression): Exp
228231

229232
// Functions also need to be parenthesized.
230233
// E.g.: const f = () => {}; f(); -> (() => {})();
231-
if (isFunctionLike(replacement) && isCallLikeExpression(parent)) {
234+
if (isFunctionLike(replacement) && (isCallLikeExpression(parent) || isPropertyAccessExpression(parent))) {
235+
return factory.createParenthesizedExpression(replacement);
236+
}
237+
238+
// Property access of numeric literals and objects need parentheses.
239+
// E.g.: const x = 1; x.toString(); -> (1).toString();
240+
if (isPropertyAccessExpression(parent) && (isNumericLiteral(replacement) || isObjectLiteralExpression(replacement))) {
232241
return factory.createParenthesizedExpression(replacement);
233242
}
234243

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/// <reference path="fourslash.ts" />
2+
3+
////const /*a1*/foo/*b1*/ = "foo";
4+
////console.log(foo.length);
5+
////const /*a2*/notTrue/*b2*/ = false;
6+
////notTrue.valueOf();
7+
8+
goTo.select("a1", "b1");
9+
verify.refactorAvailable("Inline variable");
10+
edit.applyRefactor({
11+
refactorName: "Inline variable",
12+
actionName: "Inline variable",
13+
actionDescription: "Inline variable",
14+
newContent: `console.log("foo".length);
15+
const notTrue = false;
16+
notTrue.valueOf();`
17+
});
18+
19+
goTo.select("a2", "b2");
20+
verify.refactorAvailable("Inline variable");
21+
edit.applyRefactor({
22+
refactorName: "Inline variable",
23+
actionName: "Inline variable",
24+
actionDescription: "Inline variable",
25+
newContent: `console.log("foo".length);
26+
false.valueOf();`
27+
});
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/// <reference path="fourslash.ts" />
2+
3+
////const /*a*/x/*b*/ = 1 + 2;
4+
////const y = x * 3;
5+
6+
goTo.select("a", "b");
7+
verify.refactorAvailable("Inline variable");
8+
edit.applyRefactor({
9+
refactorName: "Inline variable",
10+
actionName: "Inline variable",
11+
actionDescription: "Inline variable",
12+
newContent: "const y = (1 + 2) * 3;"
13+
});
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
/// <reference path="fourslash.ts" />
22

3-
////const /*a1*/x/*b1*/ = 1 + 2;
4-
////const y = x * 3;
5-
////const /*a2*/f/*b2*/ = () => { };
6-
////f();
3+
////const /*a1*/foo/*b1*/ = () => { };
4+
////foo();
5+
////const /*a2*/bar/*b2*/ = function() { };
6+
////bar.call(null);
77

88
goTo.select("a1", "b1");
99
verify.refactorAvailable("Inline variable");
1010
edit.applyRefactor({
1111
refactorName: "Inline variable",
1212
actionName: "Inline variable",
1313
actionDescription: "Inline variable",
14-
newContent: `const y = (1 + 2) * 3;
15-
const f = () => { };
16-
f();`
14+
newContent: `(() => { })();
15+
const bar = function() { };
16+
bar.call(null);`
1717
});
1818

1919
goTo.select("a2", "b2");
@@ -22,6 +22,6 @@ edit.applyRefactor({
2222
refactorName: "Inline variable",
2323
actionName: "Inline variable",
2424
actionDescription: "Inline variable",
25-
newContent: `const y = (1 + 2) * 3;
26-
(() => { })();`
25+
newContent: `(() => { })();
26+
(function() { }).call(null);`
2727
});
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/// <reference path="fourslash.ts" />
2+
3+
// @Filename: /a.ts
4+
////export function foo() {
5+
//// class Foo { function bar() { } }
6+
//// return Foo;
7+
////}
8+
9+
// @Filename: /b.ts
10+
////import * as a from "./a";
11+
////const /*a*/foo/*b*/ = a.foo();
12+
////new foo.bar();
13+
14+
goTo.file("/b.ts");
15+
goTo.select("a", "b");
16+
verify.refactorAvailable("Inline variable");
17+
edit.applyRefactor({
18+
refactorName: "Inline variable",
19+
actionName: "Inline variable",
20+
actionDescription: "Inline variable",
21+
newContent: `import * as a from "./a";
22+
new (a.foo()).bar();`
23+
});
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/// <reference path="fourslash.ts" />
2+
3+
////const /*a1*/foo/*b1*/ = {};
4+
////foo.toString();
5+
////const /*a2*/bar/*b2*/ = 0;
6+
////bar.toFixed().toString();
7+
////const /*a3*/pi/*b3*/ = 3.1416;
8+
////pi.toPrecision(2);
9+
10+
goTo.select("a1", "b1");
11+
verify.refactorAvailable("Inline variable");
12+
edit.applyRefactor({
13+
refactorName: "Inline variable",
14+
actionName: "Inline variable",
15+
actionDescription: "Inline variable",
16+
newContent: `({}).toString();
17+
const bar = 0;
18+
bar.toFixed().toString();
19+
const pi = 3.1416;
20+
pi.toPrecision(2);`
21+
});
22+
23+
goTo.select("a2", "b2");
24+
verify.refactorAvailable("Inline variable");
25+
edit.applyRefactor({
26+
refactorName: "Inline variable",
27+
actionName: "Inline variable",
28+
actionDescription: "Inline variable",
29+
newContent: `({}).toString();
30+
(0).toFixed().toString();
31+
const pi = 3.1416;
32+
pi.toPrecision(2);`
33+
});
34+
35+
goTo.select("a3", "b3");
36+
verify.refactorAvailable("Inline variable");
37+
edit.applyRefactor({
38+
refactorName: "Inline variable",
39+
actionName: "Inline variable",
40+
actionDescription: "Inline variable",
41+
newContent: `({}).toString();
42+
(0).toFixed().toString();
43+
(3.1416).toPrecision(2);`
44+
});

0 commit comments

Comments
 (0)