Fix missing parentheses in inline variable (#54737)

This commit is contained in:
Maria José Solano 2023-06-26 14:08:59 -07:00 committed by GitHub
parent f762de5220
commit 38575dc015
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 144 additions and 28 deletions

View File

@ -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);
}

View File

@ -1,27 +1,27 @@
/// <reference path="fourslash.ts" />
////const /*a1*/x/*b1*/ = 1 + 2;
////const y = x * 3;
////const /*a2*/f/*b2*/ = () => { };
////f();
goTo.select("a1", "b1");
verify.refactorAvailable("Inline variable");
edit.applyRefactor({
refactorName: "Inline variable",
actionName: "Inline variable",
actionDescription: "Inline variable",
newContent: `const y = (1 + 2) * 3;
const f = () => { };
f();`
});
goTo.select("a2", "b2");
verify.refactorAvailable("Inline variable");
edit.applyRefactor({
refactorName: "Inline variable",
actionName: "Inline variable",
actionDescription: "Inline variable",
newContent: `const y = (1 + 2) * 3;
(() => { })();`
});
/// <reference path="fourslash.ts" />
////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();`
});

View File

@ -0,0 +1,13 @@
/// <reference path="fourslash.ts" />
////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;"
});

View File

@ -0,0 +1,27 @@
/// <reference path="fourslash.ts" />
////const /*a1*/foo/*b1*/ = () => { };
////foo();
////const /*a2*/bar/*b2*/ = function() { };
////bar.call(null);
goTo.select("a1", "b1");
verify.refactorAvailable("Inline variable");
edit.applyRefactor({
refactorName: "Inline variable",
actionName: "Inline variable",
actionDescription: "Inline variable",
newContent: `(() => { })();
const bar = function() { };
bar.call(null);`
});
goTo.select("a2", "b2");
verify.refactorAvailable("Inline variable");
edit.applyRefactor({
refactorName: "Inline variable",
actionName: "Inline variable",
actionDescription: "Inline variable",
newContent: `(() => { })();
(function() { }).call(null);`
});

View File

@ -0,0 +1,23 @@
/// <reference path="fourslash.ts" />
// @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();`
});

View File

@ -0,0 +1,44 @@
/// <reference path="fourslash.ts" />
////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);`
});