@zzzen/pyright-internal 1.2.0-dev.20230430 → 1.2.0-dev.20230514

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 (231) hide show
  1. package/dist/analyzer/backgroundAnalysisProgram.d.ts +4 -1
  2. package/dist/analyzer/backgroundAnalysisProgram.js +12 -0
  3. package/dist/analyzer/backgroundAnalysisProgram.js.map +1 -1
  4. package/dist/analyzer/checker.d.ts +1 -0
  5. package/dist/analyzer/checker.js +89 -6
  6. package/dist/analyzer/checker.js.map +1 -1
  7. package/dist/analyzer/constraintSolver.js +14 -15
  8. package/dist/analyzer/constraintSolver.js.map +1 -1
  9. package/dist/analyzer/constructors.d.ts +6 -0
  10. package/dist/analyzer/constructors.js +513 -0
  11. package/dist/analyzer/constructors.js.map +1 -0
  12. package/dist/analyzer/dataClasses.js +86 -2
  13. package/dist/analyzer/dataClasses.js.map +1 -1
  14. package/dist/analyzer/docStringConversion.js +1 -1
  15. package/dist/analyzer/docStringConversion.js.map +1 -1
  16. package/dist/analyzer/enums.js +62 -8
  17. package/dist/analyzer/enums.js.map +1 -1
  18. package/dist/analyzer/importResolver.js +47 -29
  19. package/dist/analyzer/importResolver.js.map +1 -1
  20. package/dist/analyzer/importStatementUtils.d.ts +2 -2
  21. package/dist/analyzer/importStatementUtils.js.map +1 -1
  22. package/dist/analyzer/namedTuples.js +3 -6
  23. package/dist/analyzer/namedTuples.js.map +1 -1
  24. package/dist/analyzer/operations.d.ts +16 -0
  25. package/dist/analyzer/operations.js +749 -0
  26. package/dist/analyzer/operations.js.map +1 -0
  27. package/dist/analyzer/parseTreeUtils.d.ts +4 -2
  28. package/dist/analyzer/parseTreeUtils.js +32 -1
  29. package/dist/analyzer/parseTreeUtils.js.map +1 -1
  30. package/dist/analyzer/patternMatching.js +16 -0
  31. package/dist/analyzer/patternMatching.js.map +1 -1
  32. package/dist/analyzer/program.d.ts +11 -33
  33. package/dist/analyzer/program.js +73 -735
  34. package/dist/analyzer/program.js.map +1 -1
  35. package/dist/analyzer/protocols.js +1 -1
  36. package/dist/analyzer/protocols.js.map +1 -1
  37. package/dist/analyzer/service.d.ts +5 -21
  38. package/dist/analyzer/service.js +26 -33
  39. package/dist/analyzer/service.js.map +1 -1
  40. package/dist/analyzer/sourceFile.d.ts +9 -41
  41. package/dist/analyzer/sourceFile.js +219 -238
  42. package/dist/analyzer/sourceFile.js.map +1 -1
  43. package/dist/analyzer/sourceFileInfoUtils.d.ts +3 -9
  44. package/dist/analyzer/sourceFileInfoUtils.js.map +1 -1
  45. package/dist/analyzer/symbol.d.ts +3 -1
  46. package/dist/analyzer/symbol.js +5 -0
  47. package/dist/analyzer/symbol.js.map +1 -1
  48. package/dist/analyzer/typeEvaluator.js +460 -1425
  49. package/dist/analyzer/typeEvaluator.js.map +1 -1
  50. package/dist/analyzer/typeEvaluatorTypes.d.ts +42 -7
  51. package/dist/analyzer/typeEvaluatorTypes.js +33 -1
  52. package/dist/analyzer/typeEvaluatorTypes.js.map +1 -1
  53. package/dist/analyzer/typeGuards.js +2 -8
  54. package/dist/analyzer/typeGuards.js.map +1 -1
  55. package/dist/analyzer/typePrinter.d.ts +3 -3
  56. package/dist/analyzer/typePrinter.js +247 -100
  57. package/dist/analyzer/typePrinter.js.map +1 -1
  58. package/dist/analyzer/typeUtils.d.ts +14 -7
  59. package/dist/analyzer/typeUtils.js +204 -49
  60. package/dist/analyzer/typeUtils.js.map +1 -1
  61. package/dist/analyzer/typeVarContext.d.ts +6 -7
  62. package/dist/analyzer/typeVarContext.js +21 -32
  63. package/dist/analyzer/typeVarContext.js.map +1 -1
  64. package/dist/analyzer/typedDicts.js +2 -2
  65. package/dist/analyzer/typedDicts.js.map +1 -1
  66. package/dist/analyzer/types.d.ts +7 -4
  67. package/dist/analyzer/types.js +20 -10
  68. package/dist/analyzer/types.js.map +1 -1
  69. package/dist/backgroundAnalysisBase.d.ts +1 -1
  70. package/dist/backgroundAnalysisBase.js +16 -0
  71. package/dist/backgroundAnalysisBase.js.map +1 -1
  72. package/dist/commands/dumpFileDebugInfoCommand.js +0 -1
  73. package/dist/commands/dumpFileDebugInfoCommand.js.map +1 -1
  74. package/dist/common/extensibility.d.ts +28 -4
  75. package/dist/common/extensibility.js.map +1 -1
  76. package/dist/common/logTracker.d.ts +2 -0
  77. package/dist/common/logTracker.js +8 -1
  78. package/dist/common/logTracker.js.map +1 -1
  79. package/dist/common/lspUtils.d.ts +4 -1
  80. package/dist/common/lspUtils.js +38 -1
  81. package/dist/common/lspUtils.js.map +1 -1
  82. package/dist/common/pathUtils.d.ts +11 -11
  83. package/dist/common/pathUtils.js.map +1 -1
  84. package/dist/common/pythonVersion.d.ts +2 -1
  85. package/dist/common/pythonVersion.js +1 -0
  86. package/dist/common/pythonVersion.js.map +1 -1
  87. package/dist/common/workspaceEditUtils.d.ts +8 -8
  88. package/dist/common/workspaceEditUtils.js +10 -10
  89. package/dist/common/workspaceEditUtils.js.map +1 -1
  90. package/dist/languageServerBase.d.ts +3 -7
  91. package/dist/languageServerBase.js +41 -73
  92. package/dist/languageServerBase.js.map +1 -1
  93. package/dist/languageService/autoImporter.d.ts +50 -51
  94. package/dist/languageService/autoImporter.js +125 -210
  95. package/dist/languageService/autoImporter.js.map +1 -1
  96. package/dist/languageService/callHierarchyProvider.d.ts +1 -1
  97. package/dist/languageService/callHierarchyProvider.js +11 -37
  98. package/dist/languageService/callHierarchyProvider.js.map +1 -1
  99. package/dist/languageService/completionProvider.d.ts +39 -81
  100. package/dist/languageService/completionProvider.js +572 -801
  101. package/dist/languageService/completionProvider.js.map +1 -1
  102. package/dist/languageService/documentHighlightProvider.js +1 -1
  103. package/dist/languageService/documentHighlightProvider.js.map +1 -1
  104. package/dist/languageService/documentSymbolCollector.d.ts +6 -7
  105. package/dist/languageService/documentSymbolCollector.js +47 -28
  106. package/dist/languageService/documentSymbolCollector.js.map +1 -1
  107. package/dist/languageService/documentSymbolProvider.d.ts +13 -35
  108. package/dist/languageService/documentSymbolProvider.js +52 -264
  109. package/dist/languageService/documentSymbolProvider.js.map +1 -1
  110. package/dist/languageService/hoverProvider.d.ts +5 -6
  111. package/dist/languageService/hoverProvider.js +40 -132
  112. package/dist/languageService/hoverProvider.js.map +1 -1
  113. package/dist/languageService/referencesProvider.d.ts +6 -11
  114. package/dist/languageService/referencesProvider.js +23 -17
  115. package/dist/languageService/referencesProvider.js.map +1 -1
  116. package/dist/languageService/renameProvider.d.ts +16 -0
  117. package/dist/languageService/renameProvider.js +139 -0
  118. package/dist/languageService/renameProvider.js.map +1 -0
  119. package/dist/languageService/symbolIndexer.d.ts +31 -0
  120. package/dist/languageService/symbolIndexer.js +105 -0
  121. package/dist/languageService/symbolIndexer.js.map +1 -0
  122. package/dist/languageService/tooltipUtils.d.ts +8 -1
  123. package/dist/languageService/tooltipUtils.js +102 -1
  124. package/dist/languageService/tooltipUtils.js.map +1 -1
  125. package/dist/languageService/workspaceSymbolProvider.d.ts +17 -0
  126. package/dist/languageService/workspaceSymbolProvider.js +133 -0
  127. package/dist/languageService/workspaceSymbolProvider.js.map +1 -0
  128. package/dist/localization/localize.d.ts +33 -15
  129. package/dist/localization/localize.js +13 -7
  130. package/dist/localization/localize.js.map +1 -1
  131. package/dist/localization/package.nls.en-us.json +14 -7
  132. package/dist/parser/parser.js +3 -0
  133. package/dist/parser/parser.js.map +1 -1
  134. package/dist/pyright.js +26 -4
  135. package/dist/pyright.js.map +1 -1
  136. package/dist/tests/chainedSourceFiles.test.js +15 -20
  137. package/dist/tests/chainedSourceFiles.test.js.map +1 -1
  138. package/dist/tests/checker.test.js +14 -0
  139. package/dist/tests/checker.test.js.map +1 -1
  140. package/dist/tests/completions.test.js +11 -236
  141. package/dist/tests/completions.test.js.map +1 -1
  142. package/dist/tests/docStringConversion.test.js +36 -2
  143. package/dist/tests/docStringConversion.test.js.map +1 -1
  144. package/dist/tests/documentSymbolCollector.test.js +3 -3
  145. package/dist/tests/documentSymbolCollector.test.js.map +1 -1
  146. package/dist/tests/fourslash/completions.override2.fourslash.js +1 -16
  147. package/dist/tests/fourslash/completions.override2.fourslash.js.map +1 -1
  148. package/dist/tests/fourslash/fourslash.d.ts +4 -4
  149. package/dist/tests/fourslash/missingTypeStub.codeAction.fourslash.js +1 -1
  150. package/dist/tests/fourslash/missingTypeStub.codeAction.fourslash.js.map +1 -1
  151. package/dist/tests/harness/fourslash/testState.d.ts +17 -11
  152. package/dist/tests/harness/fourslash/testState.js +39 -50
  153. package/dist/tests/harness/fourslash/testState.js.map +1 -1
  154. package/dist/tests/importResolver.test.js +81 -1
  155. package/dist/tests/importResolver.test.js.map +1 -1
  156. package/dist/tests/sourceFile.test.js +1 -1
  157. package/dist/tests/sourceFile.test.js.map +1 -1
  158. package/dist/tests/testStateUtils.d.ts +2 -2
  159. package/dist/tests/testStateUtils.js +38 -8
  160. package/dist/tests/testStateUtils.js.map +1 -1
  161. package/dist/tests/typeEvaluator2.test.js +13 -1
  162. package/dist/tests/typeEvaluator2.test.js.map +1 -1
  163. package/dist/tests/typeEvaluator3.test.js +5 -1
  164. package/dist/tests/typeEvaluator3.test.js.map +1 -1
  165. package/dist/tests/typeEvaluator4.test.js +9 -1
  166. package/dist/tests/typeEvaluator4.test.js.map +1 -1
  167. package/dist/tests/typeEvaluator5.test.js +25 -9
  168. package/dist/tests/typeEvaluator5.test.js.map +1 -1
  169. package/dist/tests/workspaceEditUtils.test.js +95 -6
  170. package/dist/tests/workspaceEditUtils.test.js.map +1 -1
  171. package/package.json +4 -4
  172. package/dist/languageService/importAdder.d.ts +0 -40
  173. package/dist/languageService/importAdder.js +0 -388
  174. package/dist/languageService/importAdder.js.map +0 -1
  175. package/dist/languageService/indentationUtils.d.ts +0 -16
  176. package/dist/languageService/indentationUtils.js +0 -727
  177. package/dist/languageService/indentationUtils.js.map +0 -1
  178. package/dist/languageService/insertionPointUtils.d.ts +0 -9
  179. package/dist/languageService/insertionPointUtils.js +0 -132
  180. package/dist/languageService/insertionPointUtils.js.map +0 -1
  181. package/dist/languageService/renameModuleProvider.d.ts +0 -65
  182. package/dist/languageService/renameModuleProvider.js +0 -939
  183. package/dist/languageService/renameModuleProvider.js.map +0 -1
  184. package/dist/tests/fourslash/completions.commitChars.fourslash.d.ts +0 -1
  185. package/dist/tests/fourslash/completions.commitChars.fourslash.js +0 -81
  186. package/dist/tests/fourslash/completions.commitChars.fourslash.js.map +0 -1
  187. package/dist/tests/importAdder.test.d.ts +0 -1
  188. package/dist/tests/importAdder.test.js +0 -1325
  189. package/dist/tests/importAdder.test.js.map +0 -1
  190. package/dist/tests/indentationUtils.ptvs.test.d.ts +0 -1
  191. package/dist/tests/indentationUtils.ptvs.test.js +0 -324
  192. package/dist/tests/indentationUtils.ptvs.test.js.map +0 -1
  193. package/dist/tests/indentationUtils.reindent.test.d.ts +0 -1
  194. package/dist/tests/indentationUtils.reindent.test.js +0 -372
  195. package/dist/tests/indentationUtils.reindent.test.js.map +0 -1
  196. package/dist/tests/indentationUtils.test.d.ts +0 -1
  197. package/dist/tests/indentationUtils.test.js +0 -502
  198. package/dist/tests/indentationUtils.test.js.map +0 -1
  199. package/dist/tests/insertionPointUtils.test.d.ts +0 -1
  200. package/dist/tests/insertionPointUtils.test.js +0 -154
  201. package/dist/tests/insertionPointUtils.test.js.map +0 -1
  202. package/dist/tests/moveSymbol.importAdder.test.d.ts +0 -1
  203. package/dist/tests/moveSymbol.importAdder.test.js +0 -298
  204. package/dist/tests/moveSymbol.importAdder.test.js.map +0 -1
  205. package/dist/tests/moveSymbol.insertion.test.d.ts +0 -1
  206. package/dist/tests/moveSymbol.insertion.test.js +0 -537
  207. package/dist/tests/moveSymbol.insertion.test.js.map +0 -1
  208. package/dist/tests/moveSymbol.misc.test.d.ts +0 -1
  209. package/dist/tests/moveSymbol.misc.test.js +0 -169
  210. package/dist/tests/moveSymbol.misc.test.js.map +0 -1
  211. package/dist/tests/moveSymbol.updateReference.test.d.ts +0 -1
  212. package/dist/tests/moveSymbol.updateReference.test.js +0 -1071
  213. package/dist/tests/moveSymbol.updateReference.test.js.map +0 -1
  214. package/dist/tests/renameModule.folder.test.d.ts +0 -1
  215. package/dist/tests/renameModule.folder.test.js +0 -229
  216. package/dist/tests/renameModule.folder.test.js.map +0 -1
  217. package/dist/tests/renameModule.fromImports.test.d.ts +0 -1
  218. package/dist/tests/renameModule.fromImports.test.js +0 -790
  219. package/dist/tests/renameModule.fromImports.test.js.map +0 -1
  220. package/dist/tests/renameModule.imports.test.d.ts +0 -1
  221. package/dist/tests/renameModule.imports.test.js +0 -380
  222. package/dist/tests/renameModule.imports.test.js.map +0 -1
  223. package/dist/tests/renameModule.misc.test.d.ts +0 -1
  224. package/dist/tests/renameModule.misc.test.js +0 -615
  225. package/dist/tests/renameModule.misc.test.js.map +0 -1
  226. package/dist/tests/renameModule.relativePath.test.d.ts +0 -1
  227. package/dist/tests/renameModule.relativePath.test.js +0 -231
  228. package/dist/tests/renameModule.relativePath.test.js.map +0 -1
  229. package/dist/tests/renameModuleTestUtils.d.ts +0 -4
  230. package/dist/tests/renameModuleTestUtils.js +0 -76
  231. package/dist/tests/renameModuleTestUtils.js.map +0 -1
