Skip to content

Commit 55153b0

Browse files
authored
feat(57028): Support inlining variables that are used in object literal shorthand (#57051)
1 parent 6add96f commit 55153b0

File tree

2 files changed

+27
-5
lines changed

2 files changed

+27
-5
lines changed

src/services/refactors/inlineVariable.ts

+14-5
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import {
2323
isNumericLiteral,
2424
isObjectLiteralExpression,
2525
isPropertyAccessExpression,
26+
isShorthandPropertyAssignment,
2627
isTypeQueryNode,
2728
isVariableDeclarationInVariableStatement,
2829
isVariableStatement,
@@ -102,7 +103,6 @@ registerRefactor(refactorName, {
102103

103104
getEditsForAction(context, actionName) {
104105
Debug.assert(actionName === refactorName, "Unexpected refactor invoked");
105-
106106
const { file, program, startPosition } = context;
107107

108108
// tryWithReferenceToken is true below since here we're already performing the refactor.
@@ -189,9 +189,10 @@ function isDeclarationExported(declaration: InitializedVariableDeclaration): boo
189189
function getReferenceNodes(declaration: InitializedVariableDeclaration, checker: TypeChecker, file: SourceFile): Identifier[] | undefined {
190190
const references: Identifier[] = [];
191191
const cannotInline = FindAllReferences.Core.eachSymbolReferenceInFile(declaration.name as Identifier, checker, file, ref => {
192-
// Only inline if all references are reads. Else we might end up with an invalid scenario like:
193-
// const y = x++ + 1 -> const y = 2++ + 1
194-
if (FindAllReferences.isWriteAccessForReference(ref)) {
192+
// Only inline if all references are reads, or if it includes a shorthand property assignment.
193+
// Else we might end up with an invalid scenario like:
194+
// const y = x++ + 1 -> const y = 2++ + 1,
195+
if (FindAllReferences.isWriteAccessForReference(ref) && !isShorthandPropertyAssignment(ref.parent)) {
195196
return true;
196197
}
197198

@@ -216,7 +217,7 @@ function getReferenceNodes(declaration: InitializedVariableDeclaration, checker:
216217
return references.length === 0 || cannotInline ? undefined : references;
217218
}
218219

219-
function getReplacementExpression(reference: Node, replacement: Expression): Expression {
220+
function getReplacementExpression(reference: Node, replacement: Expression) {
220221
// Make sure each reference site gets its own copy of the replacement node.
221222
replacement = getSynthesizedDeepClone(replacement);
222223
const { parent } = reference;
@@ -244,5 +245,13 @@ function getReplacementExpression(reference: Node, replacement: Expression): Exp
244245
return factory.createParenthesizedExpression(replacement);
245246
}
246247

248+
// Inline shorthand property assignment
249+
// E.g.:
250+
// const x = 1;
251+
// const y = { x }; -> const y = { x: 1 };
252+
if (isIdentifier(reference) && isShorthandPropertyAssignment(parent)) {
253+
return factory.createPropertyAssignment(reference, replacement);
254+
}
255+
247256
return replacement;
248257
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/// <reference path="fourslash.ts" />
2+
3+
////const foo = 1;
4+
////const bar = { /*a*/foo/*b*/ };
5+
6+
goTo.select("a", "b");
7+
edit.applyRefactor({
8+
refactorName: "Inline variable",
9+
actionName: "Inline variable",
10+
actionDescription: "Inline variable",
11+
newContent: "const bar = { foo: 1 };",
12+
triggerReason: "invoked",
13+
});

0 commit comments

Comments
 (0)