Skip to content

Commit bbb5faf

Browse files
TypeScript Botnavya9singh
TypeScript Bot
andauthored
🤖 Pick PR #59542 (Fixing delay caused in vscode due t...) into release-5.6 (#59695)
Co-authored-by: navya9singh <[email protected]>
1 parent e6914a5 commit bbb5faf

29 files changed

+3260
-49
lines changed

‎src/services/pasteEdits.ts

+49-12
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,17 @@ import {
33
codefix,
44
Debug,
55
fileShouldUseJavaScriptRequire,
6+
findAncestor,
67
findIndex,
78
forEachChild,
89
formatting,
10+
getNewLineOrDefaultFromHost,
911
getQuotePreference,
12+
getTokenAtPosition,
1013
isIdentifier,
1114
Program,
15+
rangeContainsPosition,
16+
rangeContainsRange,
1217
SourceFile,
1318
Statement,
1419
SymbolFlags,
@@ -56,17 +61,16 @@ function pasteEdits(
5661
cancellationToken: CancellationToken,
5762
changes: textChanges.ChangeTracker,
5863
) {
59-
let actualPastedText: string[] | undefined;
64+
let actualPastedText: string | undefined;
6065
if (pastedText.length !== pasteLocations.length) {
61-
actualPastedText = pastedText.length === 1 ? pastedText : [pastedText.join("\n")];
66+
actualPastedText = pastedText.length === 1 ? pastedText[0] : pastedText.join(getNewLineOrDefaultFromHost(formatContext.host, formatContext.options));
6267
}
6368

6469
const statements: Statement[] = [];
65-
6670
let newText = targetFile.text;
6771
for (let i = pasteLocations.length - 1; i >= 0; i--) {
6872
const { pos, end } = pasteLocations[i];
69-
newText = actualPastedText ? newText.slice(0, pos) + actualPastedText[0] + newText.slice(end) : newText.slice(0, pos) + pastedText[i] + newText.slice(end);
73+
newText = actualPastedText ? newText.slice(0, pos) + actualPastedText + newText.slice(end) : newText.slice(0, pos) + pastedText[i] + newText.slice(end);
7074
}
7175

7276
let importAdder: codefix.ImportAdder;
@@ -104,12 +108,46 @@ function pasteEdits(
104108
preferences,
105109
formatContext,
106110
};
107-
forEachChild(updatedFile, function cb(node) {
108-
if (isIdentifier(node) && !originalProgram?.getTypeChecker().resolveName(node.text, node, SymbolFlags.All, /*excludeGlobals*/ false)) {
109-
// generate imports
110-
importAdder.addImportForUnresolvedIdentifier(context, node, /*useAutoImportProvider*/ true);
111-
}
112-
node.forEachChild(cb);
111+
112+
// `updatedRanges` represent the new ranges that account for the offset changes caused by pasting new text and
113+
// `offset` represents by how much the starting position of `pasteLocations` needs to be changed.
114+
//
115+
// We iterate over each updated range to get the node that wholly encloses the updated range.
116+
// For each child of that node, we checked for unresolved identifiers
117+
// within the updated range and try importing it.
118+
let offset = 0;
119+
pasteLocations.forEach((location, i) => {
120+
const oldTextLength = location.end - location.pos;
121+
const textToBePasted = actualPastedText ?? pastedText[i];
122+
const startPos = location.pos + offset;
123+
const endPos = startPos + textToBePasted.length;
124+
const range: TextRange = { pos: startPos, end: endPos };
125+
offset += textToBePasted.length - oldTextLength;
126+
127+
const enclosingNode = findAncestor(
128+
getTokenAtPosition(context.sourceFile, range.pos),
129+
ancestorNode => rangeContainsRange(ancestorNode, range),
130+
);
131+
if (!enclosingNode) return;
132+
133+
forEachChild(enclosingNode, function importUnresolvedIdentifiers(node) {
134+
const isImportCandidate = isIdentifier(node) &&
135+
rangeContainsPosition(range, node.getStart(updatedFile)) &&
136+
!updatedProgram?.getTypeChecker().resolveName(
137+
node.text,
138+
node,
139+
SymbolFlags.All,
140+
/*excludeGlobals*/ false,
141+
);
142+
if (isImportCandidate) {
143+
return importAdder.addImportForUnresolvedIdentifier(
144+
context,
145+
node,
146+
/*useAutoImportProvider*/ true,
147+
);
148+
}
149+
node.forEachChild(importUnresolvedIdentifiers);
150+
});
113151
});
114152
}
115153
importAdder.writeFixes(changes, getQuotePreference(copiedFrom ? copiedFrom.file : targetFile, preferences));
@@ -125,8 +163,7 @@ function pasteEdits(
125163
changes.replaceRangeWithText(
126164
targetFile,
127165
{ pos: paste.pos, end: paste.end },
128-
actualPastedText ?
129-
actualPastedText[0] : pastedText[i],
166+
actualPastedText ?? pastedText[i],
130167
);
131168
});
132169
}

0 commit comments

Comments
 (0)