@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
@@ -29,7 +29,6 @@ var __importStar = (this && this.__importStar) || function (mod) {
29
29
  Object.defineProperty(exports, "__esModule", { value: true });
30
30
  exports.parseFile = exports.SourceFile = exports.IPythonMode = void 0;
31
31
  const worker_threads_1 = require("worker_threads");
32
- const SymbolNameUtils = __importStar(require("../analyzer/symbolNameUtils"));
33
32
  const cancellationUtils_1 = require("../common/cancellationUtils");
34
33
  const configOptions_1 = require("../common/configOptions");
35
34
  const console_1 = require("../common/console");
@@ -39,15 +38,12 @@ const diagnosticRules_1 = require("../common/diagnosticRules");
39
38
  const diagnosticSink_1 = require("../common/diagnosticSink");
40
39
  const extensibility_1 = require("../common/extensibility");
41
40
  const logTracker_1 = require("../common/logTracker");
42
- const lspUtils_1 = require("../common/lspUtils");
43
41
  const pathUtils_1 = require("../common/pathUtils");
44
42
  const positionUtils_1 = require("../common/positionUtils");
45
43
  const StringUtils = __importStar(require("../common/stringUtils"));
46
44
  const textRange_1 = require("../common/textRange");
47
45
  const textRangeCollection_1 = require("../common/textRangeCollection");
48
46
  const timing_1 = require("../common/timing");
49
- const completionProvider_1 = require("../languageService/completionProvider");
50
- const documentSymbolProvider_1 = require("../languageService/documentSymbolProvider");
51
47
  const localize_1 = require("../localization/localize");
52
48
  const parseNodes_1 = require("../parser/parseNodes");
53
49
  const parser_1 = require("../parser/parser");
@@ -72,50 +68,58 @@ var IPythonMode;
72
68
  // Each cell is its own document.
73
69
  IPythonMode[IPythonMode["CellDocs"] = 1] = "CellDocs";
74
70
  })(IPythonMode = exports.IPythonMode || (exports.IPythonMode = {}));
