@zzzen/pyright-internal 1.2.0-dev.20230205 → 1.2.0-dev.20230219

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (161) hide show
  1. package/dist/analyzer/backgroundAnalysisProgram.d.ts +1 -0
  2. package/dist/analyzer/backgroundAnalysisProgram.js +5 -0
  3. package/dist/analyzer/backgroundAnalysisProgram.js.map +1 -1
  4. package/dist/analyzer/checker.js +8 -5
  5. package/dist/analyzer/checker.js.map +1 -1
  6. package/dist/analyzer/commentUtils.d.ts +6 -1
  7. package/dist/analyzer/commentUtils.js +100 -25
  8. package/dist/analyzer/commentUtils.js.map +1 -1
  9. package/dist/analyzer/constraintSolver.js +83 -67
  10. package/dist/analyzer/constraintSolver.js.map +1 -1
  11. package/dist/analyzer/dataClasses.js +9 -2
  12. package/dist/analyzer/dataClasses.js.map +1 -1
  13. package/dist/analyzer/declaration.d.ts +1 -0
  14. package/dist/analyzer/declaration.js.map +1 -1
  15. package/dist/analyzer/importStatementUtils.d.ts +1 -0
  16. package/dist/analyzer/importStatementUtils.js +14 -1
  17. package/dist/analyzer/importStatementUtils.js.map +1 -1
  18. package/dist/analyzer/parameterUtils.d.ts +2 -0
  19. package/dist/analyzer/parameterUtils.js +20 -0
  20. package/dist/analyzer/parameterUtils.js.map +1 -0
  21. package/dist/analyzer/parseTreeUtils.d.ts +6 -2
  22. package/dist/analyzer/parseTreeUtils.js +52 -14
  23. package/dist/analyzer/parseTreeUtils.js.map +1 -1
  24. package/dist/analyzer/parseTreeWalker.d.ts +1 -1
  25. package/dist/analyzer/patternMatching.js +25 -5
  26. package/dist/analyzer/patternMatching.js.map +1 -1
  27. package/dist/analyzer/program.d.ts +9 -2
  28. package/dist/analyzer/program.js +106 -8
  29. package/dist/analyzer/program.js.map +1 -1
  30. package/dist/analyzer/service.d.ts +1 -4
  31. package/dist/analyzer/service.js +16 -36
  32. package/dist/analyzer/service.js.map +1 -1
  33. package/dist/analyzer/sourceFile.d.ts +4 -0
  34. package/dist/analyzer/sourceFile.js +82 -16
  35. package/dist/analyzer/sourceFile.js.map +1 -1
  36. package/dist/analyzer/testWalker.js +23 -15
  37. package/dist/analyzer/testWalker.js.map +1 -1
  38. package/dist/analyzer/typeEvaluator.js +122 -71
  39. package/dist/analyzer/typeEvaluator.js.map +1 -1
  40. package/dist/analyzer/typeEvaluatorTypes.d.ts +2 -1
  41. package/dist/analyzer/typeEvaluatorTypes.js.map +1 -1
  42. package/dist/analyzer/typePrinter.d.ts +2 -1
  43. package/dist/analyzer/typePrinter.js +13 -0
  44. package/dist/analyzer/typePrinter.js.map +1 -1
  45. package/dist/analyzer/typeUtils.d.ts +1 -1
  46. package/dist/analyzer/typeUtils.js +189 -142
  47. package/dist/analyzer/typeUtils.js.map +1 -1
  48. package/dist/analyzer/typeVarContext.d.ts +31 -14
  49. package/dist/analyzer/typeVarContext.js +158 -79
  50. package/dist/analyzer/typeVarContext.js.map +1 -1
  51. package/dist/analyzer/types.d.ts +2 -1
  52. package/dist/analyzer/types.js +1 -0
  53. package/dist/analyzer/types.js.map +1 -1
  54. package/dist/backgroundAnalysisBase.d.ts +2 -1
  55. package/dist/backgroundAnalysisBase.js +15 -1
  56. package/dist/backgroundAnalysisBase.js.map +1 -1
  57. package/dist/backgroundThreadBase.js +1 -0
  58. package/dist/backgroundThreadBase.js.map +1 -1
  59. package/dist/common/commandLineOptions.d.ts +2 -0
  60. package/dist/common/commandLineOptions.js.map +1 -1
  61. package/dist/common/configOptions.d.ts +3 -0
  62. package/dist/common/configOptions.js +10 -1
  63. package/dist/common/configOptions.js.map +1 -1
  64. package/dist/common/core.d.ts +2 -0
  65. package/dist/common/core.js +9 -1
  66. package/dist/common/core.js.map +1 -1
  67. package/dist/common/diagnostic.d.ts +15 -3
  68. package/dist/common/diagnostic.js +13 -4
  69. package/dist/common/diagnostic.js.map +1 -1
  70. package/dist/common/editAction.d.ts +1 -0
  71. package/dist/common/editAction.js +8 -0
  72. package/dist/common/editAction.js.map +1 -1
  73. package/dist/common/extensibility.d.ts +34 -11
  74. package/dist/common/extensibility.js +63 -18
  75. package/dist/common/extensibility.js.map +1 -1
  76. package/dist/common/pathUtils.d.ts +3 -0
  77. package/dist/common/pathUtils.js +18 -0
  78. package/dist/common/pathUtils.js.map +1 -1
  79. package/dist/common/textEditUtils.d.ts +26 -9
  80. package/dist/common/textEditUtils.js +218 -41
  81. package/dist/common/textEditUtils.js.map +1 -1
  82. package/dist/common/textRangeCollection.d.ts +1 -0
  83. package/dist/common/textRangeCollection.js +54 -20
  84. package/dist/common/textRangeCollection.js.map +1 -1
  85. package/dist/languageServerBase.d.ts +3 -0
  86. package/dist/languageServerBase.js +90 -1
  87. package/dist/languageServerBase.js.map +1 -1
  88. package/dist/languageService/analyzerServiceExecutor.js +1 -0
  89. package/dist/languageService/analyzerServiceExecutor.js.map +1 -1
  90. package/dist/languageService/completionProvider.js +13 -7
  91. package/dist/languageService/completionProvider.js.map +1 -1
  92. package/dist/languageService/definitionProvider.js +1 -1
  93. package/dist/languageService/definitionProvider.js.map +1 -1
  94. package/dist/languageService/documentSymbolCollector.js +1 -1
  95. package/dist/languageService/documentSymbolCollector.js.map +1 -1
  96. package/dist/languageService/hoverProvider.js +10 -6
  97. package/dist/languageService/hoverProvider.js.map +1 -1
  98. package/dist/languageService/importAdder.d.ts +4 -0
  99. package/dist/languageService/importAdder.js +50 -13
  100. package/dist/languageService/importAdder.js.map +1 -1
  101. package/dist/languageService/insertionPointUtils.js +28 -7
  102. package/dist/languageService/insertionPointUtils.js.map +1 -1
  103. package/dist/languageService/renameModuleProvider.d.ts +12 -10
  104. package/dist/languageService/renameModuleProvider.js +240 -229
  105. package/dist/languageService/renameModuleProvider.js.map +1 -1
  106. package/dist/languageService/signatureHelpProvider.js +20 -3
  107. package/dist/languageService/signatureHelpProvider.js.map +1 -1
  108. package/dist/languageService/tooltipUtils.js +1 -1
  109. package/dist/languageService/tooltipUtils.js.map +1 -1
  110. package/dist/localization/localize.d.ts +10 -1
  111. package/dist/localization/localize.js +6 -1
  112. package/dist/localization/localize.js.map +1 -1
  113. package/dist/localization/package.nls.en-us.json +8 -2
  114. package/dist/tests/checker.test.js +5 -0
  115. package/dist/tests/checker.test.js.map +1 -1
  116. package/dist/tests/fourslash/completions.params.fourslash.js +37 -0
  117. package/dist/tests/fourslash/completions.params.fourslash.js.map +1 -1
  118. package/dist/tests/fourslash/hover.inferred.fourslash.d.ts +1 -0
  119. package/dist/tests/fourslash/hover.inferred.fourslash.js +24 -0
  120. package/dist/tests/fourslash/hover.inferred.fourslash.js.map +1 -0
  121. package/dist/tests/fourslash/signature.complicated.fourslash.js +31 -1
  122. package/dist/tests/fourslash/signature.complicated.fourslash.js.map +1 -1
  123. package/dist/tests/hoverProvider.test.js +27 -0
  124. package/dist/tests/hoverProvider.test.js.map +1 -1
  125. package/dist/tests/importAdder.test.js +39 -2
  126. package/dist/tests/importAdder.test.js.map +1 -1
  127. package/dist/tests/insertionPointUtils.test.js +70 -3
  128. package/dist/tests/insertionPointUtils.test.js.map +1 -1
  129. package/dist/tests/{updateSymbolReference.test.d.ts → moveSymbol.importAdder.test.d.ts} +0 -0
  130. package/dist/tests/moveSymbol.importAdder.test.js +139 -0
  131. package/dist/tests/moveSymbol.importAdder.test.js.map +1 -0
  132. package/dist/tests/moveSymbol.insertion.test.d.ts +1 -0
  133. package/dist/tests/moveSymbol.insertion.test.js +360 -0
  134. package/dist/tests/moveSymbol.insertion.test.js.map +1 -0
  135. package/dist/tests/moveSymbol.misc.test.d.ts +1 -0
  136. package/dist/tests/moveSymbol.misc.test.js +37 -0
  137. package/dist/tests/moveSymbol.misc.test.js.map +1 -0
  138. package/dist/tests/moveSymbol.updateReference.test.d.ts +1 -0
  139. package/dist/tests/{updateSymbolReference.test.js → moveSymbol.updateReference.test.js} +235 -158
  140. package/dist/tests/moveSymbol.updateReference.test.js.map +1 -0
  141. package/dist/tests/parseTreeUtils.test.js +36 -13
  142. package/dist/tests/parseTreeUtils.test.js.map +1 -1
  143. package/dist/tests/renameModuleTestUtils.js +9 -3
  144. package/dist/tests/renameModuleTestUtils.js.map +1 -1
  145. package/dist/tests/testStateUtils.d.ts +2 -0
  146. package/dist/tests/testStateUtils.js +25 -22
  147. package/dist/tests/testStateUtils.js.map +1 -1
  148. package/dist/tests/textEditUtil.test.d.ts +1 -0
  149. package/dist/tests/textEditUtil.test.js +107 -0
  150. package/dist/tests/textEditUtil.test.js.map +1 -0
  151. package/dist/tests/typeEvaluator1.test.js +4 -0
  152. package/dist/tests/typeEvaluator1.test.js.map +1 -1
  153. package/dist/tests/typeEvaluator3.test.js +2 -2
  154. package/dist/tests/typeEvaluator3.test.js.map +1 -1
  155. package/dist/tests/typeEvaluator4.test.js +10 -2
  156. package/dist/tests/typeEvaluator4.test.js.map +1 -1
  157. package/dist/workspaceMap.d.ts +0 -1
  158. package/dist/workspaceMap.js +0 -11
  159. package/dist/workspaceMap.js.map +1 -1
  160. package/package.json +1 -1
  161. package/dist/tests/updateSymbolReference.test.js.map +0 -1
