diff --git a/src/services/refactors/inlineVariable.ts b/src/services/refactors/inlineVariable.ts
index 2b0b43bf426..7595387b3e8 100644
--- a/src/services/refactors/inlineVariable.ts
+++ b/src/services/refactors/inlineVariable.ts
@@ -20,6 +20,9 @@ import {
isFunctionLike,
isIdentifier,
isInitializedVariable,
+ isNumericLiteral,
+ isObjectLiteralExpression,
+ isPropertyAccessExpression,
isTypeQueryNode,
isVariableDeclarationInVariableStatement,
isVariableStatement,
@@ -228,7 +231,13 @@ function getReplacementExpression(reference: Node, replacement: Expression): Exp
// Functions also need to be parenthesized.
// E.g.: const f = () => {}; f(); -> (() => {})();
- if (isFunctionLike(replacement) && isCallLikeExpression(parent)) {
+ if (isFunctionLike(replacement) && (isCallLikeExpression(parent) || isPropertyAccessExpression(parent))) {
+ return factory.createParenthesizedExpression(replacement);
+ }
+
+ // Property access of numeric literals and objects need parentheses.
+ // E.g.: const x = 1; x.toString(); -> (1).toString();
+ if (isPropertyAccessExpression(parent) && (isNumericLiteral(replacement) || isObjectLiteralExpression(replacement))) {
return factory.createParenthesizedExpression(replacement);
}
diff --git a/tests/cases/fourslash/inlineVariableNoParensPropertyAccess.ts b/tests/cases/fourslash/inlineVariableNoParensPropertyAccess.ts
new file mode 100644
index 00000000000..f4b2cc56817
--- /dev/null
+++ b/tests/cases/fourslash/inlineVariableNoParensPropertyAccess.ts
@@ -0,0 +1,27 @@
+///
+
+////const /*a1*/foo/*b1*/ = "foo";
+////console.log(foo.length);
+////const /*a2*/notTrue/*b2*/ = false;
+////notTrue.valueOf();
+
+goTo.select("a1", "b1");
+verify.refactorAvailable("Inline variable");
+edit.applyRefactor({
+ refactorName: "Inline variable",
+ actionName: "Inline variable",
+ actionDescription: "Inline variable",
+ newContent: `console.log("foo".length);
+const notTrue = false;
+notTrue.valueOf();`
+});
+
+goTo.select("a2", "b2");
+verify.refactorAvailable("Inline variable");
+edit.applyRefactor({
+ refactorName: "Inline variable",
+ actionName: "Inline variable",
+ actionDescription: "Inline variable",
+ newContent: `console.log("foo".length);
+false.valueOf();`
+});
diff --git a/tests/cases/fourslash/inlineVariableParensBinExpression.ts b/tests/cases/fourslash/inlineVariableParensBinExpression.ts
new file mode 100644
index 00000000000..a83d34a7630
--- /dev/null
+++ b/tests/cases/fourslash/inlineVariableParensBinExpression.ts
@@ -0,0 +1,13 @@
+///
+
+////const /*a*/x/*b*/ = 1 + 2;
+////const y = x * 3;
+
+goTo.select("a", "b");
+verify.refactorAvailable("Inline variable");
+edit.applyRefactor({
+ refactorName: "Inline variable",
+ actionName: "Inline variable",
+ actionDescription: "Inline variable",
+ newContent: "const y = (1 + 2) * 3;"
+});
\ No newline at end of file
diff --git a/tests/cases/fourslash/inlineVariableNeedsParens.ts b/tests/cases/fourslash/inlineVariableParensFunctions.ts
similarity index 62%
rename from tests/cases/fourslash/inlineVariableNeedsParens.ts
rename to tests/cases/fourslash/inlineVariableParensFunctions.ts
index 6d4edfa1288..5b85e64b61a 100644
--- a/tests/cases/fourslash/inlineVariableNeedsParens.ts
+++ b/tests/cases/fourslash/inlineVariableParensFunctions.ts
@@ -1,9 +1,9 @@
///
-////const /*a1*/x/*b1*/ = 1 + 2;
-////const y = x * 3;
-////const /*a2*/f/*b2*/ = () => { };
-////f();
+////const /*a1*/foo/*b1*/ = () => { };
+////foo();
+////const /*a2*/bar/*b2*/ = function() { };
+////bar.call(null);
goTo.select("a1", "b1");
verify.refactorAvailable("Inline variable");
@@ -11,9 +11,9 @@ edit.applyRefactor({
refactorName: "Inline variable",
actionName: "Inline variable",
actionDescription: "Inline variable",
- newContent: `const y = (1 + 2) * 3;
-const f = () => { };
-f();`
+ newContent: `(() => { })();
+const bar = function() { };
+bar.call(null);`
});
goTo.select("a2", "b2");
@@ -22,6 +22,6 @@ edit.applyRefactor({
refactorName: "Inline variable",
actionName: "Inline variable",
actionDescription: "Inline variable",
- newContent: `const y = (1 + 2) * 3;
-(() => { })();`
+ newContent: `(() => { })();
+(function() { }).call(null);`
});
\ No newline at end of file
diff --git a/tests/cases/fourslash/inlineVariableParensNewExpression.ts b/tests/cases/fourslash/inlineVariableParensNewExpression.ts
new file mode 100644
index 00000000000..4c63051c6a2
--- /dev/null
+++ b/tests/cases/fourslash/inlineVariableParensNewExpression.ts
@@ -0,0 +1,23 @@
+///
+
+// @Filename: /a.ts
+////export function foo() {
+//// class Foo { function bar() { } }
+//// return Foo;
+////}
+
+// @Filename: /b.ts
+////import * as a from "./a";
+////const /*a*/foo/*b*/ = a.foo();
+////new foo.bar();
+
+goTo.file("/b.ts");
+goTo.select("a", "b");
+verify.refactorAvailable("Inline variable");
+edit.applyRefactor({
+ refactorName: "Inline variable",
+ actionName: "Inline variable",
+ actionDescription: "Inline variable",
+ newContent: `import * as a from "./a";
+new (a.foo()).bar();`
+});
diff --git a/tests/cases/fourslash/inlineVariableParensPropertyAccess.ts b/tests/cases/fourslash/inlineVariableParensPropertyAccess.ts
new file mode 100644
index 00000000000..e8e53c502d5
--- /dev/null
+++ b/tests/cases/fourslash/inlineVariableParensPropertyAccess.ts
@@ -0,0 +1,44 @@
+///
+
+////const /*a1*/foo/*b1*/ = {};
+////foo.toString();
+////const /*a2*/bar/*b2*/ = 0;
+////bar.toFixed().toString();
+////const /*a3*/pi/*b3*/ = 3.1416;
+////pi.toPrecision(2);
+
+goTo.select("a1", "b1");
+verify.refactorAvailable("Inline variable");
+edit.applyRefactor({
+ refactorName: "Inline variable",
+ actionName: "Inline variable",
+ actionDescription: "Inline variable",
+ newContent: `({}).toString();
+const bar = 0;
+bar.toFixed().toString();
+const pi = 3.1416;
+pi.toPrecision(2);`
+});
+
+goTo.select("a2", "b2");
+verify.refactorAvailable("Inline variable");
+edit.applyRefactor({
+ refactorName: "Inline variable",
+ actionName: "Inline variable",
+ actionDescription: "Inline variable",
+ newContent: `({}).toString();
+(0).toFixed().toString();
+const pi = 3.1416;
+pi.toPrecision(2);`
+});
+
+goTo.select("a3", "b3");
+verify.refactorAvailable("Inline variable");
+edit.applyRefactor({
+ refactorName: "Inline variable",
+ actionName: "Inline variable",
+ actionDescription: "Inline variable",
+ newContent: `({}).toString();
+(0).toFixed().toString();
+(3.1416).toPrecision(2);`
+});