@@ -30,9 +30,8 @@ var __importStar = (this && this.__importStar) || function (mod) {
30
30
  Object.defineProperty(exports, "__esModule", { value: true });
31
31
  exports.Program = exports.MaxWorkspaceIndexFileCount = void 0;
32
32
  const vscode_languageserver_1 = require("vscode-languageserver");
33
- const vscode_languageserver_types_1 = require("vscode-languageserver-types");
33
+ const vscode_languageserver_textdocument_1 = require("vscode-languageserver-textdocument");
34
34
  const cancellationUtils_1 = require("../common/cancellationUtils");
35
- const collectionUtils_1 = require("../common/collectionUtils");
36
35
  const configOptions_1 = require("../common/configOptions");
37
36
  const console_1 = require("../common/console");
38
37
  const debug = __importStar(require("../common/debug"));
@@ -41,30 +40,15 @@ const extensibility_1 = require("../common/extensibility");
41
40
  const logTracker_1 = require("../common/logTracker");
42
41
  const pathUtils_1 = require("../common/pathUtils");
43
42
  const positionUtils_1 = require("../common/positionUtils");
44
- const stringUtils_1 = require("../common/stringUtils");
45
- const textEditTracker_1 = require("../common/textEditTracker");
46
43
  const textRange_1 = require("../common/textRange");
47
- const textRangeCollection_1 = require("../common/textRangeCollection");
48
44
  const timing_1 = require("../common/timing");
49
- const workspaceEditUtils_1 = require("../common/workspaceEditUtils");
50
- const autoImporter_1 = require("../languageService/autoImporter");
51
- const completionProvider_1 = require("../languageService/completionProvider");
52
- const documentSymbolCollector_1 = require("../languageService/documentSymbolCollector");
53
- const importAdder_1 = require("../languageService/importAdder");
54
- const indentationUtils_1 = require("../languageService/indentationUtils");
55
- const insertionPointUtils_1 = require("../languageService/insertionPointUtils");
56
- const referencesProvider_1 = require("../languageService/referencesProvider");
57
- const renameModuleProvider_1 = require("../languageService/renameModuleProvider");
58
45
  const AnalyzerNodeInfo = __importStar(require("./analyzerNodeInfo"));
59
46
  const cacheManager_1 = require("./cacheManager");
60
47
  const circularDependency_1 = require("./circularDependency");
61
- const declaration_1 = require("./declaration");
62
48
  const parseTreeUtils_1 = require("./parseTreeUtils");
63
- const scopeUtils_1 = require("./scopeUtils");
64
49
  const sourceFile_1 = require("./sourceFile");
65
50
  const sourceFileInfoUtils_1 = require("./sourceFileInfoUtils");
66
51
  const sourceMapper_1 = require("./sourceMapper");
67
- const symbolNameUtils_1 = require("./symbolNameUtils");
68
52
  const tracePrinter_1 = require("./tracePrinter");
69
53
  const typeEvaluatorWithTracker_1 = require("./typeEvaluatorWithTracker");
70
54
  const typeStubWriter_1 = require("./typeStubWriter");
@@ -82,6 +66,7 @@ class Program {
82
66
  this._sourceFileList = [];
83
67
  this._sourceFileMap = new Map();
84
68
  this._parsedFileCount = 0;
69
+ this._isEditMode = false;
85
70
  this._lookUpImport = (filePathOrModule, options) => {
86
71
  var _a;
87
72
  let sourceFileInfo;
@@ -171,6 +156,41 @@ class Program {
171
156
  dispose() {
172
157
  this._cacheManager.unregisterCacheOwner(this);
173
158
  }
159
+ enterEditMode() {
160
+ // Keep track of edit mode so we can apply it to new source files.
161
+ this._isEditMode = true;
162
+ // Tell all source files we're in edit mode.
163
+ this._sourceFileList.forEach((sourceFile) => {
164
+ sourceFile.sourceFile.enterEditMode();
165
+ });
166
+ }
167
+ exitEditMode() {
168
+ // Tell all source files we're no longer in edit mode. Gather
169
+ // up all of their edits.
170
+ const edits = [];
171
+ this._sourceFileList.forEach((sourceFile) => {
172
+ const newContents = sourceFile.sourceFile.exitEditMode();
173
+ if (newContents) {
174
+ // This means this source file was modified. We need to recompute its imports after
175
+ // we put it back to how it was.
176
+ this._updateSourceFileImports(sourceFile, this.configOptions);
177
+ // Create a text document so we can compute the edits.
178
+ const textDocument = vscode_languageserver_textdocument_1.TextDocument.create(sourceFile.sourceFile.getFilePath(), 'python', 1, sourceFile.sourceFile.getFileContent() || '');
179
+ // Add an edit action to the list.
180
+ edits.push({
181
+ filePath: sourceFile.sourceFile.getFilePath(),
182
+ range: {
183
+ start: { line: 0, character: 0 },
184
+ end: { line: textDocument.lineCount, character: 0 },
185
+ },
186
+ replacementText: newContents,
187
+ });
188
+ }
189
+ });
190
+ // Stop applying edit mode to new source files.
191
+ this._isEditMode = false;
192
+ return edits;
193
+ }
174
194
  setConfigOptions(configOptions) {
175
195
  this._configOptions = configOptions;
176
196
  this._importResolver.setConfigOptions(configOptions);
@@ -242,7 +262,7 @@ class Program {
242
262
  sourceFileInfo.isTracked = true;
243
263
  return sourceFileInfo.sourceFile;
244
264
  }
245
- const sourceFile = new sourceFile_1.SourceFile(this.fileSystem, filePath, importName, isThirdPartyImport, isInPyTypedPackage, this._console, this._logTracker);
265
+ const sourceFile = new sourceFile_1.SourceFile(this.fileSystem, filePath, importName, isThirdPartyImport, isInPyTypedPackage, this._isEditMode, this._console, this._logTracker);
246
266
  sourceFileInfo = {
247
267
  sourceFile,
248
268
  isTracked: true,
@@ -266,7 +286,7 @@ class Program {
266
286
  const importName = this._getImportNameForFile(filePath);
267
287
  const sourceFile = new sourceFile_1.SourceFile(this.fileSystem, filePath, importName,
268
288
  /* isThirdPartyImport */ false,
269
- /* isInPyTypedPackage */ false, this._console, this._logTracker, options === null || options === void 0 ? void 0 : options.realFilePath, (_a = options === null || options === void 0 ? void 0 : options.ipythonMode) !== null && _a !== void 0 ? _a : sourceFile_1.IPythonMode.None);
289
+ /* isInPyTypedPackage */ false, this._isEditMode, this._console, this._logTracker, options === null || options === void 0 ? void 0 : options.realFilePath, (_a = options === null || options === void 0 ? void 0 : options.ipythonMode) !== null && _a !== void 0 ? _a : sourceFile_1.IPythonMode.None);
270
290
  const chainedFilePath = options === null || options === void 0 ? void 0 : options.chainedFilePath;
271
291
  sourceFileInfo = {
272
292
  sourceFile,
@@ -499,59 +519,6 @@ class Program {
499
519
  return false;
500
520
  });
501
521
  }
502
- indexWorkspace(callback, token) {
503
- if (!this._configOptions.indexing) {
504
- return 0;
505
- }
506
- return this._runEvaluatorWithCancellationToken(token, () => {
507
- // Go through all workspace files to create indexing data.
508
- // This will cause all files in the workspace to be parsed and bound. But
509
- // _handleMemoryHighUsage will make sure we don't OOM and
510
- // at the end of this method, we will drop all trees and symbol tables
511
- // created due to indexing.
512
- let count = 0;
513
- const initiallyParsedSet = new Set();
514
- for (const sourceFileInfo of this._sourceFileList) {
515
- if (!sourceFileInfo.sourceFile.isParseRequired()) {
516
- initiallyParsedSet.add(sourceFileInfo);
517
- }
518
- if ((0, sourceFileInfoUtils_1.isUserCode)(sourceFileInfo) && !sourceFileInfo.sourceFile.isIndexingRequired()) {
519
- count++;
520
- }
521
- }
522
- if (count >= exports.MaxWorkspaceIndexFileCount) {
523
- // Already processed max files.
524
- return 0;
525
- }
526
- for (const sourceFileInfo of this._sourceFileList) {
527
- if (!(0, sourceFileInfoUtils_1.isUserCode)(sourceFileInfo) || !sourceFileInfo.sourceFile.isIndexingRequired()) {
528
- continue;
529
- }
530
- this._bindFile(sourceFileInfo);
531
- const results = sourceFileInfo.sourceFile.index({ indexingForAutoImportMode: false }, token);
532
- if (results) {
533
- if (++count > exports.MaxWorkspaceIndexFileCount) {
534
- this._console.warn(`Workspace indexing has hit its upper limit: 2000 files`);
535
- dropParseAndBindInfoCreatedForIndexing(this._sourceFileList, initiallyParsedSet);
536
- return count;
537
- }
538
- callback(sourceFileInfo.sourceFile.getFilePath(), results);
539
- }
540
- this._handleMemoryHighUsage();
541
- }
542
- dropParseAndBindInfoCreatedForIndexing(this._sourceFileList, initiallyParsedSet);
543
- return count;
544
- });
545
- function dropParseAndBindInfoCreatedForIndexing(sourceFiles, initiallyParsedSet) {
546
- for (const sourceFileInfo of sourceFiles) {
547
- if (sourceFileInfo.sourceFile.isParseRequired() || initiallyParsedSet.has(sourceFileInfo)) {
548
- continue;
549
- }
550
- // Drop parse and bind info created during indexing.
551
- sourceFileInfo.sourceFile.dropParseAndBindInfo();
552
- }
553
- }
554
- }
555
522
  // This will allow the callback to execute a type evaluator with an associated
556
523
  // cancellation token and provide a read-only program.
557
524
  run(callback, token) {
@@ -559,6 +526,38 @@ class Program {
559
526
  const evaluator = (_a = this._evaluator) !== null && _a !== void 0 ? _a : this._createNewEvaluator();
560
527
  return evaluator.runWithCancellationToken(token, () => callback(this));
561
528
  }
529
+ // This will allow the callback to execute a type evaluator with an associated
530
+ // cancellation token and provide a mutable program. Should already be in edit mode when called.
531
+ runWithMutation(callback, token) {
532
+ var _a;
533
+ if (this._isEditMode) {
534
+ // Create a temporary mutator that doesn't talk to the
535
+ // background thread. In edit mode there is no background thread.
536
+ const mutator = {
537
+ addInterimFile: (f) => {
538
+ return this.addInterimFile(f);
539
+ },
540
+ setFileOpened: (p, v, c, i, ch, r) => {
541
+ this.setFileOpened(p, v, c, {
542
+ isTracked: this.owns(p),
543
+ ipythonMode: i,
544
+ chainedFilePath: ch,
545
+ realFilePath: r,
546
+ });
547
+ },
548
+ updateOpenFileContents: (p, v, c, i, r) => {
549
+ this.setFileOpened(p, v, c, {
550
+ isTracked: this.owns(p),
551
+ ipythonMode: i,
552
+ chainedFilePath: undefined,
553
+ realFilePath: r,
554
+ });
555
+ },
556
+ };
557
+ const evaluator = (_a = this._evaluator) !== null && _a !== void 0 ? _a : this._createNewEvaluator();
558
+ evaluator.runWithCancellationToken(token, () => callback(this, mutator));
559
+ }
560
+ }
562
561
  getSourceMapper(filePath, token, mapCompiled, preferStubs) {
563
562
  const sourceFileInfo = this.getSourceFileInfo(filePath);
564
563
  const execEnv = this._configOptions.findExecEnvironment(filePath);
@@ -699,51 +698,6 @@ class Program {
699
698
  return fileContents.substr(textRange.start, textRange.length);
700
699
  });
701
700
  }
702
- getAutoImports(filePath, range, similarityLimit, nameMap, options, token) {
703
- const sourceFileInfo = this.getSourceFileInfo(filePath);
704
- if (!sourceFileInfo) {
705
- return [];
706
- }
707
- const sourceFile = sourceFileInfo.sourceFile;
708
- const fileContents = sourceFile.getOpenFileContents();
709
- if (fileContents === undefined) {
710
- // this only works with opened file
711
- return [];
712
- }
713
- return this._runEvaluatorWithCancellationToken(token, () => {
714
- var _a;
715
- this._bindFile(sourceFileInfo);
716
- const parseTree = sourceFile.getParseResults();
717
- const textRange = (0, positionUtils_1.convertRangeToTextRange)(range, parseTree.tokenizerOutput.lines);
718
- if (!textRange) {
719
- return [];
720
- }
721
- const currentNode = (0, parseTreeUtils_1.findNodeByOffset)(parseTree.parseTree, textRange.start);
722
- if (!currentNode) {
723
- return [];
724
- }
725
- const writtenWord = fileContents.substr(textRange.start, textRange.length);
726
- const map = this._buildModuleSymbolsMap(sourceFileInfo, options.libraryMap,
727
- /* includeSymbolsFromIndices */ true, token);
728
- options.patternMatcher =
729
- (_a = options.patternMatcher) !== null && _a !== void 0 ? _a : ((p, t) => (0, stringUtils_1.computeCompletionSimilarity)(p, t) > similarityLimit);
730
- const autoImporter = new autoImporter_1.AutoImporter(this._configOptions.findExecEnvironment(filePath), this._importResolver, parseTree, range.start, new completionProvider_1.CompletionMap(), map, options);
731
- // Filter out any name that is already defined in the current scope.
732
- const results = [];
733
- const currentScope = (0, scopeUtils_1.getScopeForNode)(currentNode);
734
- if (currentScope) {
735
- const info = nameMap === null || nameMap === void 0 ? void 0 : nameMap.get(writtenWord);
736
- if (info) {
737
- // No scope filter is needed since we only do exact match.
738
- (0, collectionUtils_1.appendArray)(results, autoImporter.getAutoImportCandidatesForAbbr(writtenWord, info, token));
739
- }
740
- results.push(...autoImporter
741
- .getAutoImportCandidates(writtenWord, similarityLimit, /* abbrFromUsers */ undefined, token)
742
- .filter((r) => !currentScope.lookUpSymbolRecursive(r.name)));
743
- }
744
- return results;
745
- });
746
- }
747
701
  getDiagnostics(options) {
748
702
  const fileDiagnostics = this._removeUnneededFiles();
749
703
  this._sourceFileList.forEach((sourceFileInfo) => {
@@ -788,396 +742,6 @@ class Program {
788
742
  return (0, textRange_1.doRangesIntersect)(diag.range, range);
789
743
  });
790
744
  }
791
- getFileIndex(filePath, options, token) {
792
- if (options.indexingForAutoImportMode) {
793
- // Memory optimization. We only want to hold onto symbols
794
- // usable outside when importSymbolsOnly is on.
795
- const name = (0, pathUtils_1.stripFileExtension)((0, pathUtils_1.getFileName)(filePath));
796
- if ((0, symbolNameUtils_1.isPrivateOrProtectedName)(name)) {
797
- return undefined;
798
- }
799
- }
800
- this._handleMemoryHighUsage();
801
- return this._runEvaluatorWithCancellationToken(token, () => {
802
- var _a;
803
- const sourceFileInfo = this.getSourceFileInfo(filePath);
804
- if (!sourceFileInfo) {
805
- return undefined;
806
- }
807
- const content = (_a = sourceFileInfo.sourceFile.getFileContent()) !== null && _a !== void 0 ? _a : '';
808
- if (options.indexingForAutoImportMode &&
809
- !options.includeAllSymbols &&
810
- !sourceFileInfo.sourceFile.isStubFile() &&
811
- !sourceFileInfo.sourceFile.isThirdPartyPyTypedPresent()) {
812
- // Perf optimization. if py file doesn't contain __all__
813
- // No need to parse and bind.
814
- if (content.indexOf('__all__') < 0) {
815
- return undefined;
816
- }
817
- }
818
- this._bindFile(sourceFileInfo, content);
819
- return sourceFileInfo.sourceFile.index(options, token);
820
- });
821
- }
822
- addSymbolsForDocument(filePath, symbolList, token) {
823
- return this._runEvaluatorWithCancellationToken(token, () => {
824
- const sourceFileInfo = this.getSourceFileInfo(filePath);
825
- if (sourceFileInfo) {
826
- if (!sourceFileInfo.sourceFile.getCachedIndexResults()) {
827
- // If we already have cached index for this file, no need to bind this file.
828
- this._bindFile(sourceFileInfo);
829
- }
830
- sourceFileInfo.sourceFile.addHierarchicalSymbolsForDocument(symbolList, token);
831
- }
832
- });
833
- }
834
- reportSymbolsForWorkspace(query, reporter, token) {
835
- this._runEvaluatorWithCancellationToken(token, () => {
836
- // Don't do a search if the query is empty. We'll return
837
- // too many results in this case.
838
- if (!query) {
839
- return;
840
- }
841
- // "Workspace symbols" searches symbols only from user code.
842
- for (const sourceFileInfo of this._sourceFileList) {
843
- if (!(0, sourceFileInfoUtils_1.isUserCode)(sourceFileInfo)) {
844
- continue;
845
- }
846
- if (!sourceFileInfo.sourceFile.getCachedIndexResults()) {
847
- // If we already have cached index for this file, no need to bind this file.
848
- this._bindFile(sourceFileInfo);
849
- }
850
- const symbolList = sourceFileInfo.sourceFile.getSymbolsForDocument(query, token);
851
- if (symbolList.length > 0) {
852
- reporter(symbolList);
853
- }
854
- // This operation can consume significant memory, so check
855
- // for situations where we need to discard the type cache.
856
- this._handleMemoryHighUsage();
857
- }
858
- });
859
- }
860
- async getCompletionsForPosition(filePath, position, workspacePath, options, nameMap, libraryMap, token) {
861
- const sourceFileInfo = this.getSourceFileInfo(filePath);
862
- if (!sourceFileInfo) {
863
- return undefined;
864
- }
865
- let sourceMapper;
866
- const completionResult = this._logTracker.log(`completion at ${filePath}:${position.line}:${position.character}`, (ls) => {
867
- var _a;
868
- const result = this._runEvaluatorWithCancellationToken(token, () => {
869
- this._bindFile(sourceFileInfo);
870
- const execEnv = this._configOptions.findExecEnvironment(filePath);
871
- sourceMapper = this._createSourceMapper(execEnv, token, sourceFileInfo, /* mapCompiled */ true);
872
- return sourceFileInfo.sourceFile.getCompletionsForPosition(position, workspacePath, this._configOptions, this._importResolver, this._lookUpImport, this._evaluator, options, sourceMapper, nameMap, libraryMap, () => this._buildModuleSymbolsMap(sourceFileInfo, libraryMap, options.includeUserSymbolsInAutoImport, token), token);
873
- });
874
- ls.add(`found ${(_a = result === null || result === void 0 ? void 0 : result.completionMap.size) !== null && _a !== void 0 ? _a : 'null'} items`);
875
- return result;
876
- });
877
- const completionResultsList = {
878
- completionList: vscode_languageserver_types_1.CompletionList.create(completionResult === null || completionResult === void 0 ? void 0 : completionResult.completionMap.toArray()),
879
- memberAccessInfo: completionResult === null || completionResult === void 0 ? void 0 : completionResult.memberAccessInfo,
880
- autoImportInfo: completionResult === null || completionResult === void 0 ? void 0 : completionResult.autoImportInfo,
881
- extensionInfo: completionResult === null || completionResult === void 0 ? void 0 : completionResult.extensionInfo,
882
- };
883
- const parseResults = sourceFileInfo.sourceFile.getParseResults();
884
- if ((parseResults === null || parseResults === void 0 ? void 0 : parseResults.parseTree) && (parseResults === null || parseResults === void 0 ? void 0 : parseResults.text)) {
885
- const offset = (0, positionUtils_1.convertPositionToOffset)(position, parseResults.tokenizerOutput.lines);
886
- if (offset !== undefined && sourceMapper) {
887
- await Promise.all(extensibility_1.Extensions.getProgramExtensions(parseResults.parseTree).map((e) => {
888
- var _a;
889
- return (_a = e.completionListExtension) === null || _a === void 0 ? void 0 : _a.updateCompletionResults(this.evaluator, sourceMapper, options, completionResultsList, parseResults, offset, this._configOptions.functionSignatureDisplay, token);
890
- }));
891
- }
892
- }
893
- return completionResultsList;
894
- }
895
- resolveCompletionItem(filePath, completionItem, options, nameMap, libraryMap, token) {
896
- return this._runEvaluatorWithCancellationToken(token, () => {
897
- const sourceFileInfo = this.getSourceFileInfo(filePath);
898
- if (!sourceFileInfo) {
899
- return;
900
- }
901
- this._bindFile(sourceFileInfo);
902
- const execEnv = this._configOptions.findExecEnvironment(filePath);
903
- sourceFileInfo.sourceFile.resolveCompletionItem(this._configOptions, this._importResolver, this._lookUpImport, this._evaluator, options, this._createSourceMapper(execEnv, token, sourceFileInfo, /* mapCompiled */ true), nameMap, libraryMap, () => this._buildModuleSymbolsMap(sourceFileInfo, libraryMap, options.includeUserSymbolsInAutoImport, token), completionItem, token);
904
- });
905
- }
906
- renameModule(path, newPath, token) {
907
- return this._runEvaluatorWithCancellationToken(token, () => {
908
- if ((0, pathUtils_1.isFile)(this.fileSystem, path)) {
909
- const fileInfo = this.getSourceFileInfo(path);
910
- if (!fileInfo) {
911
- return undefined;
912
- }
913
- }
914
- const renameModuleProvider = renameModuleProvider_1.RenameModuleProvider.createForModule(this._importResolver, this._configOptions, this._evaluator, path, newPath, token);
915
- if (!renameModuleProvider) {
916
- return undefined;
917
- }
918
- this._processModuleReferences(renameModuleProvider, renameModuleProvider.lastModuleName, path);
919
- return { edits: renameModuleProvider.getEdits(), fileOperations: [] };
920
- });
921
- }
922
- moveSymbolAtPosition(filePath, newFilePath, position, options, token) {
923
- return this._runEvaluatorWithCancellationToken(token, () => {
924
- var _a, _b;
925
- const sourceFileExt = (0, pathUtils_1.getFileExtension)(filePath);
926
- const destFileExt = (0, pathUtils_1.getFileExtension)(newFilePath);
927
- if (sourceFileExt.toLowerCase() !== destFileExt.toLowerCase()) {
928
- // Don't allow moving a symbol from py to pyi or vice versa.
929
- return undefined;
930
- }
931
- const fileInfo = this.getSourceFileInfo(filePath);
932
- if (!fileInfo) {
933
- return undefined;
934
- }
935
- const newFileInfo = this.getBoundSourceFileInfo(newFilePath);
936
- if (fileInfo === newFileInfo) {
937
- // Can't move symbol to the same file.
938
- return undefined;
939
- }
940
- this._bindFile(fileInfo);
941
- const parseResults = fileInfo.sourceFile.getParseResults();
942
- if (!parseResults) {
943
- return undefined;
944
- }
945
- const offset = (0, positionUtils_1.convertPositionToOffset)(position, parseResults.tokenizerOutput.lines);
946
- if (offset === undefined) {
947
- return undefined;
948
- }
949
- const node = (0, parseTreeUtils_1.findNodeByOffset)(parseResults.parseTree, offset);
950
- if (node === undefined) {
951
- return undefined;
952
- }
953
- // If this isn't a name node, there are no references to be found.
954
- if (node.nodeType !== 38 /* Name */ ||
955
- !renameModuleProvider_1.RenameModuleProvider.canMoveSymbol(this._configOptions, this._evaluator, node)) {
956
- return undefined;
957
- }
958
- // We will try to
959
- // 1. Find symbol to move.
960
- // 2. Update all references to the symbol to new location.
961
- // 3. Remove the existing symbol.
962
- // 4. Insert the symbol to the destination module.
963
- // 5. Insert imports required for the symbol moved to the destination module.
964
- // 6. Remove import no longer needed from the original module.
965
- //
966
- // Here all changes are done to edits, no features in LS will apply changes to
967
- // program directly. All modification is done through LSP by a edit request so
968
- // things like undo or edit stacks UI works.
969
- // 1. Find symbol to move.
970
- const execEnv = this._configOptions.findExecEnvironment(filePath);
971
- const declarations = documentSymbolCollector_1.DocumentSymbolCollector.getDeclarationsForNode(node, this._evaluator,
972
- /* resolveLocalNames */ false, documentSymbolCollector_1.DocumentSymbolCollectorUseCase.Rename, token, this._createSourceMapper(execEnv, token, fileInfo));
973
- const renameModuleProvider = renameModuleProvider_1.RenameModuleProvider.createForSymbol(this._importResolver, this._configOptions, this._evaluator, filePath, newFilePath, declarations, token);
974
- if (!renameModuleProvider) {
975
- return undefined;
976
- }
977
- // 2. Update affected references.
978
- this._processModuleReferences(renameModuleProvider, node.value, filePath);
979
- // 3. Remove existing symbols.
980
- const sourceDecl = renameModuleProvider.declarations.find((d) => d.node && (0, pathUtils_1.getFileExtension)(d.path) === sourceFileExt);
981
- if (!sourceDecl) {
982
- // Can't find symbol we can move.
983
- return undefined;
984
- }
985
- const symbolRange = renameModuleProvider_1.RenameModuleProvider.getSymbolTextRange(parseResults, sourceDecl);
986
- const importAdder = new importAdder_1.ImportAdder(this._configOptions, this._importResolver, this._evaluator);
987
- const collectedImports = importAdder.collectImportsForSymbolsUsed(parseResults, symbolRange, token);
988
- let insertionPoint = 0;
989
- let insertionIndentation = 0;
990
- const newFileParseResults = newFileInfo === null || newFileInfo === void 0 ? void 0 : newFileInfo.sourceFile.getParseResults();
991
- if (newFileParseResults) {
992
- const insertBefore = renameModuleProvider.tryGetFirstSymbolUsage(newFileParseResults);
993
- insertionPoint = (0, insertionPointUtils_1.getInsertionPointForSymbolUnderModule)(this._evaluator, newFileParseResults, node.value, {
994
- symbolDeclToIgnore: sourceDecl.path,
995
- insertBefore,
996
- });
997
- if (insertionPoint === undefined) {
998
- // No place to insert the symbol.
999
- return undefined;
1000
- }
1001
- insertionIndentation = (0, indentationUtils_1.getModuleStatementIndentation)(newFileParseResults);
1002
- }
1003
- const reindentResult = (0, indentationUtils_1.reindentSpan)(parseResults, symbolRange, insertionIndentation);
1004
- const fullRange = renameModuleProvider_1.RenameModuleProvider.getSymbolFullStatementTextRange(parseResults, sourceDecl);
1005
- renameModuleProvider.textEditTracker.addEdit(filePath, (0, positionUtils_1.convertTextRangeToRange)(textRange_1.TextRange.combine([reindentResult.originalSpan, fullRange]), parseResults.tokenizerOutput.lines), '');
1006
- // 4. Add the symbol to the destination file.
1007
- const fileOperations = [];
1008
- let codeSnippetToInsert = reindentResult.text;
1009
- if (newFileParseResults) {
1010
- const range = (0, positionUtils_1.convertTextRangeToRange)({ start: insertionPoint, length: 0 }, newFileParseResults.tokenizerOutput.lines);
1011
- // If we are adding at the end of line (ex, end of a file),
1012
- // add new lines.
1013
- const newLinesToAdd = _getNumberOfBlankLinesToInsert(newFileParseResults, sourceDecl, range.end);
1014
- codeSnippetToInsert = '\n'.repeat(newLinesToAdd) + codeSnippetToInsert;
1015
- renameModuleProvider.textEditTracker.addEdit(newFilePath, range, codeSnippetToInsert);
1016
- }
1017
- else {
1018
- fileOperations.push({ kind: 'create', filePath: newFilePath });
1019
- renameModuleProvider.textEditTracker.addEdit(newFilePath, (0, textRange_1.getEmptyRange)(), codeSnippetToInsert);
1020
- }
1021
- // 5. Insert imports required for the symbol moved to the destination module.
1022
- //
1023
- // Since step 5 and 6 can create nested edits, we clone the program and apply all changes to re-calculate
1024
- // edits we need to apply to the destination file. The same workflow as `fix all` but done in program level
1025
- // not service level.
1026
- const cloned = this.clone();
1027
- let edits = renameModuleProvider.getEdits();
1028
- const textAfterSymbolAdded = (0, workspaceEditUtils_1.applyTextEditsToString)(edits.filter((v) => v.filePath === newFilePath), (_a = newFileParseResults === null || newFileParseResults === void 0 ? void 0 : newFileParseResults.tokenizerOutput.lines) !== null && _a !== void 0 ? _a : new textRangeCollection_1.TextRangeCollection([]), (_b = newFileInfo === null || newFileInfo === void 0 ? void 0 : newFileInfo.sourceFile.getFileContent()) !== null && _b !== void 0 ? _b : '');
1029
- _updateFileContent(cloned, newFilePath, textAfterSymbolAdded);
1030
- const textAfterImportsAdded = _tryGetTextAfterImportsAdded(cloned, newFilePath, collectedImports, insertionPoint, token);
1031
- edits = _updateFileEditActions(edits, newFilePath, newFileParseResults, textAfterSymbolAdded, textAfterImportsAdded);
1032
- // 6. Remove imports no longer required from original module.
1033
- const textAfterSymbolRemoved = (0, workspaceEditUtils_1.applyTextEditsToString)(edits.filter((v) => v.filePath === filePath), parseResults.tokenizerOutput.lines, fileInfo.sourceFile.getFileContent());
1034
- _updateFileContent(cloned, filePath, textAfterSymbolRemoved);
1035
- const textAfterUnusedImportsRemoved = _tryGetTextAfterUnusedImportsRemoved(cloned, filePath, collectedImports, 0, token);
1036
- edits = _updateFileEditActions(edits, filePath, parseResults, textAfterSymbolRemoved, textAfterUnusedImportsRemoved);
1037
- cloned.dispose();
1038
- return {
1039
- edits,
1040
- fileOperations,
1041
- };
1042
- function _updateFileEditActions(edits, filePath, parseResults, oldText, newText) {
1043
- if (newText === undefined || oldText === newText) {
1044
- return edits;
1045
- }
1046
- // There were nested edits. Replace whole file.
1047
- edits = edits.filter((v) => v.filePath !== filePath);
1048
- edits.push({
1049
- filePath,
1050
- range: parseResults
1051
- ? (0, positionUtils_1.convertTextRangeToRange)(parseResults.parseTree, parseResults.tokenizerOutput.lines)
1052
- : (0, textRange_1.getEmptyRange)(),
1053
- replacementText: newText,
1054
- });
1055
- return edits;
1056
- }
1057
- function _tryGetTextAfterImportsAdded(cloned, filePath, importData, insertionPoint, token) {
1058
- const sourceFile = cloned.getBoundSourceFile(filePath);
1059
- const parseResults = sourceFile === null || sourceFile === void 0 ? void 0 : sourceFile.getParseResults();
1060
- if (!parseResults) {
1061
- return undefined;
1062
- }
1063
- const insertAddEdits = importAdder.applyImports(importData, filePath, parseResults, insertionPoint, options.importFormat, token);
1064
- return (0, workspaceEditUtils_1.applyTextEditsToString)(insertAddEdits, parseResults.tokenizerOutput.lines, sourceFile.getFileContent());
1065
- }
1066
- function _tryGetTextAfterUnusedImportsRemoved(cloned, filePath, importData, attempt, token) {
1067
- var _a;
1068
- (0, cancellationUtils_1.throwIfCancellationRequested)(token);
1069
- cloned.analyzeFile(filePath, token);
1070
- const sourceFile = cloned.getBoundSourceFile(filePath);
1071
- const parseResults = sourceFile === null || sourceFile === void 0 ? void 0 : sourceFile.getParseResults();
1072
- if (!parseResults) {
1073
- return undefined;
1074
- }
1075
- const tracker = new textEditTracker_1.TextEditTracker();
1076
- for (const diagnostic of cloned
1077
- .getDiagnosticsForRange(filePath, (0, positionUtils_1.convertTextRangeToRange)(parseResults.parseTree, parseResults.tokenizerOutput.lines))
1078
- .filter((d) => {
1079
- var _a;
1080
- return d.category === 3 /* UnusedCode */ &&
1081
- ((_a = d.getActions()) === null || _a === void 0 ? void 0 : _a.some((a) => a.action === "pyright.unusedImport" /* unusedImport */));
1082
- })) {
1083
- const nameNode = (0, parseTreeUtils_1.findNodeByPosition)(parseResults.parseTree, diagnostic.range.start, parseResults.tokenizerOutput.lines);
1084
- if ((nameNode === null || nameNode === void 0 ? void 0 : nameNode.nodeType) !== 38 /* Name */) {
1085
- continue;
1086
- }
1087
- // decl is synthesized. there is no node associated with the decl.
1088
- // ex) import a or import a.b
1089
- const dottedName1 = ((_a = nameNode.parent) === null || _a === void 0 ? void 0 : _a.nodeType) === 37 /* ModuleName */ ? nameNode.parent.nameParts : [nameNode];
1090
- for (const [decl, names] of importData.declarations) {
1091
- if (decl.node) {
1092
- if (textRange_1.TextRange.containsRange(decl.node, nameNode)) {
1093
- tracker.removeNodes({ node: nameNode, parseResults: parseResults });
1094
- break;
1095
- }
1096
- }
1097
- const dottedName2 = (0, parseTreeUtils_1.getDottedName)((0, parseTreeUtils_1.getDottedNameWithGivenNodeAsLastName)(names[0]));
1098
- if (dottedName2 && (0, collectionUtils_1.arrayEquals)(dottedName1, dottedName2, (e1, e2) => e1.value === e2.value)) {
1099
- tracker.removeNodes({ node: nameNode, parseResults: parseResults });
1100
- break;
1101
- }
1102
- }
1103
- }
1104
- const oldText = sourceFile.getFileContent();
1105
- const newText = (0, workspaceEditUtils_1.applyTextEditsToString)(tracker.getEdits(token).filter((v) => v.filePath === filePath), parseResults.tokenizerOutput.lines, oldText);
1106
- // We will attempt to remove unused imports multiple times since removing 1 unused import
1107
- // could make another import unused. This is due to how we calculate which import is not used.
1108
- // ex) import os, os.path, os.path.xxx
1109
- // `os.path` and `os.path.xxx` will be marked as used due to `import os`.
1110
- // once `os` is removed `os.path` will be marked as unused and so on.
1111
- // We will attempt to remove those chained unused imports up to 10 chain.
1112
- if (attempt > 10 || oldText === newText) {
1113
- return newText;
1114
- }
1115
- _updateFileContent(cloned, filePath, newText);
1116
- return _tryGetTextAfterUnusedImportsRemoved(cloned, filePath, importData, attempt + 1, token);
1117
- }
1118
- });
1119
- function _updateFileContent(cloned, filePath, text) {
1120
- var _a, _b;
1121
- const info = cloned.getSourceFileInfo(filePath);
1122
- const version = info ? ((_a = info.sourceFile.getClientVersion()) !== null && _a !== void 0 ? _a : 0) + 1 : 0;
1123
- const chainedFilePath = info ? (_b = info.chainedSourceFile) === null || _b === void 0 ? void 0 : _b.sourceFile.getFilePath() : undefined;
1124
- const ipythonMode = info ? info.sourceFile.getIPythonMode() : sourceFile_1.IPythonMode.None;
1125
- const isTracked = info ? info.isTracked : true;
1126
- const realFilePath = info ? info.sourceFile.getRealFilePath() : filePath;
1127
- cloned.setFileOpened(filePath, version, text, {
1128
- chainedFilePath,
1129
- ipythonMode,
1130
- isTracked,
1131
- realFilePath,
1132
- });
1133
- }
1134
- function _getNumberOfBlankLinesToInsert(parseResults, decl, position) {
1135
- if (position.line === 0 && position.character === 0) {
1136
- return 0;
1137
- }
1138
- let previousStatement;
1139
- const offset = (0, positionUtils_1.convertPositionToOffset)(position, parseResults.tokenizerOutput.lines);
1140
- if (offset && parseResults.parseTree.statements.length > 0) {
1141
- previousStatement = parseResults.parseTree.statements.reduce((prev, curr) => offset < curr.start ? prev : curr);
1142
- }
1143
- // This basically try to add some blank lines after the last line with text.
1144
- let linesToAdd = 0;
1145
- if (previousStatement) {
1146
- if ((0, declaration_1.isVariableDeclaration)(decl)) {
1147
- switch (previousStatement.nodeType) {
1148
- case 47 /* StatementList */:
1149
- // Small statement such as call, assignment, etc.
1150
- linesToAdd = 0;
1151
- break;
1152
- case 10 /* Class */:
1153
- case 28 /* Function */:
1154
- linesToAdd = 2;
1155
- break;
1156
- default:
1157
- // any other statement such as if, while, etc. we will add 1 blank line.
1158
- linesToAdd = 1;
1159
- }
1160
- }
1161
- else {
1162
- linesToAdd = 2;
1163
- }
1164
- }
1165
- // If the position is not at the beginning of the line, we need to add 1 more '\n'
1166
- // to start from blank line.
1167
- linesToAdd += position.character !== 0 ? 1 : 0;
1168
- // If there are already blank lines, we only add the difference.
1169
- const desiredBlankLines = linesToAdd;
1170
- const startingLine = position.character !== 0 ? position.line : position.line - 1;
1171
- for (let i = 0; i < desiredBlankLines; i++) {
1172
- const currentLine = startingLine - i;
1173
- if (currentLine < 0 || !(0, parseTreeUtils_1.isBlankLine)(parseResults, currentLine)) {
1174
- break;
1175
- }
1176
- linesToAdd--;
1177
- }
1178
- return linesToAdd;
1179
- }
1180
- }
1181
745
  clone() {
1182
746
  var _a, _b;
1183
747
  const program = new Program(this._importResolver, this._configOptions, this._console, new logTracker_1.LogTracker(this._console, 'Cloned'));
@@ -1200,123 +764,6 @@ class Program {
1200
764
  }
1201
765
  return program;
1202
766
  }
1203
- canRenameSymbolAtPosition(filePath, position, isDefaultWorkspace, allowModuleRename, token) {
1204
- return this._runEvaluatorWithCancellationToken(token, () => {
1205
- const sourceFileInfo = this.getSourceFileInfo(filePath);
1206
- if (!sourceFileInfo) {
1207
- return undefined;
1208
- }
1209
- this._bindFile(sourceFileInfo);
1210
- const referencesResult = this._getReferenceResult(sourceFileInfo, filePath, position, allowModuleRename, token);
1211
- if (!referencesResult) {
1212
- return undefined;
1213
- }
1214
- if (referencesResult.containsOnlyImportDecls &&
1215
- !this._supportRenameModule(referencesResult.declarations, isDefaultWorkspace)) {
1216
- return undefined;
1217
- }
1218
- const renameMode = this._getRenameSymbolMode(sourceFileInfo, referencesResult, isDefaultWorkspace);
1219
- if (renameMode === 'none') {
1220
- return undefined;
1221
- }
1222
- // Return the range of the symbol.
1223
- const parseResult = sourceFileInfo.sourceFile.getParseResults();
1224
- return {
1225
- range: (0, positionUtils_1.convertTextRangeToRange)(referencesResult.nodeAtOffset, parseResult.tokenizerOutput.lines),
1226
- declarations: referencesResult.declarations,
1227
- };
1228
- });
1229
- }
1230
- renameSymbolAtPosition(filePath, position, newName, isDefaultWorkspace, allowModuleRename, token) {
1231
- return this._runEvaluatorWithCancellationToken(token, () => {
1232
- var _a;
1233
- const sourceFileInfo = this.getSourceFileInfo(filePath);
1234
- if (!sourceFileInfo) {
1235
- return undefined;
1236
- }
1237
- this._bindFile(sourceFileInfo);
1238
- const referencesResult = this._getReferenceResult(sourceFileInfo, filePath, position, allowModuleRename, token);
1239
- if (!referencesResult) {
1240
- return undefined;
1241
- }
1242
- if (referencesResult.containsOnlyImportDecls) {
1243
- // All decls must be on a user file.
1244
- if (!this._supportRenameModule(referencesResult.declarations, isDefaultWorkspace)) {
1245
- return undefined;
1246
- }
1247
- const moduleInfo = renameModuleProvider_1.RenameModuleProvider.getRenameModulePathInfo(renameModuleProvider_1.RenameModuleProvider.getRenameModulePath(referencesResult.declarations), newName);
1248
- if (!moduleInfo) {
1249
- // Can't figure out module to rename.
1250
- return undefined;
1251
- }
1252
- const editActions = this.renameModule(moduleInfo.filePath, moduleInfo.newFilePath, token);
1253
- // Add file system rename.
1254
- editActions === null || editActions === void 0 ? void 0 : editActions.fileOperations.push({
1255
- kind: 'rename',
1256
- oldFilePath: moduleInfo.filePath,
1257
- newFilePath: moduleInfo.newFilePath,
1258
- });
1259
- if ((0, sourceMapper_1.isStubFile)(moduleInfo.filePath)) {
1260
- const matchingFiles = this._importResolver.getSourceFilesFromStub(moduleInfo.filePath, this._configOptions.findExecEnvironment(filePath),
1261
- /* mapCompiled */ false);
1262
- for (const matchingFile of matchingFiles) {
1263
- const matchingFileInfo = renameModuleProvider_1.RenameModuleProvider.getRenameModulePathInfo(matchingFile, newName);
1264
- if (matchingFileInfo) {
1265
- editActions === null || editActions === void 0 ? void 0 : editActions.fileOperations.push({
1266
- kind: 'rename',
1267
- oldFilePath: matchingFileInfo.filePath,
1268
- newFilePath: matchingFileInfo.newFilePath,
1269
- });
1270
- }
1271
- }
1272
- }
1273
- return editActions;
1274
- }
1275
- const referenceProvider = new referencesProvider_1.ReferencesProvider(this, token);
1276
- const renameMode = this._getRenameSymbolMode(sourceFileInfo, referencesResult, isDefaultWorkspace);
1277
- switch (renameMode) {
1278
- case 'singleFileMode':
1279
- referenceProvider.addReferencesToResult(sourceFileInfo.sourceFile.getFilePath(),
1280
- /* includeDeclaration */ true, referencesResult);
1281
- break;
1282
- case 'multiFileMode': {
1283
- for (const curSourceFileInfo of this._sourceFileList) {
1284
- // Make sure we only add user code to the references to prevent us
1285
- // from accidentally changing third party library or type stub.
1286
- if ((0, sourceFileInfoUtils_1.isUserCode)(curSourceFileInfo)) {
1287
- // Make sure searching symbol name exists in the file.
1288
- const content = (_a = curSourceFileInfo.sourceFile.getFileContent()) !== null && _a !== void 0 ? _a : '';
1289
- if (!referencesResult.symbolNames.some((s) => content.search(s) >= 0)) {
1290
- continue;
1291
- }
1292
- this._bindFile(curSourceFileInfo, content);
1293
- referenceProvider.addReferencesToResult(curSourceFileInfo.sourceFile.getFilePath(),
1294
- /* includeDeclaration */ true, referencesResult);
1295
- }
1296
- // This operation can consume significant memory, so check
1297
- // for situations where we need to discard the type cache.
1298
- this._handleMemoryHighUsage();
1299
- }
1300
- break;
1301
- }
1302
- case 'none':
1303
- // Rename is not allowed.
1304
- // ex) rename symbols from libraries.
1305
- return undefined;
1306
- default:
1307
- (0, debug_1.assertNever)(renameMode);
1308
- }
1309
- const edits = [];
1310
- referencesResult.locations.forEach((loc) => {
1311
- edits.push({
1312
- filePath: loc.path,
1313
- range: loc.range,
1314
- replacementText: newName,
1315
- });
1316
- });
1317
- return { edits, fileOperations: [] };
1318
- });
1319
- }
1320
767
  // Returns a value from 0 to 1 (or more) indicating how "full" the cache is
1321
768
  // relative to some predetermined high-water mark. We'll compute this value
1322
769
  // based on two easy-to-compute metrics: the number of entries in the type
@@ -1334,90 +781,6 @@ class Program {
1334
781
  this._parsedFileCount = 0;
1335
782
  extensibility_1.Extensions.getProgramExtensions(this.rootPath).forEach((e) => (e.clearCache ? e.clearCache() : null));
1336
783
  }
1337
- test_createSourceMapper(execEnv, from) {
1338
- return this._createSourceMapper(execEnv, vscode_languageserver_1.CancellationToken.None, /* from */ from, /* mapCompiled */ false);
1339
- }
1340
- _getRenameSymbolMode(sourceFileInfo, referencesResult, isDefaultWorkspace) {
1341
- // We have 2 different cases
1342
- // Single file mode.
1343
- // 1. rename on default workspace (ex, standalone file mode).
1344
- // 2. rename local symbols.
1345
- // 3. rename symbols defined in the non user open file.
1346
- //
1347
- // and Multi file mode.
1348
- // 1. rename public symbols defined in user files on regular workspace (ex, open folder mode).
1349
- const userFile = (0, sourceFileInfoUtils_1.isUserCode)(sourceFileInfo);
1350
- if (isDefaultWorkspace ||
1351
- (userFile && !referencesResult.requiresGlobalSearch) ||
1352
- (!userFile &&
1353
- sourceFileInfo.isOpenByClient &&
1354
- referencesResult.declarations.every((d) => this.getSourceFileInfo(d.path) === sourceFileInfo))) {
1355
- return 'singleFileMode';
1356
- }
1357
- if (referencesResult.declarations.every((d) => (0, sourceFileInfoUtils_1.isUserCode)(this.getSourceFileInfo(d.path)))) {
1358
- return 'multiFileMode';
1359
- }
1360
- // Rename is not allowed.
1361
- // ex) rename symbols from libraries.
1362
- return 'none';
1363
- }
1364
- _supportRenameModule(declarations, isDefaultWorkspace) {
1365
- // Rename module is not supported for standalone file and all decls must be on a user file.
1366
- return !isDefaultWorkspace && declarations.every((d) => (0, sourceFileInfoUtils_1.isUserCode)(this.getSourceFileInfo(d.path)));
1367
- }
1368
- _getReferenceResult(sourceFileInfo, filePath, position, allowModuleRename, token) {
1369
- const execEnv = this._configOptions.findExecEnvironment(filePath);
1370
- const referencesResult = this._getDeclarationForPosition(sourceFileInfo, position, documentSymbolCollector_1.DocumentSymbolCollectorUseCase.Rename, this._createSourceMapper(execEnv, token), token);
1371
- if (!referencesResult) {
1372
- return undefined;
1373
- }
1374
- if (allowModuleRename && referencesResult.containsOnlyImportDecls) {
1375
- return referencesResult;
1376
- }
1377
- if (referencesResult.nonImportDeclarations.length === 0) {
1378
- // There is no symbol we can rename.
1379
- return undefined;
1380
- }
1381
- // Use declarations that doesn't contain import decls.
1382
- return new referencesProvider_1.ReferencesResult(referencesResult.requiresGlobalSearch, referencesResult.nodeAtOffset, referencesResult.symbolNames, referencesResult.nonImportDeclarations, referencesResult.useCase);
1383
- }
1384
- _getDeclarationForPosition(sourceFileInfo, position, useCase, sourceMapper, token, reporter) {
1385
- // If we have no completed analysis job, there's nothing to do.
1386
- const parseResults = sourceFileInfo.sourceFile.getParseResults();
1387
- if (!parseResults) {
1388
- return undefined;
1389
- }
1390
- return referencesProvider_1.ReferencesProvider.getDeclarationForPosition(sourceMapper, parseResults, sourceFileInfo.sourceFile.getFilePath(), position, this._evaluator, reporter, useCase, token, Array.from((0, sourceFileInfoUtils_1.collectImportedByFiles)(sourceFileInfo)).map((fileInfo) => fileInfo.sourceFile));
1391
- }
1392
- _processModuleReferences(renameModuleProvider, filteringText, currentFilePath) {
1393
- var _a;
1394
- // _sourceFileList contains every user files that match "include" pattern including
1395
- // py file even if corresponding pyi exists.
1396
- for (const currentFileInfo of this._sourceFileList) {
1397
- // Make sure we only touch user code to prevent us
1398
- // from accidentally changing third party library or type stub.
1399
- if (!(0, sourceFileInfoUtils_1.isUserCode)(currentFileInfo)) {
1400
- continue;
1401
- }
1402
- // If module name isn't mentioned in the current file, skip the file
1403
- // except the file that got actually renamed/moved.
1404
- // The file that got moved might have relative import paths we need to update.
1405
- const filePath = currentFileInfo.sourceFile.getFilePath();
1406
- const content = (_a = currentFileInfo.sourceFile.getFileContent()) !== null && _a !== void 0 ? _a : '';
1407
- if (filePath !== currentFilePath && content.indexOf(filteringText) < 0) {
1408
- continue;
1409
- }
1410
- this._bindFile(currentFileInfo, content);
1411
- const parseResult = currentFileInfo.sourceFile.getParseResults();
1412
- if (!parseResult) {
1413
- continue;
1414
- }
1415
- renameModuleProvider.renameReferences(parseResult);
1416
- // This operation can consume significant memory, so check
1417
- // for situations where we need to discard the type cache.
1418
- this._handleMemoryHighUsage();
1419
- }
1420
- }
1421
784
  _handleMemoryHighUsage() {
1422
785
  const cacheUsage = this._cacheManager.getCacheUsage();
1423
786
  // If the total cache has exceeded 75%, determine whether we should empty
@@ -1769,7 +1132,7 @@ class Program {
1769
1132
  let importedFileInfo = this.getSourceFileInfo(importInfo.path);
1770
1133
  if (!importedFileInfo) {
1771
1134
  const importName = this._getImportNameForFile(importInfo.path);
1772
- const sourceFile = new sourceFile_1.SourceFile(this.fileSystem, importInfo.path, importName, importInfo.isThirdPartyImport, importInfo.isPyTypedPresent, this._console, this._logTracker);
1135
+ const sourceFile = new sourceFile_1.SourceFile(this.fileSystem, importInfo.path, importName, importInfo.isThirdPartyImport, importInfo.isPyTypedPresent, this._isEditMode, this._console, this._logTracker);
1773
1136
  importedFileInfo = {
1774
1137
  sourceFile,
1775
1138
  isTracked: false,
@@ -1878,7 +1241,7 @@ class Program {
1878
1241
  const importName = this._getImportNameForFile(filePath);
1879
1242
  const sourceFile = new sourceFile_1.SourceFile(this.fileSystem, filePath, importName,
1880
1243
  /* isThirdPartyImport */ false,
1881
- /* isInPyTypedPackage */ false, this._console, this._logTracker);
1244
+ /* isInPyTypedPackage */ false, this._isEditMode, this._console, this._logTracker);
1882
1245
  const sourceFileInfo = {
1883
1246
  sourceFile,
1884
1247
  isTracked: false,
@@ -2028,31 +1391,6 @@ class Program {
2028
1391
  });
2029
1392
  return effectiveFutureImports;
2030
1393
  }
2031
- // Build a map of all modules within this program and the module-
2032
- // level scope that contains the symbol table for the module.
2033
- _buildModuleSymbolsMap(sourceFileToExclude, libraryMap, includeSymbolsFromIndices, token) {
2034
- // If we have library map, always use the map for library symbols.
2035
- const predicate = (s) => {
2036
- if (!libraryMap) {
2037
- // We don't have any prebuilt indices, so we need to include
2038
- // all files.
2039
- return true;
2040
- }
2041
- if (!this._configOptions.indexing) {
2042
- // We have some prebuilt indices such as stdlib, but indexing is disabled.
2043
- // Include files we don't have prebuilt indices.
2044
- return libraryMap.get(s.sourceFile.getFilePath()) === undefined;
2045
- }
2046
- // We have prebuilt indices for third party libraries. Include only
2047
- // user files.
2048
- return (0, sourceFileInfoUtils_1.isUserCode)(s);
2049
- };
2050
- // Only include import alias from user files if indexing is off for now.
2051
- // Currently, when indexing is off, we don't do import alias deduplication, so
2052
- // adding import alias is cheap. But when indexing is on, we do deduplication, which
2053
- // require resolveAliasDeclaration that can cause more files to be parsed and bound.
2054
- return (0, autoImporter_1.buildModuleSymbolsMap)(this._sourceFileList.filter((s) => s !== sourceFileToExclude && predicate(s)), includeSymbolsFromIndices, token);
2055
- }
2056
1394
  _shouldCheckFile(fileInfo) {
2057
1395
  // Always do a full checking for a file that's open in the editor.
2058
1396
  if (fileInfo.isOpenByClient) {