75
- class SourceFile {
76
- constructor(fs, filePath, moduleName, isThirdPartyImport, isThirdPartyPyTypedPresent, console, logTracker, realFilePath, ipythonMode = IPythonMode.None) {
77
- // True if the file appears to have been deleted.
78
- this._isFileDeleted = false;
71
+ class WriteableData {
72
+ constructor() {
79
73
  // Number that is incremented every time the diagnostics
80
74
  // are updated.
81
- this._diagnosticVersion = 0;
75
+ this.diagnosticVersion = 0;
82
76
  // Generation count of the file contents. When the contents
83
77
  // change, this is incremented.
84
- this._fileContentsVersion = 0;
78
+ this.fileContentsVersion = 0;
85
79
  // Length and hash of the file the last time it was read from disk.
86
- this._lastFileContentLength = undefined;
87
- this._lastFileContentHash = undefined;
80
+ this.lastFileContentLength = undefined;
81
+ this.lastFileContentHash = undefined;
88
82
  // Version of file contents that have been analyzed.
89
- this._analyzedFileContentsVersion = -1;
83
+ this.analyzedFileContentsVersion = -1;
90
84
  // Do we need to walk the parse tree and clean
91
85
  // the binder information hanging from it?
92
- this._parseTreeNeedsCleaning = false;
86
+ this.parseTreeNeedsCleaning = false;
93
87
  // Reentrancy check for binding.
94
- this._isBindingInProgress = false;
88
+ this.isBindingInProgress = false;
95
89
  // Diagnostics generated during different phases of analysis.
96
- this._parseDiagnostics = [];
97
- this._commentDiagnostics = [];
98
- this._bindDiagnostics = [];
99
- this._checkerDiagnostics = [];
100
- this._typeIgnoreLines = new Map();
101
- this._pyrightIgnoreLines = new Map();
102
- // Settings that control which diagnostics should be output. The rules
103
- // are initialized to the basic set. They should be updated after the
104
- // the file is parsed.
105
- this._diagnosticRuleSet = (0, configOptions_1.getBasicDiagnosticRuleSet)();
90
+ this.parseDiagnostics = [];
91
+ this.commentDiagnostics = [];
92
+ this.bindDiagnostics = [];
93
+ this.checkerDiagnostics = [];
94
+ this.typeIgnoreLines = new Map();
95
+ this.pyrightIgnoreLines = new Map();
106
96
  // Circular dependencies that have been reported in this file.
107
- this._circularDependencies = [];
108
- this._noCircularDependencyConfirmed = false;
97
+ this.circularDependencies = [];
98
+ this.noCircularDependencyConfirmed = false;
109
99
  // Do we need to perform a binding step?
110
- this._isBindingNeeded = true;
100
+ this.isBindingNeeded = true;
111
101
  // Do we have valid diagnostic results from a checking pass?
112
- this._isCheckingNeeded = true;
102
+ this.isCheckingNeeded = true;
113
103
  // Do we need to perform an indexing step?
114
- this._indexingNeeded = true;
104
+ this.indexingNeeded = true;
105
+ // True if the file appears to have been deleted.
106
+ this.isFileDeleted = false;
107
+ }
108
+ }
109
+ class SourceFile {
110
+ constructor(fs, filePath, moduleName, isThirdPartyImport, isThirdPartyPyTypedPresent, editMode, console, logTracker, realFilePath, ipythonMode = IPythonMode.None) {
111
+ // Data that changes when the source file changes.
112
+ this._writableData = new WriteableData();
113
+ // Settings that control which diagnostics should be output. The rules
114
+ // are initialized to the basic set. They should be updated after the
115
+ // the file is parsed.
116
+ this._diagnosticRuleSet = (0, configOptions_1.getBasicDiagnosticRuleSet)();
115
117
  // Indicate whether this file is for ipython or not.
116
118
  this._ipythonMode = IPythonMode.None;
119
+ this._isEditMode = false;
117
120
  this.fileSystem = fs;
118
121
  this._console = console || new console_1.StandardConsole();
122
+ this._isEditMode = editMode;
119
123
  this._filePath = filePath;
120
124
  this._realFilePath = realFilePath !== null && realFilePath !== void 0 ? realFilePath : filePath;
121
125
  this._moduleName = moduleName;
@@ -156,13 +160,17 @@ class SourceFile {
156
160
  return this._filePath;
157
161
  }
158
162
  getModuleName() {
159
- return this._moduleName;
163
+ if (this._moduleName) {
164
+ return this._moduleName;
165
+ }
166
+ // Synthesize a module name using the file path.
167
+ return (0, pathUtils_1.stripFileExtension)((0, pathUtils_1.getFileName)(this._filePath));
160
168
  }
161
169
  setModuleName(name) {
162
170
  this._moduleName = name;
163
171
  }
164
172
  getDiagnosticVersion() {
165
- return this._diagnosticVersion;
173
+ return this._writableData.diagnosticVersion;
166
174
  }
167
175
  isStubFile() {
168
176
  return this._isStubFile;
@@ -174,7 +182,7 @@ class SourceFile {
174
182
  // If the prevVersion is specified, the method returns undefined if
175
183
  // the diagnostics haven't changed.
176
184
  getDiagnostics(options, prevDiagnosticVersion) {
177
- if (this._diagnosticVersion === prevDiagnosticVersion) {
185
+ if (this._writableData.diagnosticVersion === prevDiagnosticVersion) {
178
186
  return undefined;
179
187
  }
180
188
  let includeWarningsAndErrors = true;
@@ -184,23 +192,23 @@ class SourceFile {
184
192
  includeWarningsAndErrors = false;
185
193
  }
186
194
  let diagList = [
187
- ...this._parseDiagnostics,
188
- ...this._commentDiagnostics,
189
- ...this._bindDiagnostics,
190
- ...this._checkerDiagnostics,
195
+ ...this._writableData.parseDiagnostics,
196
+ ...this._writableData.commentDiagnostics,
197
+ ...this._writableData.bindDiagnostics,
198
+ ...this._writableData.checkerDiagnostics,
191
199
  ];
192
200
  const prefilteredDiagList = diagList;
193
- const typeIgnoreLinesClone = new Map(this._typeIgnoreLines);
194
- const pyrightIgnoreLinesClone = new Map(this._pyrightIgnoreLines);
201
+ const typeIgnoreLinesClone = new Map(this._writableData.typeIgnoreLines);
202
+ const pyrightIgnoreLinesClone = new Map(this._writableData.pyrightIgnoreLines);
195
203
  // Filter the diagnostics based on "type: ignore" lines.
196
204
  if (this._diagnosticRuleSet.enableTypeIgnoreComments) {
197
- if (this._typeIgnoreLines.size > 0) {
205
+ if (this._writableData.typeIgnoreLines.size > 0) {
198
206
  diagList = diagList.filter((d) => {
199
207
  if (d.category !== 3 /* UnusedCode */ &&
200
208
  d.category !== 4 /* UnreachableCode */ &&
201
209
  d.category !== 5 /* Deprecated */) {
202
210
  for (let line = d.range.start.line; line <= d.range.end.line; line++) {
203
- if (this._typeIgnoreLines.has(line)) {
211
+ if (this._writableData.typeIgnoreLines.has(line)) {
204
212
  typeIgnoreLinesClone.delete(line);
205
213
  return false;
206
214
  }
@@ -211,11 +219,11 @@ class SourceFile {
211
219
  }
212
220
  }
213
221
  // Filter the diagnostics based on "pyright: ignore" lines.
214
- if (this._pyrightIgnoreLines.size > 0) {
222
+ if (this._writableData.pyrightIgnoreLines.size > 0) {
215
223
  diagList = diagList.filter((d) => {
216
224
  if (d.category !== 4 /* UnreachableCode */ && d.category !== 5 /* Deprecated */) {
217
225
  for (let line = d.range.start.line; line <= d.range.end.line; line++) {
218
- const pyrightIgnoreComment = this._pyrightIgnoreLines.get(line);
226
+ const pyrightIgnoreComment = this._writableData.pyrightIgnoreLines.get(line);
219
227
  if (pyrightIgnoreComment) {
220
228
  if (!pyrightIgnoreComment.rulesList) {
221
229
  pyrightIgnoreLinesClone.delete(line);
@@ -263,20 +271,20 @@ class SourceFile {
263
271
  diag.range.start.line <= range.start.line &&
264
272
  diag.range.end.line >= range.end.line);
265
273
  };
266
- if (prefilteredErrorList.length === 0 && this._typeIgnoreAll !== undefined) {
267
- const rangeStart = this._typeIgnoreAll.range.start;
268
- const rangeEnd = rangeStart + this._typeIgnoreAll.range.length;
269
- const range = (0, positionUtils_1.convertOffsetsToRange)(rangeStart, rangeEnd, this._parseResults.tokenizerOutput.lines);
274
+ if (prefilteredErrorList.length === 0 && this._writableData.typeIgnoreAll !== undefined) {
275
+ const rangeStart = this._writableData.typeIgnoreAll.range.start;
276
+ const rangeEnd = rangeStart + this._writableData.typeIgnoreAll.range.length;
277
+ const range = (0, positionUtils_1.convertOffsetsToRange)(rangeStart, rangeEnd, this._writableData.parseResults.tokenizerOutput.lines);
270
278
  if (!isUnreachableCodeRange(range) && this._diagnosticRuleSet.enableTypeIgnoreComments) {
271
279
  unnecessaryTypeIgnoreDiags.push(new diagnostic_1.Diagnostic(diagCategory, localize_1.Localizer.Diagnostic.unnecessaryTypeIgnore(), range));
272
280
  }
273
281
  }
274
282
  typeIgnoreLinesClone.forEach((ignoreComment) => {
275
283
  var _a;
276
- if ((_a = this._parseResults) === null || _a === void 0 ? void 0 : _a.tokenizerOutput.lines) {
284
+ if ((_a = this._writableData.parseResults) === null || _a === void 0 ? void 0 : _a.tokenizerOutput.lines) {
277
285
  const rangeStart = ignoreComment.range.start;
278
286
  const rangeEnd = rangeStart + ignoreComment.range.length;
279
- const range = (0, positionUtils_1.convertOffsetsToRange)(rangeStart, rangeEnd, this._parseResults.tokenizerOutput.lines);
287
+ const range = (0, positionUtils_1.convertOffsetsToRange)(rangeStart, rangeEnd, this._writableData.parseResults.tokenizerOutput.lines);
280
288
  if (!isUnreachableCodeRange(range) && this._diagnosticRuleSet.enableTypeIgnoreComments) {
281
289
  unnecessaryTypeIgnoreDiags.push(new diagnostic_1.Diagnostic(diagCategory, localize_1.Localizer.Diagnostic.unnecessaryTypeIgnore(), range));
282
290
  }
@@ -284,11 +292,11 @@ class SourceFile {
284
292
  });
285
293
  pyrightIgnoreLinesClone.forEach((ignoreComment) => {
286
294
  var _a;
287
- if ((_a = this._parseResults) === null || _a === void 0 ? void 0 : _a.tokenizerOutput.lines) {
295
+ if ((_a = this._writableData.parseResults) === null || _a === void 0 ? void 0 : _a.tokenizerOutput.lines) {
288
296
  if (!ignoreComment.rulesList) {
289
297
  const rangeStart = ignoreComment.range.start;
290
298
  const rangeEnd = rangeStart + ignoreComment.range.length;
291
- const range = (0, positionUtils_1.convertOffsetsToRange)(rangeStart, rangeEnd, this._parseResults.tokenizerOutput.lines);
299
+ const range = (0, positionUtils_1.convertOffsetsToRange)(rangeStart, rangeEnd, this._writableData.parseResults.tokenizerOutput.lines);
292
300
  if (!isUnreachableCodeRange(range)) {
293
301
  unnecessaryTypeIgnoreDiags.push(new diagnostic_1.Diagnostic(diagCategory, localize_1.Localizer.Diagnostic.unnecessaryPyrightIgnore(), range));
294
302
  }
@@ -297,7 +305,7 @@ class SourceFile {
297
305
  ignoreComment.rulesList.forEach((unusedRule) => {
298
306
  const rangeStart = unusedRule.range.start;
299
307
  const rangeEnd = rangeStart + unusedRule.range.length;
300
- const range = (0, positionUtils_1.convertOffsetsToRange)(rangeStart, rangeEnd, this._parseResults.tokenizerOutput.lines);
308
+ const range = (0, positionUtils_1.convertOffsetsToRange)(rangeStart, rangeEnd, this._writableData.parseResults.tokenizerOutput.lines);
301
309
  if (!isUnreachableCodeRange(range)) {
302
310
  unnecessaryTypeIgnoreDiags.push(new diagnostic_1.Diagnostic(diagCategory, localize_1.Localizer.Diagnostic.unnecessaryPyrightIgnoreRule().format({
303
311
  name: unusedRule.text,
@@ -308,9 +316,10 @@ class SourceFile {
308
316
  }
309
317
  });
310
318
  }
311
- if (this._diagnosticRuleSet.reportImportCycles !== 'none' && this._circularDependencies.length > 0) {
319
+ if (this._diagnosticRuleSet.reportImportCycles !== 'none' &&
320
+ this._writableData.circularDependencies.length > 0) {
312
321
  const category = (0, diagnostic_1.convertLevelToCategory)(this._diagnosticRuleSet.reportImportCycles);
313
- this._circularDependencies.forEach((cirDep) => {
322
+ this._writableData.circularDependencies.forEach((cirDep) => {
314
323
  const diag = new diagnostic_1.Diagnostic(category, localize_1.Localizer.Diagnostic.importCycleDetected() +
315
324
  '\n' +
316
325
  cirDep
@@ -321,8 +330,8 @@ class SourceFile {
321
330
  diagList.push(diag);
322
331
  });
323
332
  }
324
- if (this._hitMaxImportDepth !== undefined) {
325
- diagList.push(new diagnostic_1.Diagnostic(0 /* Error */, localize_1.Localizer.Diagnostic.importDepthExceeded().format({ depth: this._hitMaxImportDepth }), (0, textRange_1.getEmptyRange)()));
333
+ if (this._writableData.hitMaxImportDepth !== undefined) {
334
+ diagList.push(new diagnostic_1.Diagnostic(0 /* Error */, localize_1.Localizer.Diagnostic.importDepthExceeded().format({ depth: this._writableData.hitMaxImportDepth }), (0, textRange_1.getEmptyRange)()));
326
335
  }
327
336
  // add diagnostics for comments that match the task list tokens
328
337
  this._addTaskListDiagnostics(options.taskListTokens, diagList);
@@ -333,7 +342,7 @@ class SourceFile {
333
342
  // If there is a "type: ignore" comment at the top of the file, clear
334
343
  // the diagnostic list of all error, warning, and information diagnostics.
335
344
  if (this._diagnosticRuleSet.enableTypeIgnoreComments) {
336
- if (this._typeIgnoreAll !== undefined) {
345
+ if (this._writableData.typeIgnoreAll !== undefined) {
337
346
  diagList = diagList.filter((diag) => diag.category !== 0 /* Error */ &&
338
347
  diag.category !== 1 /* Warning */ &&
339
348
  diag.category !== 2 /* Information */);
@@ -352,19 +361,33 @@ class SourceFile {
352
361
  return diagList;
353
362
  }
354
363
  getImports() {
355
- return this._imports || [];
364
+ return this._writableData.imports || [];
356
365
  }
357
366
  getBuiltinsImport() {
358
- return this._builtinsImport;
367
+ return this._writableData.builtinsImport;
359
368
  }
360
369
  getIPythonDisplayImport() {
361
- return this._ipythonDisplayImport;
370
+ return this._writableData.ipythonDisplayImport;
362
371
  }
363
372
  getModuleSymbolTable() {
364
- return this._moduleSymbolTable;
373
+ return this._writableData.moduleSymbolTable;
365
374
  }
366
375
  getCheckTime() {
367
- return this._checkTime;
376
+ return this._writableData.checkTime;
377
+ }
378
+ enterEditMode() {
379
+ this._isEditMode = true;
380
+ }
381
+ exitEditMode() {
382
+ this._isEditMode = false;
383
+ // If we had an edit, return our text.
384
+ if (this._preEditData) {
385
+ const text = this._writableData.clientDocumentContents;
386
+ this._writableData = this._preEditData;
387
+ this._preEditData = undefined;
388
+ return text;
389
+ }
390
+ return undefined;
368
391
  }
369
392
  // Indicates whether the contents of the file have changed since
370
393
  // the last analysis was performed.
@@ -372,11 +395,11 @@ class SourceFile {
372
395
  // If this is an open file any content changes will be
373
396
  // provided through the editor. We can assume contents
374
397
  // didn't change without us knowing about them.
375
- if (this._clientDocumentContents) {
398
+ if (this._writableData.clientDocumentContents) {
376
399
  return false;
377
400
  }
378
401
  // If the file was never read previously, no need to check for a change.
379
- if (this._lastFileContentLength === undefined) {
402
+ if (this._writableData.lastFileContentLength === undefined) {
380
403
  return false;
381
404
  }
382
405
  // Read in the latest file contents and see if the hash matches
@@ -384,10 +407,10 @@ class SourceFile {
384
407
  try {
385
408
  // Read the file's contents.
386
409
  const fileContents = this.fileSystem.readFileSync(this._filePath, 'utf8');
387
- if (fileContents.length !== this._lastFileContentLength) {
410
+ if (fileContents.length !== this._writableData.lastFileContentLength) {
388
411
  return true;
389
412
  }
390
- if (StringUtils.hashString(fileContents) !== this._lastFileContentHash) {
413
+ if (StringUtils.hashString(fileContents) !== this._writableData.lastFileContentHash) {
391
414
  return true;
392
415
  }
393
416
  }
@@ -400,45 +423,45 @@ class SourceFile {
400
423
  // in cases where memory is low. When info is needed, the file
401
424
  // will be re-parsed and rebound.
402
425
  dropParseAndBindInfo() {
403
- this._parseResults = undefined;
404
- this._moduleSymbolTable = undefined;
405
- this._isBindingNeeded = true;
426
+ this._writableData.parseResults = undefined;
427
+ this._writableData.moduleSymbolTable = undefined;
428
+ this._writableData.isBindingNeeded = true;
406
429
  }
407
430
  markDirty(indexingNeeded = true) {
408
- this._fileContentsVersion++;
409
- this._noCircularDependencyConfirmed = false;
410
- this._isCheckingNeeded = true;
411
- this._isBindingNeeded = true;
412
- this._indexingNeeded = indexingNeeded;
413
- this._moduleSymbolTable = undefined;
414
- this._cachedIndexResults = undefined;
431
+ this._writableData.fileContentsVersion++;
432
+ this._writableData.noCircularDependencyConfirmed = false;
433
+ this._writableData.isCheckingNeeded = true;
434
+ this._writableData.isBindingNeeded = true;
435
+ this._writableData.indexingNeeded = indexingNeeded;
436
+ this._writableData.moduleSymbolTable = undefined;
437
+ this._writableData.cachedIndexResults = undefined;
415
438
  const filePath = this.getFilePath();
416
439
  extensibility_1.Extensions.getProgramExtensions(filePath).forEach((e) => (e.fileDirty ? e.fileDirty(filePath) : null));
417
440
  }
418
441
  markReanalysisRequired(forceRebinding) {
419
442
  // Keep the parse info, but reset the analysis to the beginning.
420
- this._isCheckingNeeded = true;
421
- this._noCircularDependencyConfirmed = false;
443
+ this._writableData.isCheckingNeeded = true;
444
+ this._writableData.noCircularDependencyConfirmed = false;
422
445
  // If the file contains a wildcard import or __all__ symbols,
423
446
  // we need to rebind because a dependent import may have changed.
424
- if (this._parseResults) {
425
- if (this._parseResults.containsWildcardImport ||
426
- AnalyzerNodeInfo.getDunderAllInfo(this._parseResults.parseTree) !== undefined ||
447
+ if (this._writableData.parseResults) {
448
+ if (this._writableData.parseResults.containsWildcardImport ||
449
+ AnalyzerNodeInfo.getDunderAllInfo(this._writableData.parseResults.parseTree) !== undefined ||
427
450
  forceRebinding) {
428
451
  // We don't need to rebuild index data since wildcard
429
452
  // won't affect user file indices. User file indices
430
453
  // don't contain import alias info.
431
- this._parseTreeNeedsCleaning = true;
432
- this._isBindingNeeded = true;
433
- this._moduleSymbolTable = undefined;
454
+ this._writableData.parseTreeNeedsCleaning = true;
455
+ this._writableData.isBindingNeeded = true;
456
+ this._writableData.moduleSymbolTable = undefined;
434
457
  }
435
458
  }
436
459
  }
437
460
  getClientVersion() {
438
- return this._clientDocumentVersion;
461
+ return this._writableData.clientDocumentVersion;
439
462
  }
440
463
  getOpenFileContents() {
441
- return this._clientDocumentContents;
464
+ return this._writableData.clientDocumentContents;
442
465
  }
443
466
  getFileContent() {
444
467
  // Get current buffer content if the file is opened.
@@ -462,82 +485,90 @@ class SourceFile {
462
485
  }
463
486
  }
464
487
  setClientVersion(version, contents) {
488
+ // Save pre edit state if in edit mode.
489
+ this._cachePreEditState();
465
490
  if (version === null) {
466
- this._clientDocumentVersion = undefined;
467
- this._clientDocumentContents = undefined;
491
+ this._writableData.clientDocumentVersion = undefined;
492
+ this._writableData.clientDocumentContents = undefined;
468
493
  }
469
494
  else {
470
- this._clientDocumentVersion = version;
471
- this._clientDocumentContents = contents;
495
+ this._writableData.clientDocumentVersion = version;
496
+ this._writableData.clientDocumentContents = contents;
472
497
  const contentsHash = StringUtils.hashString(contents);
473
498
  // Have the contents of the file changed?
474
- if (contents.length !== this._lastFileContentLength || contentsHash !== this._lastFileContentHash) {
499
+ if (contents.length !== this._writableData.lastFileContentLength ||
500
+ contentsHash !== this._writableData.lastFileContentHash) {
475
501
  this.markDirty();
476
502
  }
477
- this._lastFileContentLength = contents.length;
478
- this._lastFileContentHash = contentsHash;
479
- this._isFileDeleted = false;
503
+ this._writableData.lastFileContentLength = contents.length;
504
+ this._writableData.lastFileContentHash = contentsHash;
505
+ this._writableData.isFileDeleted = false;
480
506
  }
481
507
  }
482
508
  prepareForClose() {
483
509
  // Nothing to do currently.
484
510
  }
485
511
  isFileDeleted() {
486
- return this._isFileDeleted;
512
+ return this._writableData.isFileDeleted;
487
513
  }
488
514
  isParseRequired() {
489
- return !this._parseResults || this._analyzedFileContentsVersion !== this._fileContentsVersion;
515
+ return (!this._writableData.parseResults ||
516
+ this._writableData.analyzedFileContentsVersion !== this._writableData.fileContentsVersion);
490
517
  }
491
518
  isBindingRequired() {
492
- if (this._isBindingInProgress) {
519
+ if (this._writableData.isBindingInProgress) {
493
520
  return false;
494
521
  }
495
522
  if (this.isParseRequired()) {
496
523
  return true;
497
524
  }
498
- return this._isBindingNeeded;
525
+ return this._writableData.isBindingNeeded;
499
526
  }
500
527
  isIndexingRequired() {
501
- return this._indexingNeeded;
528
+ return this._writableData.indexingNeeded;
529
+ }
530
+ markIndexDone() {
531
+ // This will be removed once indexResult is removed from sourceFile.
532
+ this._writableData.indexingNeeded = false;
502
533
  }
503
534
  isCheckingRequired() {
504
- return this._isCheckingNeeded;
535
+ return this._writableData.isCheckingNeeded;
505
536
  }
506
537
  getParseResults() {
507
538
  if (!this.isParseRequired()) {
508
- return this._parseResults;
539
+ return this._writableData.parseResults;
509
540
  }
510
541
  return undefined;
511
542
  }
512
543
  getCachedIndexResults() {
513
- return this._cachedIndexResults;
544
+ return this._writableData.cachedIndexResults;
514
545
  }
515
546
  cacheIndexResults(indexResults) {
516
- this._cachedIndexResults = indexResults;
547
+ this._writableData.cachedIndexResults = indexResults;
517
548
  }
518
549
  // Adds a new circular dependency for this file but only if
519
550
  // it hasn't already been added.
520
551
  addCircularDependency(circDependency) {
521
552
  let updatedDependencyList = false;
522
553
  // Some topologies can result in a massive number of cycles. We'll cut it off.
523
- if (this._circularDependencies.length < _maxImportCyclesPerFile) {
524
- if (!this._circularDependencies.some((dep) => dep.isEqual(circDependency))) {
525
- this._circularDependencies.push(circDependency);
554
+ if (this._writableData.circularDependencies.length < _maxImportCyclesPerFile) {
555
+ if (!this._writableData.circularDependencies.some((dep) => dep.isEqual(circDependency))) {
556
+ this._writableData.circularDependencies.push(circDependency);
526
557
  updatedDependencyList = true;
527
558
  }
528
559
  }
529
560
  if (updatedDependencyList) {
530
- this._diagnosticVersion++;
561
+ this._writableData.diagnosticVersion++;
531
562
  }
532
563
  }
533
564
  setNoCircularDependencyConfirmed() {
534
- this._noCircularDependencyConfirmed = true;
565
+ this._writableData.noCircularDependencyConfirmed = true;
535
566
  }
536
567
  isNoCircularDependencyConfirmed() {
537
- return !this.isParseRequired() && this._noCircularDependencyConfirmed;
568
+ return !this.isParseRequired() && this._writableData.noCircularDependencyConfirmed;
538
569
  }
539
570
  setHitMaxImportDepth(maxImportDepth) {
540
- this._hitMaxImportDepth = maxImportDepth;
571
+ this._writableData.hitMaxImportDepth = maxImportDepth;
541
572
  }
542
573
  // Parse the file and update the state. Callers should wait for completion
543
574
  // (or at least cancel) prior to calling again. It returns true if a parse
@@ -561,8 +592,8 @@ class SourceFile {
561
592
  throw new Error("Can't get file content");
562
593
  }
563
594
  // Remember the length and hash for comparison purposes.
564
- this._lastFileContentLength = fileContents.length;
565
- this._lastFileContentHash = StringUtils.hashString(fileContents);
595
+ this._writableData.lastFileContentLength = fileContents.length;
596
+ this._writableData.lastFileContentHash = StringUtils.hashString(fileContents);
566
597
  });
567
598
  logState.add(`fs read ${timing_1.timingStats.readFileTime.totalTime - startTime}ms`);
568
599
  }
@@ -570,7 +601,7 @@ class SourceFile {
570
601
  diagSink.addError(`Source file could not be read`, (0, textRange_1.getEmptyRange)());
571
602
  fileContents = '';
572
603
  if (!this.fileSystem.existsSync(this._realFilePath)) {
573
- this._isFileDeleted = true;
604
+ this._writableData.isFileDeleted = true;
574
605
  }
575
606
  }
576
607
  }
@@ -578,27 +609,28 @@ class SourceFile {
578
609
  // Parse the token stream, building the abstract syntax tree.
579
610
  const parseResults = parseFile(configOptions, this._filePath, fileContents, this._ipythonMode, diagSink);
580
611
  (0, debug_1.assert)(parseResults !== undefined && parseResults.tokenizerOutput !== undefined);
581
- this._parseResults = parseResults;
582
- this._typeIgnoreLines = this._parseResults.tokenizerOutput.typeIgnoreLines;
583
- this._typeIgnoreAll = this._parseResults.tokenizerOutput.typeIgnoreAll;
584
- this._pyrightIgnoreLines = this._parseResults.tokenizerOutput.pyrightIgnoreLines;
612
+ this._writableData.parseResults = parseResults;
613
+ this._writableData.typeIgnoreLines = this._writableData.parseResults.tokenizerOutput.typeIgnoreLines;
614
+ this._writableData.typeIgnoreAll = this._writableData.parseResults.tokenizerOutput.typeIgnoreAll;
615
+ this._writableData.pyrightIgnoreLines =
616
+ this._writableData.parseResults.tokenizerOutput.pyrightIgnoreLines;
585
617
  // Resolve imports.
586
618
  const execEnvironment = configOptions.findExecEnvironment(this._filePath);
587
619
  timing_1.timingStats.resolveImportsTime.timeOperation(() => {
588
620
  const importResult = this._resolveImports(importResolver, parseResults.importedModules, execEnvironment);
589
- this._imports = importResult.imports;
590
- this._builtinsImport = importResult.builtinsImportResult;
591
- this._ipythonDisplayImport = importResult.ipythonDisplayImportResult;
592
- this._parseDiagnostics = diagSink.fetchAndClear();
621
+ this._writableData.imports = importResult.imports;
622
+ this._writableData.builtinsImport = importResult.builtinsImportResult;
623
+ this._writableData.ipythonDisplayImport = importResult.ipythonDisplayImportResult;
624
+ this._writableData.parseDiagnostics = diagSink.fetchAndClear();
593
625
  });
594
626
  // Is this file in a "strict" path?
595
627
  const useStrict = configOptions.strict.find((strictFileSpec) => strictFileSpec.regExp.test(this._realFilePath)) !==
596
628
  undefined;
597
629
  const commentDiags = [];
598
- this._diagnosticRuleSet = CommentUtils.getFileLevelDirectives(this._parseResults.tokenizerOutput.tokens, this._parseResults.tokenizerOutput.lines, configOptions.diagnosticRuleSet, useStrict, commentDiags);
599
- this._commentDiagnostics = [];
630
+ this._diagnosticRuleSet = CommentUtils.getFileLevelDirectives(this._writableData.parseResults.tokenizerOutput.tokens, this._writableData.parseResults.tokenizerOutput.lines, configOptions.diagnosticRuleSet, useStrict, commentDiags);
631
+ this._writableData.commentDiagnostics = [];
600
632
  commentDiags.forEach((commentDiag) => {
601
- this._commentDiagnostics.push(new diagnostic_1.Diagnostic(0 /* Error */, commentDiag.message, (0, positionUtils_1.convertTextRangeToRange)(commentDiag.range, this._parseResults.tokenizerOutput.lines)));
633
+ this._writableData.commentDiagnostics.push(new diagnostic_1.Diagnostic(0 /* Error */, commentDiag.message, (0, positionUtils_1.convertTextRangeToRange)(commentDiag.range, this._writableData.parseResults.tokenizerOutput.lines)));
602
634
  });
603
635
  }
604
636
  catch (e) {
@@ -607,7 +639,7 @@ class SourceFile {
607
639
  JSON.stringify(e);
608
640
  this._console.error(localize_1.Localizer.Diagnostic.internalParseError().format({ file: this.getFilePath(), message }));
609
641
  // Create dummy parse results.
610
- this._parseResults = {
642
+ this._writableData.parseResults = {
611
643
  text: '',
612
644
  parseTree: parseNodes_1.ModuleNode.create({ start: 0, length: 0 }),
613
645
  importedModules: [],
@@ -625,110 +657,50 @@ class SourceFile {
625
657
  containsWildcardImport: false,
626
658
  typingSymbolAliases: new Map(),
627
659
  };
628
- this._imports = undefined;
629
- this._builtinsImport = undefined;
630
- this._ipythonDisplayImport = undefined;
660
+ this._writableData.imports = undefined;
661
+ this._writableData.builtinsImport = undefined;
662
+ this._writableData.ipythonDisplayImport = undefined;
631
663
  const diagSink = new diagnosticSink_1.DiagnosticSink();
632
664
  diagSink.addError(localize_1.Localizer.Diagnostic.internalParseError().format({ file: this.getFilePath(), message }), (0, textRange_1.getEmptyRange)());
633
- this._parseDiagnostics = diagSink.fetchAndClear();
665
+ this._writableData.parseDiagnostics = diagSink.fetchAndClear();
634
666
  // Do not rethrow the exception, swallow it here. Callers are not
635
667
  // prepared to handle an exception.
636
668
  }
637
- this._analyzedFileContentsVersion = this._fileContentsVersion;
638
- this._indexingNeeded = true;
639
- this._isBindingNeeded = true;
640
- this._isCheckingNeeded = true;
641
- this._parseTreeNeedsCleaning = false;
642
- this._hitMaxImportDepth = undefined;
643
- this._diagnosticVersion++;
669
+ this._writableData.analyzedFileContentsVersion = this._writableData.fileContentsVersion;
670
+ this._writableData.indexingNeeded = true;
671
+ this._writableData.isBindingNeeded = true;
672
+ this._writableData.isCheckingNeeded = true;
673
+ this._writableData.parseTreeNeedsCleaning = false;
674
+ this._writableData.hitMaxImportDepth = undefined;
675
+ this._writableData.diagnosticVersion++;
644
676
  return true;
645
677
  });
646
678
  }
647
- index(options, token) {
648
- return this._logTracker.log(`indexing: ${this._getPathForLogging(this._filePath)}`, (ls) => {
649
- // If we have no completed analysis job, there's nothing to do.
650
- if (!this._parseResults || !this.isIndexingRequired()) {
651
- ls.suppress();
652
- return undefined;
653
- }
654
- this._indexingNeeded = false;
655
- const symbols = documentSymbolProvider_1.DocumentSymbolProvider.indexSymbols(AnalyzerNodeInfo.getFileInfo(this._parseResults.parseTree), this._parseResults, options, token);
656
- ls.add(`found ${symbols.length}`);
657
- const name = (0, pathUtils_1.stripFileExtension)((0, pathUtils_1.getFileName)(this._filePath));
658
- const privateOrProtected = SymbolNameUtils.isPrivateOrProtectedName(name);
659
- return { privateOrProtected, symbols };
660
- });
661
- }
662
- addHierarchicalSymbolsForDocument(symbolList, token) {
663
- // If we have no completed analysis job, there's nothing to do.
664
- if (!this._parseResults && !this._cachedIndexResults) {
665
- return;
666
- }
667
- documentSymbolProvider_1.DocumentSymbolProvider.addHierarchicalSymbolsForDocument(this._parseResults ? AnalyzerNodeInfo.getFileInfo(this._parseResults.parseTree) : undefined, this.getCachedIndexResults(), this._parseResults, symbolList, token);
668
- }
669
- getSymbolsForDocument(query, token) {
670
- // If we have no completed analysis job, there's nothing to do.
671
- if (!this._parseResults && !this._cachedIndexResults) {
672
- return [];
673
- }
674
- return documentSymbolProvider_1.DocumentSymbolProvider.getSymbolsForDocument(this._parseResults ? AnalyzerNodeInfo.getFileInfo(this._parseResults.parseTree) : undefined, this.getCachedIndexResults(), this._parseResults, this._filePath, query, token);
675
- }
676
- getCompletionsForPosition(position, workspacePath, configOptions, importResolver, importLookup, evaluator, options, sourceMapper, nameMap, libraryMap, moduleSymbolsCallback, token) {
677
- // If we have no completed analysis job, there's nothing to do.
678
- if (!this._parseResults) {
679
- return undefined;
680
- }
681
- // This command should be called only for open files, in which
682
- // case we should have the file contents already loaded.
683
- const fileContents = this.getOpenFileContents();
684
- if (fileContents === undefined) {
685
- return undefined;
686
- }
687
- const completionProvider = new completionProvider_1.CompletionProvider(workspacePath, this._parseResults, fileContents, importResolver, position, this._filePath, configOptions, importLookup, evaluator, options, sourceMapper, {
688
- nameMap,
689
- libraryMap,
690
- getModuleSymbolsMap: moduleSymbolsCallback,
691
- }, token);
692
- return completionProvider.getCompletionsForPosition();
693
- }
694
- resolveCompletionItem(configOptions, importResolver, importLookup, evaluator, options, sourceMapper, nameMap, libraryMap, moduleSymbolsCallback, completionItem, token) {
695
- const fileContents = this.getOpenFileContents();
696
- if (!this._parseResults || fileContents === undefined) {
697
- return;
698
- }
699
- const completionData = (0, lspUtils_1.fromLSPAny)(completionItem.data);
700
- const completionProvider = new completionProvider_1.CompletionProvider(completionData.workspacePath, this._parseResults, fileContents, importResolver, completionData.position, this._filePath, configOptions, importLookup, evaluator, options, sourceMapper, {
701
- nameMap,
702
- libraryMap,
703
- getModuleSymbolsMap: moduleSymbolsCallback,
704
- }, token);
705
- completionProvider.resolveCompletionItem(completionItem);
706
- }
707
679
  bind(configOptions, importLookup, builtinsScope, futureImports) {
708
680
  (0, debug_1.assert)(!this.isParseRequired(), 'Bind called before parsing');
709
681
  (0, debug_1.assert)(this.isBindingRequired(), 'Bind called unnecessarily');
710
- (0, debug_1.assert)(!this._isBindingInProgress, 'Bind called while binding in progress');
711
- (0, debug_1.assert)(this._parseResults !== undefined, 'Parse results not available');
682
+ (0, debug_1.assert)(!this._writableData.isBindingInProgress, 'Bind called while binding in progress');
683
+ (0, debug_1.assert)(this._writableData.parseResults !== undefined, 'Parse results not available');
712
684
  return this._logTracker.log(`binding: ${this._getPathForLogging(this._filePath)}`, () => {
713
685
  try {
714
686
  // Perform name binding.
715
687
  timing_1.timingStats.bindTime.timeOperation(() => {
716
688
  this._cleanParseTreeIfRequired();
717
- const fileInfo = this._buildFileInfo(configOptions, this._parseResults.text, importLookup, builtinsScope, futureImports);
718
- AnalyzerNodeInfo.setFileInfo(this._parseResults.parseTree, fileInfo);
689
+ const fileInfo = this._buildFileInfo(configOptions, this._writableData.parseResults.text, importLookup, builtinsScope, futureImports);
690
+ AnalyzerNodeInfo.setFileInfo(this._writableData.parseResults.parseTree, fileInfo);
719
691
  const binder = new binder_1.Binder(fileInfo, configOptions.indexGenerationMode);
720
- this._isBindingInProgress = true;
721
- binder.bindModule(this._parseResults.parseTree);
692
+ this._writableData.isBindingInProgress = true;
693
+ binder.bindModule(this._writableData.parseResults.parseTree);
722
694
  // If we're in "test mode" (used for unit testing), run an additional
723
695
  // "test walker" over the parse tree to validate its internal consistency.
724
696
  if (configOptions.internalTestMode) {
725
697
  const testWalker = new testWalker_1.TestWalker();
726
- testWalker.walk(this._parseResults.parseTree);
698
+ testWalker.walk(this._writableData.parseResults.parseTree);
727
699
  }
728
- this._bindDiagnostics = fileInfo.diagnosticSink.fetchAndClear();
729
- const moduleScope = AnalyzerNodeInfo.getScope(this._parseResults.parseTree);
700
+ this._writableData.bindDiagnostics = fileInfo.diagnosticSink.fetchAndClear();
701
+ const moduleScope = AnalyzerNodeInfo.getScope(this._writableData.parseResults.parseTree);
730
702
  (0, debug_1.assert)(moduleScope !== undefined, 'Module scope not returned by binder');
731
- this._moduleSymbolTable = moduleScope.symbolTable;
703
+ this._writableData.moduleSymbolTable = moduleScope.symbolTable;
732
704
  });
733
705
  }
734
706
  catch (e) {
@@ -738,36 +710,36 @@ class SourceFile {
738
710
  this._console.error(localize_1.Localizer.Diagnostic.internalBindError().format({ file: this.getFilePath(), message }));
739
711
  const diagSink = new diagnosticSink_1.DiagnosticSink();
740
712
  diagSink.addError(localize_1.Localizer.Diagnostic.internalBindError().format({ file: this.getFilePath(), message }), (0, textRange_1.getEmptyRange)());
741
- this._bindDiagnostics = diagSink.fetchAndClear();
713
+ this._writableData.bindDiagnostics = diagSink.fetchAndClear();
742
714
  // Do not rethrow the exception, swallow it here. Callers are not
743
715
  // prepared to handle an exception.
744
716
  }
745
717
  finally {
746
- this._isBindingInProgress = false;
718
+ this._writableData.isBindingInProgress = false;
747
719
  }
748
720
  // Prepare for the next stage of the analysis.
749
- this._diagnosticVersion++;
750
- this._isCheckingNeeded = true;
751
- this._indexingNeeded = true;
752
- this._isBindingNeeded = false;
721
+ this._writableData.diagnosticVersion++;
722
+ this._writableData.isCheckingNeeded = true;
723
+ this._writableData.indexingNeeded = true;
724
+ this._writableData.isBindingNeeded = false;
753
725
  });
754
726
  }
755
727
  check(importResolver, evaluator, sourceMapper, dependentFiles) {
756
728
  (0, debug_1.assert)(!this.isParseRequired(), 'Check called before parsing');
757
729
  (0, debug_1.assert)(!this.isBindingRequired(), 'Check called before binding');
758
- (0, debug_1.assert)(!this._isBindingInProgress, 'Check called while binding in progress');
730
+ (0, debug_1.assert)(!this._writableData.isBindingInProgress, 'Check called while binding in progress');
759
731
  (0, debug_1.assert)(this.isCheckingRequired(), 'Check called unnecessarily');
760
- (0, debug_1.assert)(this._parseResults !== undefined, 'Parse results not available');
732
+ (0, debug_1.assert)(this._writableData.parseResults !== undefined, 'Parse results not available');
761
733
  return this._logTracker.log(`checking: ${this._getPathForLogging(this._filePath)}`, () => {
762
734
  try {
763
735
  timing_1.timingStats.typeCheckerTime.timeOperation(() => {
764
736
  const checkDuration = new timing_1.Duration();
765
- const checker = new checker_1.Checker(importResolver, evaluator, this._parseResults, sourceMapper, dependentFiles);
737
+ const checker = new checker_1.Checker(importResolver, evaluator, this._writableData.parseResults, sourceMapper, dependentFiles);
766
738
  checker.check();
767
- this._isCheckingNeeded = false;
768
- const fileInfo = AnalyzerNodeInfo.getFileInfo(this._parseResults.parseTree);
769
- this._checkerDiagnostics = fileInfo.diagnosticSink.fetchAndClear();
770
- this._checkTime = checkDuration.getDurationInMilliseconds();
739
+ this._writableData.isCheckingNeeded = false;
740
+ const fileInfo = AnalyzerNodeInfo.getFileInfo(this._writableData.parseResults.parseTree);
741
+ this._writableData.checkerDiagnostics = fileInfo.diagnosticSink.fetchAndClear();
742
+ this._writableData.checkTime = checkDuration.getDurationInMilliseconds();
771
743
  });
772
744
  }
773
745
  catch (e) {
@@ -779,9 +751,9 @@ class SourceFile {
779
751
  this._console.error(localize_1.Localizer.Diagnostic.internalTypeCheckingError().format({ file: this.getFilePath(), message }));
780
752
  const diagSink = new diagnosticSink_1.DiagnosticSink();
781
753
  diagSink.addError(localize_1.Localizer.Diagnostic.internalTypeCheckingError().format({ file: this.getFilePath(), message }), (0, textRange_1.getEmptyRange)());
782
- this._checkerDiagnostics = diagSink.fetchAndClear();
754
+ this._writableData.checkerDiagnostics = diagSink.fetchAndClear();
783
755
  // Mark the file as complete so we don't get into an infinite loop.
784
- this._isCheckingNeeded = false;
756
+ this._writableData.isCheckingNeeded = false;
785
757
  }
786
758
  throw e;
787
759
  }
@@ -789,14 +761,26 @@ class SourceFile {
789
761
  // Clear any circular dependencies associated with this file.
790
762
  // These will be detected by the program module and associated
791
763
  // with the source file right before it is finalized.
792
- this._circularDependencies = [];
793
- this._diagnosticVersion++;
764
+ this._writableData.circularDependencies = [];
765
+ this._writableData.diagnosticVersion++;
794
766
  }
795
767
  });
796
768
  }
797
769
  test_enableIPythonMode(enable) {
798
770
  this._ipythonMode = enable ? IPythonMode.CellDocs : IPythonMode.None;
799
771
  }
772
+ _cachePreEditState() {
773
+ // If there's no document yet, this change doesn't count as a write yet.
774
+ if (this._writableData.clientDocumentContents !== undefined) {
775
+ // If this is our first write, then make a copy of the writable data.
776
+ if (this._isEditMode && !this._preEditData) {
777
+ // Copy over the writable data.
778
+ this._preEditData = this._writableData;
779
+ // Recreate all the writable data from scratch.
780
+ this._writableData = new WriteableData();
781
+ }
782
+ }
783
+ }
800
784
  // Get all task list diagnostics for the current file and add them
801
785
  // to the specified diagnostic list
802
786
  _addTaskListDiagnostics(taskListTokens, diagList) {
@@ -806,10 +790,10 @@ class SourceFile {
806
790
  return;
807
791
  }
808
792
  // if we have no tokens, we're done
809
- if (!((_b = (_a = this._parseResults) === null || _a === void 0 ? void 0 : _a.tokenizerOutput) === null || _b === void 0 ? void 0 : _b.tokens)) {
793
+ if (!((_b = (_a = this._writableData.parseResults) === null || _a === void 0 ? void 0 : _a.tokenizerOutput) === null || _b === void 0 ? void 0 : _b.tokens)) {
810
794
  return;
811
795
  }
812
- const tokenizerOutput = this._parseResults.tokenizerOutput;
796
+ const tokenizerOutput = this._writableData.parseResults.tokenizerOutput;
813
797
  for (let i = 0; i < tokenizerOutput.tokens.count; i++) {
814
798
  const token = tokenizerOutput.tokens.getItemAt(i);
815
799
  // if there are no comments, skip this token
@@ -845,8 +829,8 @@ class SourceFile {
845
829
  }
846
830
  }
847
831
  _buildFileInfo(configOptions, fileContents, importLookup, builtinsScope, futureImports) {
848
- (0, debug_1.assert)(this._parseResults !== undefined, 'Parse results not available');
849
- const analysisDiagnostics = new diagnosticSink_1.TextRangeDiagnosticSink(this._parseResults.tokenizerOutput.lines);
832
+ (0, debug_1.assert)(this._writableData.parseResults !== undefined, 'Parse results not available');
833
+ const analysisDiagnostics = new diagnosticSink_1.TextRangeDiagnosticSink(this._writableData.parseResults.tokenizerOutput.lines);
850
834
  const fileInfo = {
851
835
  importLookup,
852
836
  futureImports,
@@ -855,11 +839,11 @@ class SourceFile {
855
839
  executionEnvironment: configOptions.findExecEnvironment(this._filePath),
856
840
  diagnosticRuleSet: this._diagnosticRuleSet,
857
841
  fileContents,
858
- lines: this._parseResults.tokenizerOutput.lines,
859
- typingSymbolAliases: this._parseResults.typingSymbolAliases,
842
+ lines: this._writableData.parseResults.tokenizerOutput.lines,
843
+ typingSymbolAliases: this._writableData.parseResults.typingSymbolAliases,
860
844
  definedConstants: configOptions.defineConstant,
861
845
  filePath: this._filePath,
862
- moduleName: this._moduleName,
846
+ moduleName: this.getModuleName(),
863
847
  isStubFile: this._isStubFile,
864
848
  isTypingStubFile: this._isTypingStubFile,
865
849
  isTypingExtensionsStubFile: this._isTypingExtensionsStubFile,
@@ -871,11 +855,11 @@ class SourceFile {
871
855
  return fileInfo;
872
856
  }
873
857
  _cleanParseTreeIfRequired() {
874
- if (this._parseResults) {
875
- if (this._parseTreeNeedsCleaning) {
876
- const cleanerWalker = new parseTreeCleaner_1.ParseTreeCleanerWalker(this._parseResults.parseTree);
858
+ if (this._writableData.parseResults) {
859
+ if (this._writableData.parseTreeNeedsCleaning) {
860
+ const cleanerWalker = new parseTreeCleaner_1.ParseTreeCleanerWalker(this._writableData.parseResults.parseTree);
877
861
  cleanerWalker.clean();
878
- this._parseTreeNeedsCleaning = false;
862
+ this._writableData.parseTreeNeedsCleaning = false;
879
863
  }
880
864
  }
881
865
  }
@@ -940,10 +924,7 @@ class SourceFile {
940
924
  };
941
925
  }
942
926
  _getPathForLogging(filepath) {
943
- if (this.fileSystem.isMappedFilePath(filepath)) {
944
- return this.fileSystem.getOriginalFilePath(filepath);
945
- }
946
- return filepath;
927
+ return (0, logTracker_1.getPathForLogging)(this.fileSystem, filepath);
947
928
  }
948
929
  }
949
930
  exports.SourceFile = SourceFile;