8000 Paste without imports (#59093) · yeonjuan/TypeScript@7bd7dfc · GitHub
[go: up one dir, main page]

Skip to content

Commit 7bd7dfc

Browse files
authored
Paste without imports (microsoft#59093)
1 parent 9623893 commit 7bd7dfc

File tree

4 files changed

+346
-6
lines changed

4 files changed

+346
-6
lines changed

src/services/pasteEdits.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ function pasteEdits(
9090
}
9191
statements.push(...statementsInSourceFile.slice(startNodeIndex, endNodeIndex === -1 ? statementsInSourceFile.length : endNodeIndex + 1));
9292
});
93-
const usage = getUsageInfo(copiedFrom.file, statements, originalProgram!.getTypeChecker(), getExistingLocals(updatedFile, statements, originalProgram!.getTypeChecker()));
93+
const usage = getUsageInfo(copiedFrom.file, statements, originalProgram!.getTypeChecker(), getExistingLocals(updatedFile, statements, originalProgram!.getTypeChecker()), { pos: copiedFrom.range[0].pos, end: copiedFrom.range[copiedFrom.range.length - 1].end });
9494
Debug.assertIsDefined(originalProgram);
9595
const useEsModuleSyntax = !fileShouldUseJavaScriptRequire(targetFile.fileName, originalProgram, host, !!copiedFrom.file.commonJsModuleIndicator);
9696
addExportsInOldFile(copiedFrom.file, usage.targetFileImportsFromOldFile, changes, useEsModuleSyntax);