@@ -20,7 +20,6 @@ const sourceMapper_1 = require("../analyzer/sourceMapper");
20
20
  const collectionUtils_1 = require("../common/collectionUtils");
21
21
  const debug_1 = require("../common/debug");
22
22
  const pathUtils_1 = require("../common/pathUtils");
23
- const positionUtils_1 = require("../common/positionUtils");
24
23
  const textEditUtils_1 = require("../common/textEditUtils");
25
24
  const textRange_1 = require("../common/textRange");
26
25
  const parseNodes_1 = require("../parser/parseNodes");
@@ -32,14 +31,14 @@ var UpdateType;
32
31
  UpdateType[UpdateType["Symbol"] = 2] = "Symbol";
33
32
  })(UpdateType || (UpdateType = {}));
34
33
  class RenameModuleProvider {
35
- constructor(_fs, _evaluator, _moduleFilePath, newModuleFilePath, _moduleNameAndType, _newModuleNameAndType, _type, _declarations, _token) {
34
+ constructor(_fs, _evaluator, _moduleFilePath, newModuleFilePath, _moduleNameAndType, _newModuleNameAndType, _type, declarations, _token) {
36
35
  this._fs = _fs;
37
36
  this._evaluator = _evaluator;
38
37
  this._moduleFilePath = _moduleFilePath;
39
38
  this._moduleNameAndType = _moduleNameAndType;
40
39
  this._newModuleNameAndType = _newModuleNameAndType;
41
40
  this._type = _type;
42
- this._declarations = _declarations;
41
+ this.declarations = declarations;
43
42
  this._token = _token;
44
43
  this._aliasIntroduced = new Set();
45
44
  this._textEditTracker = new textEditUtils_1.TextEditTracker();
@@ -47,17 +46,7 @@ class RenameModuleProvider {
47
46
  this._newModuleFilePath = (0, pathUtils_1.resolvePaths)(newModuleFilePath);
48
47
  this._moduleNames = this._moduleName.split('.');
49
48
  this._newModuleNames = this._newModuleName.split('.');
50
- if (this._moduleNames.length !== this._newModuleNames.length) {
51
- this._onlyNameChanged = false;
52
- return;
53
- }
54
- let i = 0;
55
- for (i = 0; i < this._moduleNames.length - 1; i++) {
56
- if (this._moduleNames[i] !== this._newModuleNames[i]) {
57
- break;
58
- }
59
- }
60
- this._onlyNameChanged = i === this._moduleNames.length - 1;
49
+ this._onlyNameChanged = (0, importStatementUtils_1.haveSameParentModule)(this._moduleNames, this._newModuleNames);
61
50
  (0, debug_1.assert)(this._type !== UpdateType.Folder || this._onlyNameChanged, 'We only support simple rename for folder');
62
51
  }
63
52
  static createForModule(importResolver, configOptions, evaluator, path, newPath, token) {
@@ -154,21 +143,48 @@ class RenameModuleProvider {
154
143
  }
155
144
  return new RenameModuleProvider(importResolver.fileSystem, evaluator, moduleFilePath, newModuleFilePath, moduleName, newModuleName, type, declarations, token);
156
145
  }
157
- renameReferences(filePath, parseResults) {
146
+ get lastModuleName() {
147
+ return this._moduleNames[this._moduleNames.length - 1];
148
+ }
149
+ get textEditTracker() {
150
+ return this._textEditTracker;
151
+ }
152
+ getEdits() {
153
+ return this._textEditTracker.getEdits(this._token);
154
+ }
155
+ renameReferences(parseResults) {
158
156
  switch (this._type) {
159
157
  case UpdateType.Folder:
160
- return this._renameFolderReferences(filePath, parseResults);
158
+ return this._renameFolderReferences(parseResults);
161
159
  case UpdateType.File:
162
- return this._renameModuleReferences(filePath, parseResults);
160
+ return this._renameModuleReferences(parseResults);
163
161
  case UpdateType.Symbol:
164
- return this._updateSymbolReferences(filePath, parseResults);
162
+ return this._updateSymbolReferences(parseResults);
165
163
  default:
166
164
  return (0, debug_1.assertNever)(this._type, `${this._type} is unknown`);
167
165
  }
168
166
  }
169
- _updateSymbolReferences(filePath, parseResults) {
170
- var _a, _b, _c;
171
- const collector = new documentSymbolCollector_1.DocumentSymbolCollector([(0, declarationUtils_1.getNameFromDeclaration)(this._declarations[0]) || ''], this._declarations, this._evaluator, this._token, parseResults.parseTree,
167
+ tryGetFirstSymbolUsage(parseResults) {
168
+ const collector = new documentSymbolCollector_1.DocumentSymbolCollector([(0, declarationUtils_1.getNameFromDeclaration)(this.declarations[0]) || ''], this.declarations, this._evaluator, this._token, parseResults.parseTree,
169
+ /* treatModuleImportAndFromImportSame */ true,
170
+ /* skipUnreachableCode */ false);
171
+ for (const result of collector.collect().sort((r1, r2) => r1.range.start - r2.range.start)) {
172
+ // We only care about symbol usages, not alias decl of the symbol.
173
+ if ((0, parseTreeUtils_1.isImportModuleName)(result.node) ||
174
+ (0, parseTreeUtils_1.isImportAlias)(result.node) ||
175
+ (0, parseTreeUtils_1.isFromImportModuleName)(result.node) ||
176
+ (0, parseTreeUtils_1.isFromImportName)(result.node) ||
177
+ (0, parseTreeUtils_1.isFromImportAlias)(result.node)) {
178
+ continue;
179
+ }
180
+ return result.range.start;
181
+ }
182
+ return undefined;
183
+ }
184
+ _updateSymbolReferences(parseResults) {
185
+ const filePath = (0, analyzerNodeInfo_1.getFileInfo)(parseResults.parseTree).filePath;
186
+ const isSource = filePath === this._moduleFilePath;
187
+ const collector = new documentSymbolCollector_1.DocumentSymbolCollector([(0, declarationUtils_1.getNameFromDeclaration)(this.declarations[0]) || ''], this.declarations, this._evaluator, this._token, parseResults.parseTree,
172
188
  /* treatModuleImportAndFromImportSame */ true,
173
189
  /* skipUnreachableCode */ false);
174
190
  // See if we need to insert new import statement
@@ -176,76 +192,73 @@ class RenameModuleProvider {
176
192
  // See whether we have existing import statement for the same module
177
193
  // ex) import [moduleName] or from ... import [moduleName]
178
194
  const imported = importStatements.orderedImports.find((i) => i.moduleName === this._newModuleName);
179
- const nameRemoved = new Set();
195
+ // Indicate whether current file has any usage of the symbol
196
+ let hasSymbolUsage = false;
197
+ const wildcardImports = new Map();
180
198
  const importUsed = new Map();
181
199
  for (const result of collector.collect()) {
182
200
  const nodeFound = result.node;
183
201
  if (nodeFound.nodeType === 49 /* String */) {
184
- // Ignore symbol appearing in the __all__. it should be handled
185
- // when decl is moved.
202
+ if (isSource) {
203
+ // Delete the symbol reference in __all__ if the file is the source file.
204
+ this._textEditTracker.addEditWithTextRange(parseResults, nodeFound, '');
205
+ }
186
206
  continue;
187
207
  }
188
208
  if ((0, parseTreeUtils_1.isFromImportName)(nodeFound)) {
189
- // ex) from ... import [symbol] ...
190
- const fromNode = (_a = nodeFound.parent) === null || _a === void 0 ? void 0 : _a.parent;
191
- const newModuleName = this._getNewModuleName(filePath, fromNode.module.leadingDots > 0,
192
- /* isLastPartImportName */ false);
193
- if (fromNode.imports.length === 1) {
194
- // ex) "from [module] import symbol" to "from [module.changed] import symbol"
195
- this._addResultWithTextRange(filePath, fromNode.module, parseResults, newModuleName);
196
- }
197
- else {
198
- // ex) "from module import symbol, another_symbol" to
199
- // "from module import another_symbol" and "from module.changed import symbol"
200
- // Delete the existing import name including alias.
201
- const importFromAs = nodeFound.parent;
202
- this._addFromImportNameDeletion(filePath, parseResults, nameRemoved, fromNode.imports, importFromAs);
203
- // For now, this won't merge absolute and relative path "from import" statement.
204
- const importNameInfo = {
205
- name: importFromAs.name.value,
206
- alias: (_b = importFromAs.alias) === null || _b === void 0 ? void 0 : _b.value,
207
- };
208
- this._addResultEdits(this._getTextEditsForNewOrExistingFromImport(filePath, fromNode, parseResults, nameRemoved, importStatements, newModuleName, [importNameInfo]));
209
- }
209
+ this._updateNameInFromImportForSymbolReferences(parseResults, importStatements, nodeFound);
210
210
  continue;
211
211
  }
212
+ // Exclude symbol decl itself.
213
+ hasSymbolUsage = isSource
214
+ ? !this.declarations.some((d) => textRange_1.TextRange.containsRange(d.node, nodeFound))
215
+ : true;
212
216
  const dottedName = (0, parseTreeUtils_1.getDottedNameWithGivenNodeAsLastName)(nodeFound);
213
217
  if (dottedName === nodeFound || dottedName.nodeType !== 35 /* MemberAccess */) {
218
+ this._collectWildcardImports(nodeFound, wildcardImports);
214
219
  // ex) from module import foo
215
220
  // foo
216
221
  // foo.method()
217
- //
218
- // from module import *
219
- // foo()
220
- // bar()
221
- //
222
- // we don't need to do anything for wild card case since
223
- // we will preserve __all__ entries.
224
- continue;
225
- }
226
- const moduleName = dottedName.leftExpression.nodeType === 35 /* MemberAccess */
227
- ? dottedName.leftExpression.memberName
228
- : dottedName.leftExpression.nodeType === 38 /* Name */
229
- ? dottedName.leftExpression
230
- : undefined;
231
- if (!moduleName) {
232
- // ex) from module import foo
233
- // getModule().foo
234
- continue;
235
- }
236
- const moduleDecl = (_c = this._evaluator
237
- .getDeclarationsForNameNode(moduleName)) === null || _c === void 0 ? void 0 : _c.filter((d) => (0, declaration_1.isAliasDeclaration)(d) &&
238
- (d.node.nodeType === 21 /* ImportAs */ || d.node.nodeType === 23 /* ImportFromAs */));
239
- if (!moduleDecl || moduleDecl.length === 0) {
240
- // ex) from xxx import yyy
241
- // yyy.property.foo
242
222
  continue;
243
223
  }
244
- const importAs = moduleDecl[0].node;
245
- (0, collectionUtils_1.getOrAdd)(importUsed, importAs, () => []).push(dottedName);
246
- continue;
224
+ this._collectSymbolReferencesPerImports(dottedName, importUsed);
225
+ }
226
+ if (isSource && hasSymbolUsage) {
227
+ // If the original file has references to the symbol moved, we need to either
228
+ // insert import statement or update existing one.
229
+ const newModuleName = (imported === null || imported === void 0 ? void 0 : imported.node.nodeType) === 22 /* ImportFrom */
230
+ ? this._getNewModuleName(filePath, imported.node.module.leadingDots > 0,
231
+ /* isLastPartImportName */ false)
232
+ : undefined;
233
+ const options = (imported === null || imported === void 0 ? void 0 : imported.node.nodeType) === 22 /* ImportFrom */
234
+ ? {
235
+ currentFromImport: imported.node,
236
+ originalModuleName: this._moduleName,
237
+ }
238
+ : undefined;
239
+ this._textEditTracker.addOrUpdateImport(parseResults, importStatements, { name: this._newModuleName, nameForImportFrom: newModuleName }, (0, importStatementUtils_1.getImportGroupFromModuleNameAndType)(this._newModuleNameAndType), [{ name: (0, declarationUtils_1.getNameFromDeclaration)(this.declarations[0]) }], options);
247
240
  }
241
+ // Handle symbol references that are used off wildcard imports.
242
+ this._processSymbolReferenceOffWildcardImports(parseResults, importStatements, wildcardImports);
248
243
  // Handle symbol references that are used off imported modules.
244
+ this._processSymbolReferenceOffImports(parseResults, importStatements, imported, importUsed);
245
+ }
246
+ _processSymbolReferenceOffImports(parseResults, importStatements, imported, importUsed) {
247
+ const filePath = (0, analyzerNodeInfo_1.getFileInfo)(parseResults.parseTree).filePath;
248
+ const isDestination = filePath === this._newModuleFilePath;
249
+ if (isDestination) {
250
+ for (const [key, value] of importUsed) {
251
+ if (this._canReplaceImportName(parseResults, key, value)) {
252
+ // We can remove existing import statement.
253
+ this._textEditTracker.deleteImportName(parseResults, key);
254
+ }
255
+ for (const node of value) {
256
+ this._textEditTracker.addEditWithTextRange(parseResults, textRange_1.TextRange.fromBounds(node.start, node.memberName.start), '');
257
+ }
258
+ }
259
+ return;
260
+ }
261
+ // Other files.
249
262
  for (const [key, value] of importUsed) {
250
263
  let referenceModuleName;
251
264
  if (this._canReplaceImportName(parseResults, key, value)) {
@@ -253,25 +266,25 @@ class RenameModuleProvider {
253
266
  if (key.nodeType === 21 /* ImportAs */) {
254
267
  if (moduleName) {
255
268
  referenceModuleName = moduleName;
256
- this._addImportNameDeletion(filePath, parseResults, nameRemoved, key.parent.list, key);
269
+ this._textEditTracker.deleteImportName(parseResults, key);
257
270
  }
258
271
  else {
259
272
  referenceModuleName = key.alias ? key.alias.value : this._newModuleName;
260
- this._addResultWithTextRange(filePath, key.module, parseResults, this._newModuleName);
273
+ this._textEditTracker.addEditWithTextRange(parseResults, key.module, this._newModuleName);
261
274
  }
262
275
  }
263
276
  else {
264
277
  if (moduleName) {
265
278
  referenceModuleName = moduleName;
266
- this._addFromImportNameDeletion(filePath, parseResults, nameRemoved, key.parent.imports, key);
279
+ this._textEditTracker.deleteImportName(parseResults, key);
267
280
  }
268
281
  else {
269
282
  const fromNode = key.parent;
270
283
  const newModuleName = this._getNewModuleName(filePath, fromNode.module.leadingDots > 0,
271
284
  /* isLastPartImportName */ true);
272
285
  referenceModuleName = key.alias ? key.alias.value : this._newLastModuleName;
273
- this._addResultWithTextRange(filePath, fromNode.module, parseResults, newModuleName);
274
- this._addResultWithTextRange(filePath, key.name, parseResults, this._newLastModuleName);
286
+ this._textEditTracker.addEditWithTextRange(parseResults, fromNode.module, newModuleName);
287
+ this._textEditTracker.addEditWithTextRange(parseResults, key.name, this._newLastModuleName);
275
288
  }
276
289
  }
277
290
  }
@@ -282,14 +295,108 @@ class RenameModuleProvider {
282
295
  }
283
296
  else {
284
297
  referenceModuleName = this._newModuleName;
285
- this._addResultEdits((0, importStatementUtils_1.getTextEditsForAutoImportInsertion)([], { name: this._newModuleName }, importStatements, (0, importStatementUtils_1.getImportGroupFromModuleNameAndType)(this._newModuleNameAndType), parseResults, (0, positionUtils_1.convertOffsetToPosition)(parseResults.parseTree.length, parseResults.tokenizerOutput.lines)).map((e) => ({ filePath, range: e.range, replacementText: e.replacementText })));
298
+ this._textEditTracker.addOrUpdateImport(parseResults, importStatements, { name: this._newModuleName }, (0, importStatementUtils_1.getImportGroupFromModuleNameAndType)(this._newModuleNameAndType));
286
299
  }
287
300
  }
288
301
  for (const node of value) {
289
- this._addResultWithTextRange(filePath, node.leftExpression, parseResults, referenceModuleName);
302
+ this._textEditTracker.addEditWithTextRange(parseResults, node.leftExpression, referenceModuleName);
290
303
  }
291
304
  }
292
305
  }
306
+ _processSymbolReferenceOffWildcardImports(parseResults, importStatements, wildcardImports) {
307
+ const filePath = (0, analyzerNodeInfo_1.getFileInfo)(parseResults.parseTree).filePath;
308
+ const isDestination = filePath === this._newModuleFilePath;
309
+ if (isDestination) {
310
+ // Destination file contains the moved symbol decl. no need to insert
311
+ // import statement for the symbol moved.
312
+ return;
313
+ }
314
+ for (const [key, value] of wildcardImports) {
315
+ const fromNode = key;
316
+ const newModuleName = this._getNewModuleName(filePath, fromNode.module.leadingDots > 0,
317
+ /* isLastPartImportName */ false);
318
+ this._textEditTracker.addOrUpdateImport(parseResults, importStatements, { name: this._newModuleName, nameForImportFrom: newModuleName }, (0, importStatementUtils_1.getImportGroupFromModuleNameAndType)(this._newModuleNameAndType), [...value].map((v) => ({ name: v })), {
319
+ currentFromImport: fromNode,
320
+ originalModuleName: this._moduleName,
321
+ });
322
+ }
323
+ }
324
+ _collectSymbolReferencesPerImports(dottedName, importUsed) {
325
+ var _a;
326
+ const moduleName = dottedName.leftExpression.nodeType === 35 /* MemberAccess */
327
+ ? dottedName.leftExpression.memberName
328
+ : dottedName.leftExpression.nodeType === 38 /* Name */
329
+ ? dottedName.leftExpression
330
+ : undefined;
331
+ if (!moduleName) {
332
+ // ex) from module import foo
333
+ // getModule().foo
334
+ return;
335
+ }
336
+ const moduleDecl = (_a = this._evaluator
337
+ .getDeclarationsForNameNode(moduleName)) === null || _a === void 0 ? void 0 : _a.filter((d) => (0, declaration_1.isAliasDeclaration)(d) &&
338
+ (d.node.nodeType === 21 /* ImportAs */ || d.node.nodeType === 23 /* ImportFromAs */));
339
+ if (!moduleDecl || moduleDecl.length === 0) {
340
+ // ex) from xxx import yyy
341
+ // yyy.property.foo
342
+ return;
343
+ }
344
+ const importAs = moduleDecl[0].node;
345
+ (0, collectionUtils_1.getOrAdd)(importUsed, importAs, () => []).push(dottedName);
346
+ }
347
+ _collectWildcardImports(nodeFound, wildcardImports) {
348
+ const nameDecls = this._evaluator.getDeclarationsForNameNode(nodeFound);
349
+ const aliasDeclFromWildCardImport = nameDecls === null || nameDecls === void 0 ? void 0 : nameDecls.find((d) => d.node.nodeType === 22 /* ImportFrom */ && d.node.isWildcardImport);
350
+ if (!aliasDeclFromWildCardImport || !(0, declaration_1.isAliasDeclaration)(aliasDeclFromWildCardImport)) {
351
+ return;
352
+ }
353
+ // ex) from module import *
354
+ // foo()
355
+ // bar()
356
+ (0, collectionUtils_1.getOrAdd)(wildcardImports, aliasDeclFromWildCardImport.node, () => new Set()).add(nodeFound.value);
357
+ }
358
+ _updateNameInFromImportForSymbolReferences(parseResults, importStatements, nodeFound) {
359
+ var _a;
360
+ const filePath = (0, analyzerNodeInfo_1.getFileInfo)(parseResults.parseTree).filePath;
361
+ const isDestination = filePath === this._newModuleFilePath;
362
+ // ex) from ... import [symbol] ...
363
+ const importFromAs = nodeFound.parent;
364
+ const fromNode = importFromAs === null || importFromAs === void 0 ? void 0 : importFromAs.parent;
365
+ const newModuleName = this._getNewModuleName(filePath, fromNode.module.leadingDots > 0,
366
+ /* isLastPartImportName */ false);
367
+ const hasAlias = !!importFromAs.alias;
368
+ if (isDestination && !hasAlias) {
369
+ if (fromNode.imports.length === 1) {
370
+ // If we have import statement for the symbol in the destination file,
371
+ // we need to remove it.
372
+ this._textEditTracker.deleteImportName(parseResults, importFromAs);
373
+ return;
374
+ }
375
+ // ex) "from module import symbol, another_symbol" to
376
+ // "from module import another_symbol" and "from module.changed import symbol"
377
+ // Delete the existing import name including alias.
378
+ this._textEditTracker.deleteImportName(parseResults, importFromAs);
379
+ return;
380
+ }
381
+ if (fromNode.imports.length === 1) {
382
+ // ex) "from [module] import symbol" to "from [module.changed] import symbol"
383
+ this._textEditTracker.addEditWithTextRange(parseResults, fromNode.module, newModuleName);
384
+ return;
385
+ }
386
+ // ex) "from module import symbol, another_symbol" to
387
+ // "from module import another_symbol" and "from module.changed import symbol"
388
+ // Delete the existing import name including alias.
389
+ this._textEditTracker.deleteImportName(parseResults, importFromAs);
390
+ // For now, this won't merge absolute and relative path "from import" statement.
391
+ const importNameInfo = {
392
+ name: importFromAs.name.value,
393
+ alias: (_a = importFromAs.alias) === null || _a === void 0 ? void 0 : _a.value,
394
+ };
395
+ this._textEditTracker.addOrUpdateImport(parseResults, importStatements, { name: this._newModuleName, nameForImportFrom: newModuleName }, (0, importStatementUtils_1.getImportGroupFromModuleNameAndType)(this._newModuleNameAndType), [importNameInfo], {
396
+ currentFromImport: fromNode,
397
+ originalModuleName: this._moduleName,
398
+ });
399
+ }
293
400
  _getReferenceModuleName(importStatements, imported) {
294
401
  var _a, _b;
295
402
  if (imported && imported.node.nodeType === 20 /* Import */) {
@@ -323,34 +430,35 @@ class RenameModuleProvider {
323
430
  // collector will report decls as well. ignore decls.
324
431
  continue;
325
432
  }
433
+ // other symbols from the module are used in the file.
326
434
  if (!symbolReferences.some((s) => textRange_1.TextRange.containsRange(s, result.node))) {
327
435
  return false;
328
436
  }
329
437
  }
330
438
  return true;
331
439
  }
332
- _renameFolderReferences(filePath, parseResults) {
333
- const collector = new documentSymbolCollector_1.DocumentSymbolCollector([this.lastModuleName], this._declarations, this._evaluator, this._token, parseResults.parseTree,
440
+ _renameFolderReferences(parseResults) {
441
+ const collector = new documentSymbolCollector_1.DocumentSymbolCollector([this.lastModuleName], this.declarations, this._evaluator, this._token, parseResults.parseTree,
334
442
  /* treatModuleImportAndFromImportSame */ true,
335
443
  /* skipUnreachableCode */ false);
336
444
  // We only support simple rename of folder. Change all occurrence of the old folder name
337
445
  // to new name.
338
446
  for (const result of collector.collect()) {
339
- this._addResultWithTextRange(filePath, result.range, parseResults, this._newLastModuleName);
447
+ this._textEditTracker.addEditWithTextRange(parseResults, result.range, this._newLastModuleName);
340
448
  }
341
449
  }
342
- _renameModuleReferences(filePath, parseResults) {
343
- const collector = new documentSymbolCollector_1.DocumentSymbolCollector([this.lastModuleName], this._declarations, this._evaluator, this._token, parseResults.parseTree,
450
+ _renameModuleReferences(parseResults) {
451
+ const collector = new documentSymbolCollector_1.DocumentSymbolCollector([this.lastModuleName], this.declarations, this._evaluator, this._token, parseResults.parseTree,
344
452
  /* treatModuleImportAndFromImportSame */ true,
345
453
  /* skipUnreachableCode */ false);
346
- const nameRemoved = new Set();
347
454
  const results = collector.collect();
348
455
  // Update module references first.
349
- this._updateModuleReferences(filePath, parseResults, nameRemoved, results);
456
+ this._updateModuleReferences(parseResults, results);
350
457
  // If the module file has moved, we need to update all relative paths used in the file to reflect the move.
351
- this._updateRelativeModuleNamePath(filePath, parseResults, nameRemoved, results);
458
+ this._updateRelativeModuleNamePath(parseResults, results);
352
459
  }
353
- _updateRelativeModuleNamePath(filePath, parseResults, nameRemoved, results) {
460
+ _updateRelativeModuleNamePath(parseResults, results) {
461
+ const filePath = (0, analyzerNodeInfo_1.getFileInfo)(parseResults.parseTree).filePath;
354
462
  if (filePath !== this._moduleFilePath) {
355
463
  // We only update relative import paths for the file that has moved.
356
464
  return;
@@ -358,7 +466,7 @@ class RenameModuleProvider {
358
466
  let importStatements;
359
467
  // Filter out module name that is already re-written.
360
468
  for (const edit of this._getNewRelativeModuleNamesForFileMoved(filePath, ModuleNameCollector.collect(parseResults.parseTree).filter((m) => !results.some((r) => textRange_1.TextRange.containsRange(m.parent, r.node))))) {
361
- this._addResultWithTextRange(filePath, edit.moduleName, parseResults, edit.newModuleName);
469
+ this._textEditTracker.addEditWithTextRange(parseResults, edit.moduleName, edit.newModuleName);
362
470
  if (!edit.itemsToMove) {
363
471
  continue;
364
472
  }
@@ -370,28 +478,35 @@ class RenameModuleProvider {
370
478
  const fromNode = edit.moduleName.parent;
371
479
  // First, delete existing exported symbols from "from import" statement.
372
480
  for (const importFromAs of edit.itemsToMove) {
373
- this._addFromImportNameDeletion(filePath, parseResults, nameRemoved, fromNode.imports, importFromAs);
481
+ this._textEditTracker.deleteImportName(parseResults, importFromAs);
374
482
  }
375
483
  importStatements =
376
484
  importStatements !== null && importStatements !== void 0 ? importStatements : (0, importStatementUtils_1.getTopLevelImports)(parseResults.parseTree, /* includeImplicitImports */ false);
377
485
  // For now, this won't merge absolute and relative path "from import"
378
486
  // statement.
379
- this._addResultEdits(this._getTextEditsForNewOrExistingFromImport(filePath, fromNode, parseResults, nameRemoved, importStatements, (0, importStatementUtils_1.getRelativeModuleName)(this._fs, this._newModuleFilePath, this._newModuleFilePath,
380
- /* ignoreFolderStructure */ false,
381
- /* sourceIsFile */ true), edit.itemsToMove.map((i) => {
487
+ this._textEditTracker.addOrUpdateImport(parseResults, importStatements, {
488
+ name: this._newModuleName,
489
+ nameForImportFrom: (0, importStatementUtils_1.getRelativeModuleName)(this._fs, this._newModuleFilePath, this._newModuleFilePath,
490
+ /* ignoreFolderStructure */ false,
491
+ /* sourceIsFile */ true),
492
+ }, (0, importStatementUtils_1.getImportGroupFromModuleNameAndType)(this._newModuleNameAndType), edit.itemsToMove.map((i) => {
382
493
  var _a;
383
494
  return { name: i.name.value, alias: (_a = i.alias) === null || _a === void 0 ? void 0 : _a.value };
384
- })));
495
+ }), {
496
+ currentFromImport: fromNode,
497
+ originalModuleName: this._moduleName,
498
+ });
385
499
  }
386
500
  }
387
- _updateModuleReferences(filePath, parseResults, nameRemoved, results) {
501
+ _updateModuleReferences(parseResults, results) {
388
502
  var _a, _b, _c, _d, _e;
503
+ const filePath = (0, analyzerNodeInfo_1.getFileInfo)(parseResults.parseTree).filePath;
389
504
  let importStatements;
390
505
  for (const result of results) {
391
506
  const nodeFound = result.node;
392
507
  if (nodeFound.nodeType === 49 /* String */) {
393
508
  // ex) __all__ = ["[a]"]
394
- this._addResultWithTextRange(filePath, result.range, parseResults, this._newLastModuleName);
509
+ this._textEditTracker.addEditWithTextRange(parseResults, result.range, this._newLastModuleName);
395
510
  continue;
396
511
  }
397
512
  if ((0, parseTreeUtils_1.isImportModuleName)(nodeFound)) {
@@ -419,17 +534,17 @@ class RenameModuleProvider {
419
534
  !moduleNameNode.parent.alias &&
420
535
  this._newModuleNames.length > 1) {
421
536
  this._aliasIntroduced.add(moduleNameNode.parent);
422
- this._addResultWithTextRange(filePath, moduleNameNode, parseResults, `${this._newModuleName} as ${this._newLastModuleName}`);
537
+ this._textEditTracker.addEditWithTextRange(parseResults, moduleNameNode, `${this._newModuleName} as ${this._newLastModuleName}`);
423
538
  continue;
424
539
  }
425
540
  // Otherwise, update whole module name to new name
426
541
  // ex) import [xxx.yyy] to import [aaa.bbb]
427
- this._addResultWithTextRange(filePath, moduleNameNode, parseResults, this._newModuleName);
542
+ this._textEditTracker.addEditWithTextRange(parseResults, moduleNameNode, this._newModuleName);
428
543
  continue;
429
544
  }
430
545
  if ((0, parseTreeUtils_1.isImportAlias)(nodeFound)) {
431
546
  // ex) import xxx as [yyy] to import xxx as [zzz]
432
- this._addResultWithTextRange(filePath, result.range, parseResults, this._newLastModuleName);
547
+ this._textEditTracker.addEditWithTextRange(parseResults, result.range, this._newLastModuleName);
433
548
  continue;
434
549
  }
435
550
  if ((0, parseTreeUtils_1.isFromImportModuleName)(nodeFound)) {
@@ -456,7 +571,7 @@ class RenameModuleProvider {
456
571
  // We don't have any sub modules, we can change module name to new one.
457
572
  // Update whole module name to new name.
458
573
  // ex) from [xxx.yyy] import zzz to from [aaa.bbb] import zzz
459
- this._addResultWithTextRange(filePath, moduleNameNode, parseResults, this._getNewModuleName(filePath, moduleNameNode.leadingDots > 0,
574
+ this._textEditTracker.addEditWithTextRange(parseResults, moduleNameNode, this._getNewModuleName(filePath, moduleNameNode.leadingDots > 0,
460
575
  /* isLastPartImportName */ false));
461
576
  continue;
462
577
  }
@@ -470,31 +585,32 @@ class RenameModuleProvider {
470
585
  // Update module name if needed.
471
586
  if (fromNode.module.leadingDots > 0) {
472
587
  for (const edit of this._getNewRelativeModuleNamesForFileMoved(filePath, [fromNode.module])) {
473
- this._addResultWithTextRange(filePath, edit.moduleName, parseResults, edit.newModuleName);
588
+ this._textEditTracker.addEditWithTextRange(parseResults, edit.moduleName, edit.newModuleName);
474
589
  }
475
590
  }
476
591
  // First, delete existing exported symbols from "from import" statement.
477
592
  for (const importFromAs of exportedSymbols) {
478
- this._addFromImportNameDeletion(filePath, parseResults, nameRemoved, fromNode.imports, importFromAs);
593
+ this._textEditTracker.deleteImportName(parseResults, importFromAs);
479
594
  }
480
595
  importStatements =
481
596
  importStatements !== null && importStatements !== void 0 ? importStatements : (0, importStatementUtils_1.getTopLevelImports)(parseResults.parseTree, /* includeImplicitImports */ false);
482
597
  // For now, this won't merge absolute and relative path "from import"
483
598
  // statement.
484
- this._addResultEdits(this._getTextEditsForNewOrExistingFromImport(filePath, fromNode, parseResults, nameRemoved, importStatements, this._newModuleName, exportedSymbols.map((i) => {
599
+ this._textEditTracker.addOrUpdateImport(parseResults, importStatements, { name: this._newModuleName }, (0, importStatementUtils_1.getImportGroupFromModuleNameAndType)(this._newModuleNameAndType), exportedSymbols.map((i) => {
485
600
  var _a;
486
- const name = results.findIndex((r) => r.node === i.name) >= 0
487
- ? this._newLastModuleName
488
- : i.name.value;
601
+ const name = results.findIndex((r) => r.node === i.name) >= 0 ? this._newLastModuleName : i.name.value;
489
602
  const alias = results.findIndex((r) => r.node === i.alias) >= 0
490
603
  ? this._newLastModuleName
491
604
  : (_a = i.alias) === null || _a === void 0 ? void 0 : _a.value;
492
605
  return { name, alias };
493
- })));
606
+ }), {
607
+ currentFromImport: fromNode,
608
+ originalModuleName: this._moduleName,
609
+ });
494
610
  continue;
495
611
  }
496
612
  if ((0, parseTreeUtils_1.isFromImportName)(nodeFound)) {
497
- if (nameRemoved.has(nodeFound.id)) {
613
+ if (this._textEditTracker.isNodeRemoved(nodeFound)) {
498
614
  // Import name is already removed.
499
615
  continue;
500
616
  }
@@ -505,13 +621,13 @@ class RenameModuleProvider {
505
621
  // Existing logic should make sure re-exported symbol name work as before after
506
622
  // symbol rename.
507
623
  if (this._isExportedSymbol(nodeFound)) {
508
- this._addResultWithTextRange(filePath, result.range, parseResults, this._newLastModuleName);
624
+ this._textEditTracker.addEditWithTextRange(parseResults, result.range, this._newLastModuleName);
509
625
  continue;
510
626
  }
511
627
  if (fromNode.imports.length === 1) {
512
628
  // ex) from xxx import [yyy] to from [aaa.bbb] import [zzz]
513
- this._addResultWithTextRange(filePath, fromNode.module, parseResults, newModuleName);
514
- this._addResultWithTextRange(filePath, result.range, parseResults, this._newLastModuleName);
629
+ this._textEditTracker.addEditWithTextRange(parseResults, fromNode.module, newModuleName);
630
+ this._textEditTracker.addEditWithTextRange(parseResults, result.range, this._newLastModuleName);
515
631
  }
516
632
  else {
517
633
  // Delete the existing import name including alias.
@@ -519,10 +635,10 @@ class RenameModuleProvider {
519
635
  // Update module name if needed.
520
636
  if (fromNode.module.leadingDots > 0) {
521
637
  for (const edit of this._getNewRelativeModuleNamesForFileMoved(filePath, [fromNode.module])) {
522
- this._addResultWithTextRange(filePath, edit.moduleName, parseResults, edit.newModuleName);
638
+ this._textEditTracker.addEditWithTextRange(parseResults, edit.moduleName, edit.newModuleName);
523
639
  }
524
640
  }
525
- this._addFromImportNameDeletion(filePath, parseResults, nameRemoved, fromNode.imports, importFromAs);
641
+ this._textEditTracker.deleteImportName(parseResults, importFromAs);
526
642
  importStatements =
527
643
  importStatements !== null && importStatements !== void 0 ? importStatements : (0, importStatementUtils_1.getTopLevelImports)(parseResults.parseTree, /* includeImplicitImports */ false);
528
644
  // ex) from xxx import yyy, [zzz] to
@@ -541,17 +657,20 @@ class RenameModuleProvider {
541
657
  ? this._newLastModuleName
542
658
  : (_d = importFromAs.alias) === null || _d === void 0 ? void 0 : _d.value,
543
659
  };
544
- this._addResultEdits(this._getTextEditsForNewOrExistingFromImport(filePath, fromNode, parseResults, nameRemoved, importStatements, newModuleName, [importNameInfo]));
660
+ this._textEditTracker.addOrUpdateImport(parseResults, importStatements, { name: this._newModuleName, nameForImportFrom: newModuleName }, (0, importStatementUtils_1.getImportGroupFromModuleNameAndType)(this._newModuleNameAndType), [importNameInfo], {
661
+ currentFromImport: fromNode,
662
+ originalModuleName: this._moduleName,
663
+ });
545
664
  }
546
665
  continue;
547
666
  }
548
667
  if ((0, parseTreeUtils_1.isFromImportAlias)(nodeFound)) {
549
- if (nameRemoved.has(nodeFound.id)) {
668
+ if (this._textEditTracker.isNodeRemoved(nodeFound)) {
550
669
  // alias is already removed.
551
670
  continue;
552
671
  }
553
672
  // ex) from ccc import xxx as [yyy] to from ccc import xxx as [zzz]
554
- this._addResultWithTextRange(filePath, result.range, parseResults, this._newLastModuleName);
673
+ this._textEditTracker.addEditWithTextRange(parseResults, result.range, this._newLastModuleName);
555
674
  continue;
556
675
  }
557
676
  /** TODO: if we get more than 1 decls, flag it as attention needed */
@@ -561,7 +680,7 @@ class RenameModuleProvider {
561
680
  // Simple case. only name has changed. but not path.
562
681
  // Just replace name to new symbol name.
563
682
  // ex) a.[b].foo() to a.[z].foo()
564
- this._addResultWithTextRange(filePath, result.range, parseResults, this._newLastModuleName);
683
+ this._textEditTracker.addEditWithTextRange(parseResults, result.range, this._newLastModuleName);
565
684
  continue;
566
685
  }
567
686
  if (decls === null || decls === void 0 ? void 0 : decls.some((d) => !d.usesLocalName &&
@@ -570,7 +689,7 @@ class RenameModuleProvider {
570
689
  const dottedName = (0, parseTreeUtils_1.getDottedNameWithGivenNodeAsLastName)(nodeFound);
571
690
  if (((_e = dottedName.parent) === null || _e === void 0 ? void 0 : _e.nodeType) !== 35 /* MemberAccess */) {
572
691
  // Replace whole dotted name with new module name.
573
- this._addResultWithTextRange(filePath, dottedName, parseResults, this._newModuleName);
692
+ this._textEditTracker.addEditWithTextRange(parseResults, dottedName, this._newModuleName);
574
693
  continue;
575
694
  }
576
695
  // Check whether name after me is sub module or not.
@@ -586,11 +705,11 @@ class RenameModuleProvider {
586
705
  // Next name is actual symbol. Replace whole name to new module name.
587
706
  // ex) import a.b.c
588
707
  // [a.b.c].[foo]()
589
- this._addResultWithTextRange(filePath, dottedName, parseResults, this._newModuleName);
708
+ this._textEditTracker.addEditWithTextRange(parseResults, dottedName, this._newModuleName);
590
709
  continue;
591
710
  }
592
711
  if (result.node.value !== this._newLastModuleName) {
593
- this._addResultWithTextRange(filePath, result.range, parseResults, this._newLastModuleName);
712
+ this._textEditTracker.addEditWithTextRange(parseResults, result.range, this._newLastModuleName);
594
713
  continue;
595
714
  }
596
715
  }
@@ -705,12 +824,6 @@ class RenameModuleProvider {
705
824
  // ex) x.y.z used in "from x.y.z import ..."
706
825
  return moduleName;
707
826
  }
708
- getEdits() {
709
- return this._textEditTracker.getEdits(this._token);
710
- }
711
- get lastModuleName() {
712
- return this._moduleNames[this._moduleNames.length - 1];
713
- }
714
827
  get _moduleName() {
715
828
  return this._moduleNameAndType.moduleName;
716
829
  }
@@ -720,108 +833,6 @@ class RenameModuleProvider {
720
833
  get _newModuleName() {
721
834
  return this._newModuleNameAndType.moduleName;
722
835
  }
723
- _addImportNameDeletion(filePath, parseResults, nameRemoved, imports, importToDelete) {
724
- this._addImportNameDeletionInternal(filePath, parseResults, nameRemoved, imports, importToDelete, 20 /* Import */);
725
- // Mark that we don't need to process these node again later.
726
- nameRemoved.add(importToDelete.module.id);
727
- importToDelete.module.nameParts.forEach((n) => nameRemoved.add(n.id));
728
- if (importToDelete.alias) {
729
- nameRemoved.add(importToDelete.alias.id);
730
- }
731
- }
732
- _addFromImportNameDeletion(filePath, parseResults, nameRemoved, imports, importToDelete) {
733
- this._addImportNameDeletionInternal(filePath, parseResults, nameRemoved, imports, importToDelete, 22 /* ImportFrom */);
734
- // Mark that we don't need to process these node again later.
735
- nameRemoved.add(importToDelete.name.id);
736
- if (importToDelete.alias) {
737
- nameRemoved.add(importToDelete.alias.id);
738
- }
739
- }
740
- _addImportNameDeletionInternal(filePath, parseResults, nameRemoved, imports, importToDelete, importKind) {
741
- const ranges = (0, importStatementUtils_1.getTextRangeForImportNameDeletion)(imports, imports.findIndex((v) => v === importToDelete));
742
- ranges.forEach((r) => this._addResultWithTextRange(filePath, r, parseResults, ''));
743
- // Mark that we don't need to process these node again later.
744
- nameRemoved.add(importToDelete.id);
745
- // Check whether we have deleted all trailing import names.
746
- // If either no trailing import is deleted or handled properly
747
- // then, there is nothing to do. otherwise, either delete the whole statement
748
- // or remove trailing comma.
749
- // ex) from x import [y], z or from x import y[, z]
750
- let lastImportIndexNotDeleted = 0;
751
- for (lastImportIndexNotDeleted = imports.length - 1; lastImportIndexNotDeleted >= 0; lastImportIndexNotDeleted--) {
752
- if (!nameRemoved.has(imports[lastImportIndexNotDeleted].id)) {
753
- break;
754
- }
755
- }
756
- if (lastImportIndexNotDeleted === -1) {
757
- // Whole statement is deleted. Remove the statement itself.
758
- // ex) [from x import a, b, c] or [import a]
759
- const importStatement = (0, parseTreeUtils_1.getFirstAncestorOrSelfOfKind)(importToDelete, importKind);
760
- if (importStatement) {
761
- this._textEditTracker.addEdit(filePath, (0, parseTreeUtils_1.getFullStatementRange)(importStatement, parseResults.tokenizerOutput), '');
762
- }
763
- }
764
- else if (lastImportIndexNotDeleted >= 0 && lastImportIndexNotDeleted < imports.length - 2) {
765
- // We need to delete trailing comma
766
- // ex) from x import a, [b, c]
767
- const start = textRange_1.TextRange.getEnd(imports[lastImportIndexNotDeleted]);
768
- const length = textRange_1.TextRange.getEnd(imports[lastImportIndexNotDeleted + 1]) - start;
769
- this._addResultWithTextRange(filePath, { start, length }, parseResults, '');
770
- }
771
- }
772
- _addResultWithTextRange(filePath, range, parseResults, newName) {
773
- const existing = parseResults.text.substr(range.start, range.length);
774
- if (existing === newName) {
775
- // No change. Return as it is.
776
- return;
777
- }
778
- this._textEditTracker.addEdit(filePath, (0, positionUtils_1.convertTextRangeToRange)(range, parseResults.tokenizerOutput.lines), newName);
779
- }
780
- _addResultEdits(edits) {
781
- this._textEditTracker.addEdits(...edits);
782
- }
783
- _getTextEditsForNewOrExistingFromImport(filePath, currentFromImport, parseResults, nameRemoved, importStatements, moduleName, importNameInfo) {
784
- // See whether we have existing from import statement for the same module
785
- // ex) from [|moduleName|] import subModule
786
- const imported = importStatements.orderedImports.find((i) => i.moduleName === moduleName);
787
- if (imported && imported.node.nodeType === 22 /* ImportFrom */ && !imported.node.isWildcardImport) {
788
- const edits = (0, importStatementUtils_1.getTextEditsForAutoImportSymbolAddition)(importNameInfo, imported, parseResults);
789
- if (imported.node !== currentFromImport) {
790
- // Add what we want to the existing "import from" statement as long as it is not the same import
791
- // node we are working on.
792
- return edits.map((e) => ({ filePath, range: e.range, replacementText: e.replacementText }));
793
- }
794
- // Check whether we can avoid creating a new statement. We can't just merge with existing one since
795
- // we could create invalid text edits (2 edits that change the same span, or invalid replacement text since
796
- // texts on the node has changed)
797
- if (this._onlyNameChanged && importNameInfo.length === 1 && edits.length === 1) {
798
- const deletions = this._textEditTracker.getDeletionsForSpan(filePath, edits[0].range);
799
- if (deletions.length === 0) {
800
- return [{ filePath, range: edits[0].range, replacementText: edits[0].replacementText }];
801
- }
802
- else {
803
- const alias = importNameInfo[0].alias === this._newLastModuleName
804
- ? this.lastModuleName
805
- : importNameInfo[0].alias;
806
- const importName = currentFromImport.imports.find((i) => { var _a; return i.name.value === this.lastModuleName && ((_a = i.alias) === null || _a === void 0 ? void 0 : _a.value) === alias; });
807
- if (importName) {
808
- this._textEditTracker.removeEdits(filePath, deletions);
809
- if (importName.alias) {
810
- nameRemoved.delete(importName.alias.id);
811
- }
812
- return [
813
- {
814
- filePath,
815
- range: (0, positionUtils_1.convertTextRangeToRange)(importName.name, parseResults.tokenizerOutput.lines),
816
- replacementText: this._newLastModuleName,
817
- },
818
- ];
819
- }
820
- }
821
- }
822
- }
823
- return (0, importStatementUtils_1.getTextEditsForAutoImportInsertion)(importNameInfo, { name: moduleName }, importStatements, (0, importStatementUtils_1.getImportGroupFromModuleNameAndType)(this._newModuleNameAndType), parseResults, (0, positionUtils_1.convertOffsetToPosition)(parseResults.parseTree.length, parseResults.tokenizerOutput.lines)).map((e) => ({ filePath, range: e.range, replacementText: e.replacementText }));
824
- }
825
836
  }
826
837
  exports.RenameModuleProvider = RenameModuleProvider;
827
838
  class ModuleNameCollector extends parseTreeWalker_1.ParseTreeWalker {