src/services/refactors/moveToFile.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ import {
129129
PropertyAccessExpression,
130130
PropertyAssignment,
131131
QuotePreference,
132+
rangeContainsRange,
132133
RefactorContext,
133134
RefactorEditInfo,
134135
RequireOrImportCall,
@@ -145,6 +146,7 @@ import {
145146
SyntaxKind,
146147
takeWhile,
147148
textChanges,
149+
TextRange,
148150
TransformFlags,
149151
tryCast,
150152
TypeAliasDeclaration,
@@ -861,7 +863,7 @@ function isPureImport(node: Node): boolean {
861863
}
862864

863865
/** @internal */
864-
export function getUsageInfo(oldFile: SourceFile, toMove: readonly Statement[], checker: TypeChecker, existingTargetLocals: ReadonlySet<Symbol> = new Set()): UsageInfo {
866+
export function getUsageInfo(oldFile: SourceFile, toMove: readonly Statement[], checker: TypeChecker, existingTargetLocals: ReadonlySet<Symbol> = new Set(), enclosingRange?: TextRange): UsageInfo {
865867
const movedSymbols = new Set<Symbol>();
866868
const oldImportsNeededByTargetFile = new Map<Symbol, [/*isValidTypeOnlyUseSite*/ boolean, codefix.ImportOrRequireAliasDeclaration | undefined]>();
867869
const targetFileImportsFromOldFile = new Map<Symbol, /*isValidTypeOnlyUseSite*/ boolean>();
@@ -880,7 +882,7 @@ export function getUsageInfo(oldFile: SourceFile, toMove: readonly Statement[],
880882

881883
const unusedImportsFromOldFile = new Set<Symbol>();
882884
for (const statement of toMove) {
883-
forEachReference(statement, checker, (symbol, isValidTypeOnlyUseSite) => {
885+
forEachReference(statement, checker, enclosingRange, (symbol, isValidTypeOnlyUseSite) => {
884886
if (!symbol.declarations || isGlobalType(checker, symbol)) {
885887
return;
886888
}
@@ -916,7 +918,7 @@ export function getUsageInfo(oldFile: SourceFile, toMove: readonly Statement[],
916918
unusedImportsFromOldFile.delete(jsxNamespaceSymbol);
917919
}
918920

919-
forEachReference(statement, checker, (symbol, isValidTypeOnlyUseSite) => {
921+
forEachReference(statement, checker, enclosingRange, (symbol, isValidTypeOnlyUseSite) => {
920922
if (movedSymbols.has(symbol)) oldFileImportsFromTargetFile.set(symbol, isValidTypeOnlyUseSite);
921923
unusedImportsFromOldFile.delete(symbol);
922924
});
@@ -959,9 +961,12 @@ function inferNewFileName(importsFromNewFile: Map<Symbol, unknown>, movedSymbols
959961
return forEachKey(importsFromNewFile, symbolNameNoDefault) || forEachKey(movedSymbols, symbolNameNoDefault) || "newFile";
960962
}
961963

962-
function forEachReference(node: Node, checker: TypeChecker, onReference: (s: Symbol, isValidTypeOnlyUseSite: boolean) => void) {
964+
function forEachReference(node: Node, checker: TypeChecker, enclosingRange: TextRange | undefined, onReference: (s: Symbol, isValidTypeOnlyUseSite: boolean) => void) {
963965
node.forEachChild(function cb(node) {
964966
if (isIdentifier(node) && !isDeclarationName(node)) {
967+
if (enclosingRange && !rangeContainsRange(enclosingRange, node)) {
968+
return;
969+
}
965970
const sym = checker.getSymbolAtLocation(node);
966971
if (sym) onReference(sym, isValidTypeOnlyAliasUseSite(node));
967972
}
@@ -1140,7 +1145,7 @@ export function getExistingLocals(sourceFile: SourceFile, statements: readonly S
11401145
}
11411146

11421147
for (const statement of statements) {
1143-
forEachReference(statement, checker, s => {
1148+
forEachReference(statement, checker, /*enclosingRange*/ undefined, s => {
11441149
const symbol = skipAlias(s, checker);
11451150
if (symbol.valueDeclaration && getSourceFileOfNode(symbol.valueDeclaration).path === sourceFile.path) {
11461151
existingLocals.add(symbol);
Lines changed: 310 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,310 @@
1+
currentDirectory:: / useCaseSensitiveFileNames: false
2+
Info seq [hh:mm:ss:mss] Provided types map file "/typesMap.json" doesn't exist
3+
//// [/a.ts]
4+
export interface Foo { }
5+
6+
export const foo: Foo = {}
7+
8+
//// [/b.ts]
9+
10+
11+
//// [/lib.d.ts]
12+
lib.d.ts-Text
13+
14+
//// [/lib.decorators.d.ts]
15+
lib.decorators.d.ts-Text
16+
17+
//// [/lib.decorators.legacy.d.ts]
18+
lib.decorators.legacy.d.ts-Text
19+
20+
//// [/tsconfig.json]
21+
{ "files": ["a.ts", "b.ts"] }
22+
23+
24+
Info seq [hh:mm:ss:mss] request:
25+
{
26+
"seq": 0,
27+
"type": "request",
28+
"arguments": {
29+
"file": "/b.ts"
30+
},
31+
"command": "open"
32+
}
33+
Info seq [hh:mm:ss:mss] getConfigFileNameForFile:: File: /b.ts ProjectRootPath: undefined:: Result: /tsconfig.json
34+
Info seq [hh:mm:ss:mss] Creating configuration project /tsconfig.json
35+
Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tsconfig.json 2000 undefined Project: /tsconfig.json WatchType: Config file
36+
Info seq [hh:mm:ss:mss] event:
37+
{
38+
"seq": 0,
39+
"type": "event",
40+
"event": "projectLoadingStart",
41+
"body": {
42+
"projectName": "/tsconfig.json",
43+
"reason": "Creating possible configured project for /b.ts to open"
44+
}
45+
}
46+
Info seq [hh:mm:ss:mss] Config: /tsconfig.json : {
47+
"rootNames": [
48+
"/a.ts",
49+
"/b.ts"
50+
],
51+
"options": {
52+
"configFilePath": "/tsconfig.json"
53+
}
54+
}
55+
Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /a.ts 500 undefined WatchType: Closed Script info
56+
Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json
57+
Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.d.ts 500 undefined WatchType: Closed Script info
58+
Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.d.ts 500 undefined WatchType: Closed Script info
59+
Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.legacy.d.ts 500 undefined WatchType: Closed Script info
60+
Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 1 projectProgramVersion: 0 structureChanged: true structureIsReused:: Not Elapsed:: *ms
61+
Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured)
62+
Info seq [hh:mm:ss:mss] Files (5)
63+
/lib.d.ts Text-1 lib.d.ts-Text
64+
/lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text
65+
/lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text
66+
/a.ts Text-1 "export interface Foo { }\n\nexport const foo: Foo = {}"
67+
/b.ts SVC-1-0 ""
68+
69+
70+
lib.d.ts
71+
Default library for target 'es5'
72+
lib.decorators.d.ts
73+
Library referenced via 'decorators' from file 'lib.d.ts'
74+
lib.decorators.legacy.d.ts
75+
Library referenced via 'decorators.legacy' from file 'lib.d.ts'
76+
a.ts
77+
Part of 'files' list in tsconfig.json
78+
b.ts
79+
Part of 'files' list in tsconfig.json
80+
81+
Info seq [hh:mm:ss:mss] -----------------------------------------------
82+
Info seq [hh:mm:ss:mss] event:
83+
{
84+
"seq": 0,
85+
"type": "event",
86+
"event": "projectLoadingFinish",
87+
"body": {
88+
"projectName": "/tsconfig.json"
89+
}
90+
}
91+
Info seq [hh:mm:ss:mss] event:
92+
{
93+
"seq": 0,
94+
"type": "event",
95+
"event": "configFileDiag",
96+
"body": {
97+
"triggerFile": "/b.ts",
98+
"configFile": "/tsconfig.json",
99+
"diagnostics": []
100+
}
101+
}
102+
Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured)
103+
Info seq [hh:mm:ss:mss] Files (5)
104+
105+
Info seq [hh:mm:ss:mss] -----------------------------------------------
106+
Info seq [hh:mm:ss:mss] Open files:
107+
Info seq [hh:mm:ss:mss] FileName: /b.ts ProjectRootPath: undefined
108+
Info seq [hh:mm:ss:mss] Projects: /tsconfig.json
109+
Info seq [hh:mm:ss:mss] response:
110+
{
111+
"seq": 0,
112+
"type": "response",
113+
"command": "open",
114+
"request_seq": 0,
115+
"success": true,
116+
"performanceData": {
117+
"updateGraphDurationMs": *
118+
}
119+
}
120+
After Request
121+
watchedFiles::
122+
/a.ts: *new*
123+
{"pollingInterval":500}
124+
/lib.d.ts: *new*
125+
{"pollingInterval":500}
126+
/lib.decorators.d.ts: *new*
127+
{"pollingInterval":500}
128+
/lib.decorators.legacy.d.ts: *new*
129+
{"pollingInterval":500}
130+
/tsconfig.json: *new*
131+
{"pollingInterval":2000}
132+
133+
Projects::
134+
/tsconfig.json (Configured) *new*
135+
projectStateVersion: 1
136+
projectProgramVersion: 1
137+
138+
ScriptInfos::
139+
/a.ts *new*
140+
version: Text-1
141+
containingProjects: 1
142+
/tsconfig.json
143+
/b.ts (Open) *new*
144+
version: SVC-1-0
145+
containingProjects: 1
146+
/tsconfig.json *default*
147+
/lib.d.ts *new*
148+
version: Text-1
149+
containingProjects: 1
150+
/tsconfig.json
151+
/lib.decorators.d.ts *new*
152+
version: Text-1
153+
containingProjects: 1
154+
/tsconfig.json
155+
/lib.decorators.legacy.d.ts *new*
156+
version: Text-1
157+
containingProjects: 1
158+
/tsconfig.json
159+
160+
Info seq [hh:mm:ss:mss] request:
161+
{
162+
"seq": 1,
163+
"type": "request",
164+
"arguments": {
165+
"formatOptions": {
166+
"indentSize": 4,
167+
"tabSize": 4,
168+
"newLineCharacter": "\n",
169+
"convertTabsToSpaces": true,
170+
"indentStyle": 2,
171+
"insertSpaceAfterConstructor": false,
172+
"insertSpaceAfterCommaDelimiter": true,
173+
"insertSpaceAfterSemicolonInForStatements": true,
174+
"insertSpaceBeforeAndAfterBinaryOperators": true,
175+
"insertSpaceAfterKeywordsInControlFlowStatements": true,
176+
"insertSpaceAfterFunctionKeywordForAnonymousFunctions": false,
177+
"insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis": false,
178+
"insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": false,
179+
"insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": true,
180+
"insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces": false,
181+
"insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces": false,
182+
"insertSpaceBeforeFunctionParenthesis": false,
183+
"placeOpenBraceOnNewLineForFunctions": false,
184+
"placeOpenBraceOnNewLineForControlBlocks": false,
185+
"semicolons": "ignore",
186+
"trimTrailingWhitespace": true,
187+
"indentSwitchCase": true
188+
}
189+
},
190+
"command": "configure"
191+
}
192+
Info seq [hh:mm:ss:mss] Format host information updated
193+
Info seq [hh:mm:ss:mss] response:
194+
{
195+
"seq": 0,
196+
"type": "response",
197+
"command": "configure",
198+
"request_seq": 1,
199+
"success": true
200+
}
201+
Info seq [hh:mm:ss:mss] request:
202+
{
203+
"seq": 2,
204+
"type": "request",
205+
"arguments": {
206+
"file": "/b.ts",
207+
"pastedText": [
208+
"export"
209+
],
210+
"pasteLocations": [
211+
{
212+
"start": {
213+
"line": 1,
214+
"offset": 1
215+
},
216+
"end": {
217+
"line": 1,
218+
"offset": 1
219+
}
220+
}
221+
],
222+
"copiedFrom": {
223+
"file": "a.ts",
224+
"spans": [
225+
{
226+
"start": {
227+
"line": 3,
228+
"offset": 1
229+
},
230+
"end": {
231+
"line": 3,
232+
"offset": 7
233+
}
234+
}
235+
]
236+
}
237+
},
238+
"command": "getPasteEdits"
239+
}
240+
Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json
241+
Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 2 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms
242+
Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured)
243+
Info seq [hh:mm:ss:mss] Files (5)
244+
/lib.d.ts Text-1 lib.d.ts-Text
245+
/lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text
246+
/lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text
247+
/a.ts Text-1 "export interface Foo { }\n\nexport const foo: Foo = {}"
248+
/b.ts SVC-1-1 "export"
249+
250+
Info seq [hh:mm:ss:mss] -----------------------------------------------
251+
Info seq [hh:mm:ss:mss] response:
252+
{
253+
"seq": 0,
254+
"type": "response",
255+
"command": "getPasteEdits",
256+
"request_seq": 2,
257+
"success": true,
258+
"performanceData": {
259+
"updateGraphDurationMs": *
260+
},
261+
"body": {
262+
"edits": [
263+
{
264+
"fileName": "/b.ts",
265+
"textChanges": [
266+
{
267+
"start": {
268+
"line": 1,
269+
"offset": 1
270+
},
271+
"end": {
272+
"line": 1,
273+
"offset": 1
274+
},
275+
"newText": "export"
276+
}
277+
]
278+
}
279+
],
280+
"fixId": "providePostPasteEdits"
281+
}
282+
}
283+
After Request
284+
Projects::
285+
/tsconfig.json (Configured) *changed*
286+
projectStateVersion: 3 *changed*
287+
projectProgramVersion: 1
288+
dirty: true *changed*
289+
290+
ScriptInfos::
291+
/a.ts
292+
version: Text-1
293+
containingProjects: 1
294+
/tsconfig.json
295+
/b.ts (Open) *changed*
296+
version: SVC-1-2 *changed*
297+
containingProjects: 1
298+
/tsconfig.json *default*
299+
/lib.d.ts
300+
version: Text-1
301+
containingProjects: 1
302+
/tsconfig.json
303+
/lib.decorators.d.ts
304+
version: Text-1
305+
containingProjects: 1
306+
/tsconfig.json
307+
/lib.decorators.legacy.d.ts
308+
version: Text-1
309+
containingProjects: 1
310+
/tsconfig.json

0 commit comments

Comments
 (0)
0