@zzzen/pyright-internal 1.2.0-dev.20230430 → 1.2.0-dev.20230507
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.
- package/dist/analyzer/backgroundAnalysisProgram.d.ts +3 -0
- package/dist/analyzer/backgroundAnalysisProgram.js +12 -0
- package/dist/analyzer/backgroundAnalysisProgram.js.map +1 -1
- package/dist/analyzer/checker.d.ts +1 -0
- package/dist/analyzer/checker.js +52 -4
- package/dist/analyzer/checker.js.map +1 -1
- package/dist/analyzer/constructors.d.ts +6 -0
- package/dist/analyzer/constructors.js +456 -0
- package/dist/analyzer/constructors.js.map +1 -0
- package/dist/analyzer/dataClasses.js +84 -0
- package/dist/analyzer/dataClasses.js.map +1 -1
- package/dist/analyzer/enums.js +54 -8
- package/dist/analyzer/enums.js.map +1 -1
- package/dist/analyzer/importStatementUtils.d.ts +2 -2
- package/dist/analyzer/importStatementUtils.js.map +1 -1
- package/dist/analyzer/namedTuples.js +1 -1
- package/dist/analyzer/namedTuples.js.map +1 -1
- package/dist/analyzer/operations.d.ts +16 -0
- package/dist/analyzer/operations.js +749 -0
- package/dist/analyzer/operations.js.map +1 -0
- package/dist/analyzer/parseTreeUtils.d.ts +4 -2
- package/dist/analyzer/parseTreeUtils.js +32 -1
- package/dist/analyzer/parseTreeUtils.js.map +1 -1
- package/dist/analyzer/patternMatching.js +16 -0
- package/dist/analyzer/patternMatching.js.map +1 -1
- package/dist/analyzer/program.d.ts +5 -17
- package/dist/analyzer/program.js +46 -493
- package/dist/analyzer/program.js.map +1 -1
- package/dist/analyzer/service.d.ts +3 -11
- package/dist/analyzer/service.js +16 -12
- package/dist/analyzer/service.js.map +1 -1
- package/dist/analyzer/sourceFile.d.ts +10 -33
- package/dist/analyzer/sourceFile.js +225 -181
- package/dist/analyzer/sourceFile.js.map +1 -1
- package/dist/analyzer/sourceFileInfoUtils.d.ts +3 -9
- package/dist/analyzer/sourceFileInfoUtils.js.map +1 -1
- package/dist/analyzer/typeEvaluator.js +100 -1285
- package/dist/analyzer/typeEvaluator.js.map +1 -1
- package/dist/analyzer/typeEvaluatorTypes.d.ts +38 -7
- package/dist/analyzer/typeEvaluatorTypes.js +33 -1
- package/dist/analyzer/typeEvaluatorTypes.js.map +1 -1
- package/dist/analyzer/typeGuards.js +2 -8
- package/dist/analyzer/typeGuards.js.map +1 -1
- package/dist/analyzer/typeUtils.d.ts +2 -0
- package/dist/analyzer/typeUtils.js +33 -3
- package/dist/analyzer/typeUtils.js.map +1 -1
- package/dist/analyzer/typeVarContext.d.ts +5 -5
- package/dist/analyzer/typeVarContext.js +7 -0
- package/dist/analyzer/typeVarContext.js.map +1 -1
- package/dist/analyzer/typedDicts.js +2 -2
- package/dist/analyzer/typedDicts.js.map +1 -1
- package/dist/analyzer/types.d.ts +4 -2
- package/dist/analyzer/types.js +7 -0
- package/dist/analyzer/types.js.map +1 -1
- package/dist/common/extensibility.d.ts +2 -1
- package/dist/common/extensibility.js.map +1 -1
- package/dist/common/pathUtils.d.ts +11 -11
- package/dist/common/pathUtils.js.map +1 -1
- package/dist/common/workspaceEditUtils.d.ts +5 -5
- package/dist/common/workspaceEditUtils.js.map +1 -1
- package/dist/languageServerBase.d.ts +1 -2
- package/dist/languageServerBase.js +8 -13
- package/dist/languageServerBase.js.map +1 -1
- package/dist/languageService/callHierarchyProvider.d.ts +1 -1
- package/dist/languageService/callHierarchyProvider.js +5 -5
- package/dist/languageService/callHierarchyProvider.js.map +1 -1
- package/dist/languageService/completionProvider.d.ts +10 -13
- package/dist/languageService/completionProvider.js +21 -10
- package/dist/languageService/completionProvider.js.map +1 -1
- package/dist/languageService/documentHighlightProvider.js +1 -1
- package/dist/languageService/documentHighlightProvider.js.map +1 -1
- package/dist/languageService/documentSymbolCollector.d.ts +6 -7
- package/dist/languageService/documentSymbolCollector.js +17 -8
- package/dist/languageService/documentSymbolCollector.js.map +1 -1
- package/dist/languageService/hoverProvider.d.ts +4 -3
- package/dist/languageService/hoverProvider.js +29 -35
- package/dist/languageService/hoverProvider.js.map +1 -1
- package/dist/languageService/referencesProvider.d.ts +7 -12
- package/dist/languageService/referencesProvider.js +25 -17
- package/dist/languageService/referencesProvider.js.map +1 -1
- package/dist/languageService/renameProvider.d.ts +17 -0
- package/dist/languageService/renameProvider.js +143 -0
- package/dist/languageService/renameProvider.js.map +1 -0
- package/dist/localization/localize.d.ts +17 -14
- package/dist/localization/localize.js +4 -6
- package/dist/localization/localize.js.map +1 -1
- package/dist/localization/package.nls.en-us.json +5 -6
- package/dist/tests/documentSymbolCollector.test.js +3 -3
- package/dist/tests/documentSymbolCollector.test.js.map +1 -1
- package/dist/tests/fourslash/fourslash.d.ts +4 -4
- package/dist/tests/fourslash/missingTypeStub.codeAction.fourslash.js +1 -1
- package/dist/tests/fourslash/missingTypeStub.codeAction.fourslash.js.map +1 -1
- package/dist/tests/harness/fourslash/testState.d.ts +3 -3
- package/dist/tests/harness/fourslash/testState.js +14 -14
- package/dist/tests/harness/fourslash/testState.js.map +1 -1
- package/dist/tests/sourceFile.test.js +1 -1
- package/dist/tests/sourceFile.test.js.map +1 -1
- package/dist/tests/testStateUtils.d.ts +2 -2
- package/dist/tests/testStateUtils.js +38 -8
- package/dist/tests/testStateUtils.js.map +1 -1
- package/dist/tests/typeEvaluator2.test.js +1 -1
- package/dist/tests/typeEvaluator3.test.js +1 -1
- package/dist/tests/typeEvaluator4.test.js +9 -1
- package/dist/tests/typeEvaluator4.test.js.map +1 -1
- package/dist/tests/typeEvaluator5.test.js +4 -0
- package/dist/tests/typeEvaluator5.test.js.map +1 -1
- package/dist/tests/workspaceEditUtils.test.js +84 -0
- package/dist/tests/workspaceEditUtils.test.js.map +1 -1
- package/package.json +4 -4
- package/dist/languageService/indentationUtils.d.ts +0 -16
- package/dist/languageService/indentationUtils.js +0 -727
- package/dist/languageService/indentationUtils.js.map +0 -1
- package/dist/languageService/insertionPointUtils.d.ts +0 -9
- package/dist/languageService/insertionPointUtils.js +0 -132
- package/dist/languageService/insertionPointUtils.js.map +0 -1
- package/dist/languageService/renameModuleProvider.d.ts +0 -65
- package/dist/languageService/renameModuleProvider.js +0 -939
- package/dist/languageService/renameModuleProvider.js.map +0 -1
- package/dist/tests/indentationUtils.ptvs.test.d.ts +0 -1
- package/dist/tests/indentationUtils.ptvs.test.js +0 -324
- package/dist/tests/indentationUtils.ptvs.test.js.map +0 -1
- package/dist/tests/indentationUtils.reindent.test.d.ts +0 -1
- package/dist/tests/indentationUtils.reindent.test.js +0 -372
- package/dist/tests/indentationUtils.reindent.test.js.map +0 -1
- package/dist/tests/indentationUtils.test.d.ts +0 -1
- package/dist/tests/indentationUtils.test.js +0 -502
- package/dist/tests/indentationUtils.test.js.map +0 -1
- package/dist/tests/insertionPointUtils.test.d.ts +0 -1
- package/dist/tests/insertionPointUtils.test.js +0 -154
- package/dist/tests/insertionPointUtils.test.js.map +0 -1
- package/dist/tests/moveSymbol.importAdder.test.d.ts +0 -1
- package/dist/tests/moveSymbol.importAdder.test.js +0 -298
- package/dist/tests/moveSymbol.importAdder.test.js.map +0 -1
- package/dist/tests/moveSymbol.insertion.test.d.ts +0 -1
- package/dist/tests/moveSymbol.insertion.test.js +0 -537
- package/dist/tests/moveSymbol.insertion.test.js.map +0 -1
- package/dist/tests/moveSymbol.misc.test.d.ts +0 -1
- package/dist/tests/moveSymbol.misc.test.js +0 -169
- package/dist/tests/moveSymbol.misc.test.js.map +0 -1
- package/dist/tests/moveSymbol.updateReference.test.d.ts +0 -1
- package/dist/tests/moveSymbol.updateReference.test.js +0 -1071
- package/dist/tests/moveSymbol.updateReference.test.js.map +0 -1
- package/dist/tests/renameModule.folder.test.d.ts +0 -1
- package/dist/tests/renameModule.folder.test.js +0 -229
- package/dist/tests/renameModule.folder.test.js.map +0 -1
- package/dist/tests/renameModule.fromImports.test.d.ts +0 -1
- package/dist/tests/renameModule.fromImports.test.js +0 -790
- package/dist/tests/renameModule.fromImports.test.js.map +0 -1
- package/dist/tests/renameModule.imports.test.d.ts +0 -1
- package/dist/tests/renameModule.imports.test.js +0 -380
- package/dist/tests/renameModule.imports.test.js.map +0 -1
- package/dist/tests/renameModule.misc.test.d.ts +0 -1
- package/dist/tests/renameModule.misc.test.js +0 -615
- package/dist/tests/renameModule.misc.test.js.map +0 -1
- package/dist/tests/renameModule.relativePath.test.d.ts +0 -1
- package/dist/tests/renameModule.relativePath.test.js +0 -231
- package/dist/tests/renameModule.relativePath.test.js.map +0 -1
- package/dist/tests/renameModuleTestUtils.d.ts +0 -4
- package/dist/tests/renameModuleTestUtils.js +0 -76
- package/dist/tests/renameModuleTestUtils.js.map +0 -1
@@ -72,50 +72,58 @@ var IPythonMode;
|
|
72
72
|
// Each cell is its own document.
|
73
73
|
IPythonMode[IPythonMode["CellDocs"] = 1] = "CellDocs";
|
74
74
|
})(IPythonMode = exports.IPythonMode || (exports.IPythonMode = {}));
|
75
|
-
class
|
76
|
-
constructor(
|
77
|
-
// True if the file appears to have been deleted.
|
78
|
-
this._isFileDeleted = false;
|
75
|
+
class WriteableData {
|
76
|
+
constructor() {
|
79
77
|
// Number that is incremented every time the diagnostics
|
80
78
|
// are updated.
|
81
|
-
this.
|
79
|
+
this.diagnosticVersion = 0;
|
82
80
|
// Generation count of the file contents. When the contents
|
83
81
|
// change, this is incremented.
|
84
|
-
this.
|
82
|
+
this.fileContentsVersion = 0;
|
85
83
|
// Length and hash of the file the last time it was read from disk.
|
86
|
-
this.
|
87
|
-
this.
|
84
|
+
this.lastFileContentLength = undefined;
|
85
|
+
this.lastFileContentHash = undefined;
|
88
86
|
// Version of file contents that have been analyzed.
|
89
|
-
this.
|
87
|
+
this.analyzedFileContentsVersion = -1;
|
90
88
|
// Do we need to walk the parse tree and clean
|
91
89
|
// the binder information hanging from it?
|
92
|
-
this.
|
90
|
+
this.parseTreeNeedsCleaning = false;
|
93
91
|
// Reentrancy check for binding.
|
94
|
-
this.
|
92
|
+
this.isBindingInProgress = false;
|
95
93
|
// Diagnostics generated during different phases of analysis.
|
96
|
-
this.
|
97
|
-
this.
|
98
|
-
this.
|
99
|
-
this.
|
100
|
-
this.
|
101
|
-
this.
|
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)();
|
94
|
+
this.parseDiagnostics = [];
|
95
|
+
this.commentDiagnostics = [];
|
96
|
+
this.bindDiagnostics = [];
|
97
|
+
this.checkerDiagnostics = [];
|
98
|
+
this.typeIgnoreLines = new Map();
|
99
|
+
this.pyrightIgnoreLines = new Map();
|
106
100
|
// Circular dependencies that have been reported in this file.
|
107
|
-
this.
|
108
|
-
this.
|
101
|
+
this.circularDependencies = [];
|
102
|
+
this.noCircularDependencyConfirmed = false;
|
109
103
|
// Do we need to perform a binding step?
|
110
|
-
this.
|
104
|
+
this.isBindingNeeded = true;
|
111
105
|
// Do we have valid diagnostic results from a checking pass?
|
112
|
-
this.
|
106
|
+
this.isCheckingNeeded = true;
|
113
107
|
// Do we need to perform an indexing step?
|
114
|
-
this.
|
108
|
+
this.indexingNeeded = true;
|
109
|
+
// True if the file appears to have been deleted.
|
110
|
+
this.isFileDeleted = false;
|
111
|
+
}
|
112
|
+
}
|
113
|
+
class SourceFile {
|
114
|
+
constructor(fs, filePath, moduleName, isThirdPartyImport, isThirdPartyPyTypedPresent, editMode, console, logTracker, realFilePath, ipythonMode = IPythonMode.None) {
|
115
|
+
// Data that changes when the source file changes.
|
116
|
+
this._writableData = new WriteableData();
|
117
|
+
// Settings that control which diagnostics should be output. The rules
|
118
|
+
// are initialized to the basic set. They should be updated after the
|
119
|
+
// the file is parsed.
|
120
|
+
this._diagnosticRuleSet = (0, configOptions_1.getBasicDiagnosticRuleSet)();
|
115
121
|
// Indicate whether this file is for ipython or not.
|
116
122
|
this._ipythonMode = IPythonMode.None;
|
123
|
+
this._isEditMode = false;
|
117
124
|
this.fileSystem = fs;
|
118
125
|
this._console = console || new console_1.StandardConsole();
|
126
|
+
this._isEditMode = editMode;
|
119
127
|
this._filePath = filePath;
|
120
128
|
this._realFilePath = realFilePath !== null && realFilePath !== void 0 ? realFilePath : filePath;
|
121
129
|
this._moduleName = moduleName;
|
@@ -162,7 +170,7 @@ class SourceFile {
|
|
162
170
|
this._moduleName = name;
|
163
171
|
}
|
164
172
|
getDiagnosticVersion() {
|
165
|
-
return this.
|
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.
|
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.
|
188
|
-
...this.
|
189
|
-
...this.
|
190
|
-
...this.
|
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.
|
194
|
-
const pyrightIgnoreLinesClone = new Map(this.
|
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.
|
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.
|
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.
|
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.
|
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.
|
267
|
-
const rangeStart = this.
|
268
|
-
const rangeEnd = rangeStart + this.
|
269
|
-
const range = (0, positionUtils_1.convertOffsetsToRange)(rangeStart, rangeEnd, this.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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' &&
|
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.
|
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.
|
325
|
-
diagList.push(new diagnostic_1.Diagnostic(0 /* Error */, localize_1.Localizer.Diagnostic.importDepthExceeded().format({ depth: this.
|
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.
|
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.
|
364
|
+
return this._writableData.imports || [];
|
356
365
|
}
|
357
366
|
getBuiltinsImport() {
|
358
|
-
return this.
|
367
|
+
return this._writableData.builtinsImport;
|
359
368
|
}
|
360
369
|
getIPythonDisplayImport() {
|
361
|
-
return this.
|
370
|
+
return this._writableData.ipythonDisplayImport;
|
362
371
|
}
|
363
372
|
getModuleSymbolTable() {
|
364
|
-
return this.
|
373
|
+
return this._writableData.moduleSymbolTable;
|
365
374
|
}
|
366
375
|
getCheckTime() {
|
367
|
-
return this.
|
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.
|
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.
|
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.
|
410
|
+
if (fileContents.length !== this._writableData.lastFileContentLength) {
|
388
411
|
return true;
|
389
412
|
}
|
390
|
-
if (StringUtils.hashString(fileContents) !== this.
|
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.
|
404
|
-
this.
|
405
|
-
this.
|
426
|
+
this._writableData.parseResults = undefined;
|
427
|
+
this._writableData.moduleSymbolTable = undefined;
|
428
|
+
this._writableData.isBindingNeeded = true;
|
406
429
|
}
|
407
430
|
markDirty(indexingNeeded = true) {
|
408
|
-
this.
|
409
|
-
this.
|
410
|
-
this.
|
411
|
-
this.
|
412
|
-
this.
|
413
|
-
this.
|
414
|
-
this.
|
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.
|
421
|
-
this.
|
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.
|
425
|
-
if (this.
|
426
|
-
AnalyzerNodeInfo.getDunderAllInfo(this.
|
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.
|
432
|
-
this.
|
433
|
-
this.
|
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.
|
461
|
+
return this._writableData.clientDocumentVersion;
|
439
462
|
}
|
440
463
|
getOpenFileContents() {
|
441
|
-
return this.
|
464
|
+
return this._writableData.clientDocumentContents;
|
442
465
|
}
|
443
466
|
getFileContent() {
|
444
467
|
// Get current buffer content if the file is opened.
|
@@ -462,82 +485,86 @@ 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.
|
467
|
-
this.
|
491
|
+
this._writableData.clientDocumentVersion = undefined;
|
492
|
+
this._writableData.clientDocumentContents = undefined;
|
468
493
|
}
|
469
494
|
else {
|
470
|
-
this.
|
471
|
-
this.
|
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.
|
499
|
+
if (contents.length !== this._writableData.lastFileContentLength ||
|
500
|
+
contentsHash !== this._writableData.lastFileContentHash) {
|
475
501
|
this.markDirty();
|
476
502
|
}
|
477
|
-
this.
|
478
|
-
this.
|
479
|
-
this.
|
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.
|
512
|
+
return this._writableData.isFileDeleted;
|
487
513
|
}
|
488
514
|
isParseRequired() {
|
489
|
-
return !this.
|
515
|
+
return (!this._writableData.parseResults ||
|
516
|
+
this._writableData.analyzedFileContentsVersion !== this._writableData.fileContentsVersion);
|
490
517
|
}
|
491
518
|
isBindingRequired() {
|
492
|
-
if (this.
|
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.
|
525
|
+
return this._writableData.isBindingNeeded;
|
499
526
|
}
|
500
527
|
isIndexingRequired() {
|
501
|
-
return this.
|
528
|
+
return this._writableData.indexingNeeded;
|
502
529
|
}
|
503
530
|
isCheckingRequired() {
|
504
|
-
return this.
|
531
|
+
return this._writableData.isCheckingNeeded;
|
505
532
|
}
|
506
533
|
getParseResults() {
|
507
534
|
if (!this.isParseRequired()) {
|
508
|
-
return this.
|
535
|
+
return this._writableData.parseResults;
|
509
536
|
}
|
510
537
|
return undefined;
|
511
538
|
}
|
512
539
|
getCachedIndexResults() {
|
513
|
-
return this.
|
540
|
+
return this._writableData.cachedIndexResults;
|
514
541
|
}
|
515
542
|
cacheIndexResults(indexResults) {
|
516
|
-
this.
|
543
|
+
this._writableData.cachedIndexResults = indexResults;
|
517
544
|
}
|
518
545
|
// Adds a new circular dependency for this file but only if
|
519
546
|
// it hasn't already been added.
|
520
547
|
addCircularDependency(circDependency) {
|
521
548
|
let updatedDependencyList = false;
|
522
549
|
// Some topologies can result in a massive number of cycles. We'll cut it off.
|
523
|
-
if (this.
|
524
|
-
if (!this.
|
525
|
-
this.
|
550
|
+
if (this._writableData.circularDependencies.length < _maxImportCyclesPerFile) {
|
551
|
+
if (!this._writableData.circularDependencies.some((dep) => dep.isEqual(circDependency))) {
|
552
|
+
this._writableData.circularDependencies.push(circDependency);
|
526
553
|
updatedDependencyList = true;
|
527
554
|
}
|
528
555
|
}
|
529
556
|
if (updatedDependencyList) {
|
530
|
-
this.
|
557
|
+
this._writableData.diagnosticVersion++;
|
531
558
|
}
|
532
559
|
}
|
533
560
|
setNoCircularDependencyConfirmed() {
|
534
|
-
this.
|
561
|
+
this._writableData.noCircularDependencyConfirmed = true;
|
535
562
|
}
|
536
563
|
isNoCircularDependencyConfirmed() {
|
537
|
-
return !this.isParseRequired() && this.
|
564
|
+
return !this.isParseRequired() && this._writableData.noCircularDependencyConfirmed;
|
538
565
|
}
|
539
566
|
setHitMaxImportDepth(maxImportDepth) {
|
540
|
-
this.
|
567
|
+
this._writableData.hitMaxImportDepth = maxImportDepth;
|
541
568
|
}
|
542
569
|
// Parse the file and update the state. Callers should wait for completion
|
543
570
|
// (or at least cancel) prior to calling again. It returns true if a parse
|
@@ -561,8 +588,8 @@ class SourceFile {
|
|
561
588
|
throw new Error("Can't get file content");
|
562
589
|
}
|
563
590
|
// Remember the length and hash for comparison purposes.
|
564
|
-
this.
|
565
|
-
this.
|
591
|
+
this._writableData.lastFileContentLength = fileContents.length;
|
592
|
+
this._writableData.lastFileContentHash = StringUtils.hashString(fileContents);
|
566
593
|
});
|
567
594
|
logState.add(`fs read ${timing_1.timingStats.readFileTime.totalTime - startTime}ms`);
|
568
595
|
}
|
@@ -570,7 +597,7 @@ class SourceFile {
|
|
570
597
|
diagSink.addError(`Source file could not be read`, (0, textRange_1.getEmptyRange)());
|
571
598
|
fileContents = '';
|
572
599
|
if (!this.fileSystem.existsSync(this._realFilePath)) {
|
573
|
-
this.
|
600
|
+
this._writableData.isFileDeleted = true;
|
574
601
|
}
|
575
602
|
}
|
576
603
|
}
|
@@ -578,27 +605,28 @@ class SourceFile {
|
|
578
605
|
// Parse the token stream, building the abstract syntax tree.
|
579
606
|
const parseResults = parseFile(configOptions, this._filePath, fileContents, this._ipythonMode, diagSink);
|
580
607
|
(0, debug_1.assert)(parseResults !== undefined && parseResults.tokenizerOutput !== undefined);
|
581
|
-
this.
|
582
|
-
this.
|
583
|
-
this.
|
584
|
-
this.
|
608
|
+
this._writableData.parseResults = parseResults;
|
609
|
+
this._writableData.typeIgnoreLines = this._writableData.parseResults.tokenizerOutput.typeIgnoreLines;
|
610
|
+
this._writableData.typeIgnoreAll = this._writableData.parseResults.tokenizerOutput.typeIgnoreAll;
|
611
|
+
this._writableData.pyrightIgnoreLines =
|
612
|
+
this._writableData.parseResults.tokenizerOutput.pyrightIgnoreLines;
|
585
613
|
// Resolve imports.
|
586
614
|
const execEnvironment = configOptions.findExecEnvironment(this._filePath);
|
587
615
|
timing_1.timingStats.resolveImportsTime.timeOperation(() => {
|
588
616
|
const importResult = this._resolveImports(importResolver, parseResults.importedModules, execEnvironment);
|
589
|
-
this.
|
590
|
-
this.
|
591
|
-
this.
|
592
|
-
this.
|
617
|
+
this._writableData.imports = importResult.imports;
|
618
|
+
this._writableData.builtinsImport = importResult.builtinsImportResult;
|
619
|
+
this._writableData.ipythonDisplayImport = importResult.ipythonDisplayImportResult;
|
620
|
+
this._writableData.parseDiagnostics = diagSink.fetchAndClear();
|
593
621
|
});
|
594
622
|
// Is this file in a "strict" path?
|
595
623
|
const useStrict = configOptions.strict.find((strictFileSpec) => strictFileSpec.regExp.test(this._realFilePath)) !==
|
596
624
|
undefined;
|
597
625
|
const commentDiags = [];
|
598
|
-
this._diagnosticRuleSet = CommentUtils.getFileLevelDirectives(this.
|
599
|
-
this.
|
626
|
+
this._diagnosticRuleSet = CommentUtils.getFileLevelDirectives(this._writableData.parseResults.tokenizerOutput.tokens, this._writableData.parseResults.tokenizerOutput.lines, configOptions.diagnosticRuleSet, useStrict, commentDiags);
|
627
|
+
this._writableData.commentDiagnostics = [];
|
600
628
|
commentDiags.forEach((commentDiag) => {
|
601
|
-
this.
|
629
|
+
this._writableData.commentDiagnostics.push(new diagnostic_1.Diagnostic(0 /* Error */, commentDiag.message, (0, positionUtils_1.convertTextRangeToRange)(commentDiag.range, this._writableData.parseResults.tokenizerOutput.lines)));
|
602
630
|
});
|
603
631
|
}
|
604
632
|
catch (e) {
|
@@ -607,7 +635,7 @@ class SourceFile {
|
|
607
635
|
JSON.stringify(e);
|
608
636
|
this._console.error(localize_1.Localizer.Diagnostic.internalParseError().format({ file: this.getFilePath(), message }));
|
609
637
|
// Create dummy parse results.
|
610
|
-
this.
|
638
|
+
this._writableData.parseResults = {
|
611
639
|
text: '',
|
612
640
|
parseTree: parseNodes_1.ModuleNode.create({ start: 0, length: 0 }),
|
613
641
|
importedModules: [],
|
@@ -625,34 +653,34 @@ class SourceFile {
|
|
625
653
|
containsWildcardImport: false,
|
626
654
|
typingSymbolAliases: new Map(),
|
627
655
|
};
|
628
|
-
this.
|
629
|
-
this.
|
630
|
-
this.
|
656
|
+
this._writableData.imports = undefined;
|
657
|
+
this._writableData.builtinsImport = undefined;
|
658
|
+
this._writableData.ipythonDisplayImport = undefined;
|
631
659
|
const diagSink = new diagnosticSink_1.DiagnosticSink();
|
632
660
|
diagSink.addError(localize_1.Localizer.Diagnostic.internalParseError().format({ file: this.getFilePath(), message }), (0, textRange_1.getEmptyRange)());
|
633
|
-
this.
|
661
|
+
this._writableData.parseDiagnostics = diagSink.fetchAndClear();
|
634
662
|
// Do not rethrow the exception, swallow it here. Callers are not
|
635
663
|
// prepared to handle an exception.
|
636
664
|
}
|
637
|
-
this.
|
638
|
-
this.
|
639
|
-
this.
|
640
|
-
this.
|
641
|
-
this.
|
642
|
-
this.
|
643
|
-
this.
|
665
|
+
this._writableData.analyzedFileContentsVersion = this._writableData.fileContentsVersion;
|
666
|
+
this._writableData.indexingNeeded = true;
|
667
|
+
this._writableData.isBindingNeeded = true;
|
668
|
+
this._writableData.isCheckingNeeded = true;
|
669
|
+
this._writableData.parseTreeNeedsCleaning = false;
|
670
|
+
this._writableData.hitMaxImportDepth = undefined;
|
671
|
+
this._writableData.diagnosticVersion++;
|
644
672
|
return true;
|
645
673
|
});
|
646
674
|
}
|
647
675
|
index(options, token) {
|
648
676
|
return this._logTracker.log(`indexing: ${this._getPathForLogging(this._filePath)}`, (ls) => {
|
649
677
|
// If we have no completed analysis job, there's nothing to do.
|
650
|
-
if (!this.
|
678
|
+
if (!this._writableData.parseResults || !this.isIndexingRequired()) {
|
651
679
|
ls.suppress();
|
652
680
|
return undefined;
|
653
681
|
}
|
654
|
-
this.
|
655
|
-
const symbols = documentSymbolProvider_1.DocumentSymbolProvider.indexSymbols(AnalyzerNodeInfo.getFileInfo(this.
|
682
|
+
this._writableData.indexingNeeded = false;
|
683
|
+
const symbols = documentSymbolProvider_1.DocumentSymbolProvider.indexSymbols(AnalyzerNodeInfo.getFileInfo(this._writableData.parseResults.parseTree), this._writableData.parseResults, options, token);
|
656
684
|
ls.add(`found ${symbols.length}`);
|
657
685
|
const name = (0, pathUtils_1.stripFileExtension)((0, pathUtils_1.getFileName)(this._filePath));
|
658
686
|
const privateOrProtected = SymbolNameUtils.isPrivateOrProtectedName(name);
|
@@ -661,21 +689,25 @@ class SourceFile {
|
|
661
689
|
}
|
662
690
|
addHierarchicalSymbolsForDocument(symbolList, token) {
|
663
691
|
// If we have no completed analysis job, there's nothing to do.
|
664
|
-
if (!this.
|
692
|
+
if (!this._writableData.parseResults && !this._writableData.cachedIndexResults) {
|
665
693
|
return;
|
666
694
|
}
|
667
|
-
documentSymbolProvider_1.DocumentSymbolProvider.addHierarchicalSymbolsForDocument(this.
|
695
|
+
documentSymbolProvider_1.DocumentSymbolProvider.addHierarchicalSymbolsForDocument(this._writableData.parseResults
|
696
|
+
? AnalyzerNodeInfo.getFileInfo(this._writableData.parseResults.parseTree)
|
697
|
+
: undefined, this.getCachedIndexResults(), this._writableData.parseResults, symbolList, token);
|
668
698
|
}
|
669
699
|
getSymbolsForDocument(query, token) {
|
670
700
|
// If we have no completed analysis job, there's nothing to do.
|
671
|
-
if (!this.
|
701
|
+
if (!this._writableData.parseResults && !this._writableData.cachedIndexResults) {
|
672
702
|
return [];
|
673
703
|
}
|
674
|
-
return documentSymbolProvider_1.DocumentSymbolProvider.getSymbolsForDocument(this.
|
704
|
+
return documentSymbolProvider_1.DocumentSymbolProvider.getSymbolsForDocument(this._writableData.parseResults
|
705
|
+
? AnalyzerNodeInfo.getFileInfo(this._writableData.parseResults.parseTree)
|
706
|
+
: undefined, this.getCachedIndexResults(), this._writableData.parseResults, this._filePath, query, token);
|
675
707
|
}
|
676
|
-
getCompletionsForPosition(position, workspacePath,
|
708
|
+
getCompletionsForPosition(program, position, workspacePath, importLookup, options, nameMap, libraryMap, moduleSymbolsCallback, token) {
|
677
709
|
// If we have no completed analysis job, there's nothing to do.
|
678
|
-
if (!this.
|
710
|
+
if (!this._writableData.parseResults) {
|
679
711
|
return undefined;
|
680
712
|
}
|
681
713
|
// This command should be called only for open files, in which
|
@@ -684,20 +716,20 @@ class SourceFile {
|
|
684
716
|
if (fileContents === undefined) {
|
685
717
|
return undefined;
|
686
718
|
}
|
687
|
-
const completionProvider = new completionProvider_1.CompletionProvider(
|
719
|
+
const completionProvider = new completionProvider_1.CompletionProvider(program, workspacePath, this._filePath, position, importLookup, options, {
|
688
720
|
nameMap,
|
689
721
|
libraryMap,
|
690
722
|
getModuleSymbolsMap: moduleSymbolsCallback,
|
691
723
|
}, token);
|
692
724
|
return completionProvider.getCompletionsForPosition();
|
693
725
|
}
|
694
|
-
resolveCompletionItem(
|
726
|
+
resolveCompletionItem(program, importLookup, options, nameMap, libraryMap, moduleSymbolsCallback, completionItem, token) {
|
695
727
|
const fileContents = this.getOpenFileContents();
|
696
|
-
if (!this.
|
728
|
+
if (!this._writableData.parseResults || fileContents === undefined) {
|
697
729
|
return;
|
698
730
|
}
|
699
731
|
const completionData = (0, lspUtils_1.fromLSPAny)(completionItem.data);
|
700
|
-
const completionProvider = new completionProvider_1.CompletionProvider(completionData.workspacePath, this.
|
732
|
+
const completionProvider = new completionProvider_1.CompletionProvider(program, completionData.workspacePath, this._filePath, completionData.position, importLookup, options, {
|
701
733
|
nameMap,
|
702
734
|
libraryMap,
|
703
735
|
getModuleSymbolsMap: moduleSymbolsCallback,
|
@@ -707,28 +739,28 @@ class SourceFile {
|
|
707
739
|
bind(configOptions, importLookup, builtinsScope, futureImports) {
|
708
740
|
(0, debug_1.assert)(!this.isParseRequired(), 'Bind called before parsing');
|
709
741
|
(0, debug_1.assert)(this.isBindingRequired(), 'Bind called unnecessarily');
|
710
|
-
(0, debug_1.assert)(!this.
|
711
|
-
(0, debug_1.assert)(this.
|
742
|
+
(0, debug_1.assert)(!this._writableData.isBindingInProgress, 'Bind called while binding in progress');
|
743
|
+
(0, debug_1.assert)(this._writableData.parseResults !== undefined, 'Parse results not available');
|
712
744
|
return this._logTracker.log(`binding: ${this._getPathForLogging(this._filePath)}`, () => {
|
713
745
|
try {
|
714
746
|
// Perform name binding.
|
715
747
|
timing_1.timingStats.bindTime.timeOperation(() => {
|
716
748
|
this._cleanParseTreeIfRequired();
|
717
|
-
const fileInfo = this._buildFileInfo(configOptions, this.
|
718
|
-
AnalyzerNodeInfo.setFileInfo(this.
|
749
|
+
const fileInfo = this._buildFileInfo(configOptions, this._writableData.parseResults.text, importLookup, builtinsScope, futureImports);
|
750
|
+
AnalyzerNodeInfo.setFileInfo(this._writableData.parseResults.parseTree, fileInfo);
|
719
751
|
const binder = new binder_1.Binder(fileInfo, configOptions.indexGenerationMode);
|
720
|
-
this.
|
721
|
-
binder.bindModule(this.
|
752
|
+
this._writableData.isBindingInProgress = true;
|
753
|
+
binder.bindModule(this._writableData.parseResults.parseTree);
|
722
754
|
// If we're in "test mode" (used for unit testing), run an additional
|
723
755
|
// "test walker" over the parse tree to validate its internal consistency.
|
724
756
|
if (configOptions.internalTestMode) {
|
725
757
|
const testWalker = new testWalker_1.TestWalker();
|
726
|
-
testWalker.walk(this.
|
758
|
+
testWalker.walk(this._writableData.parseResults.parseTree);
|
727
759
|
}
|
728
|
-
this.
|
729
|
-
const moduleScope = AnalyzerNodeInfo.getScope(this.
|
760
|
+
this._writableData.bindDiagnostics = fileInfo.diagnosticSink.fetchAndClear();
|
761
|
+
const moduleScope = AnalyzerNodeInfo.getScope(this._writableData.parseResults.parseTree);
|
730
762
|
(0, debug_1.assert)(moduleScope !== undefined, 'Module scope not returned by binder');
|
731
|
-
this.
|
763
|
+
this._writableData.moduleSymbolTable = moduleScope.symbolTable;
|
732
764
|
});
|
733
765
|
}
|
734
766
|
catch (e) {
|
@@ -738,36 +770,36 @@ class SourceFile {
|
|
738
770
|
this._console.error(localize_1.Localizer.Diagnostic.internalBindError().format({ file: this.getFilePath(), message }));
|
739
771
|
const diagSink = new diagnosticSink_1.DiagnosticSink();
|
740
772
|
diagSink.addError(localize_1.Localizer.Diagnostic.internalBindError().format({ file: this.getFilePath(), message }), (0, textRange_1.getEmptyRange)());
|
741
|
-
this.
|
773
|
+
this._writableData.bindDiagnostics = diagSink.fetchAndClear();
|
742
774
|
// Do not rethrow the exception, swallow it here. Callers are not
|
743
775
|
// prepared to handle an exception.
|
744
776
|
}
|
745
777
|
finally {
|
746
|
-
this.
|
778
|
+
this._writableData.isBindingInProgress = false;
|
747
779
|
}
|
748
780
|
// Prepare for the next stage of the analysis.
|
749
|
-
this.
|
750
|
-
this.
|
751
|
-
this.
|
752
|
-
this.
|
781
|
+
this._writableData.diagnosticVersion++;
|
782
|
+
this._writableData.isCheckingNeeded = true;
|
783
|
+
this._writableData.indexingNeeded = true;
|
784
|
+
this._writableData.isBindingNeeded = false;
|
753
785
|
});
|
754
786
|
}
|
755
787
|
check(importResolver, evaluator, sourceMapper, dependentFiles) {
|
756
788
|
(0, debug_1.assert)(!this.isParseRequired(), 'Check called before parsing');
|
757
789
|
(0, debug_1.assert)(!this.isBindingRequired(), 'Check called before binding');
|
758
|
-
(0, debug_1.assert)(!this.
|
790
|
+
(0, debug_1.assert)(!this._writableData.isBindingInProgress, 'Check called while binding in progress');
|
759
791
|
(0, debug_1.assert)(this.isCheckingRequired(), 'Check called unnecessarily');
|
760
|
-
(0, debug_1.assert)(this.
|
792
|
+
(0, debug_1.assert)(this._writableData.parseResults !== undefined, 'Parse results not available');
|
761
793
|
return this._logTracker.log(`checking: ${this._getPathForLogging(this._filePath)}`, () => {
|
762
794
|
try {
|
763
795
|
timing_1.timingStats.typeCheckerTime.timeOperation(() => {
|
764
796
|
const checkDuration = new timing_1.Duration();
|
765
|
-
const checker = new checker_1.Checker(importResolver, evaluator, this.
|
797
|
+
const checker = new checker_1.Checker(importResolver, evaluator, this._writableData.parseResults, sourceMapper, dependentFiles);
|
766
798
|
checker.check();
|
767
|
-
this.
|
768
|
-
const fileInfo = AnalyzerNodeInfo.getFileInfo(this.
|
769
|
-
this.
|
770
|
-
this.
|
799
|
+
this._writableData.isCheckingNeeded = false;
|
800
|
+
const fileInfo = AnalyzerNodeInfo.getFileInfo(this._writableData.parseResults.parseTree);
|
801
|
+
this._writableData.checkerDiagnostics = fileInfo.diagnosticSink.fetchAndClear();
|
802
|
+
this._writableData.checkTime = checkDuration.getDurationInMilliseconds();
|
771
803
|
});
|
772
804
|
}
|
773
805
|
catch (e) {
|
@@ -779,9 +811,9 @@ class SourceFile {
|
|
779
811
|
this._console.error(localize_1.Localizer.Diagnostic.internalTypeCheckingError().format({ file: this.getFilePath(), message }));
|
780
812
|
const diagSink = new diagnosticSink_1.DiagnosticSink();
|
781
813
|
diagSink.addError(localize_1.Localizer.Diagnostic.internalTypeCheckingError().format({ file: this.getFilePath(), message }), (0, textRange_1.getEmptyRange)());
|
782
|
-
this.
|
814
|
+
this._writableData.checkerDiagnostics = diagSink.fetchAndClear();
|
783
815
|
// Mark the file as complete so we don't get into an infinite loop.
|
784
|
-
this.
|
816
|
+
this._writableData.isCheckingNeeded = false;
|
785
817
|
}
|
786
818
|
throw e;
|
787
819
|
}
|
@@ -789,14 +821,26 @@ class SourceFile {
|
|
789
821
|
// Clear any circular dependencies associated with this file.
|
790
822
|
// These will be detected by the program module and associated
|
791
823
|
// with the source file right before it is finalized.
|
792
|
-
this.
|
793
|
-
this.
|
824
|
+
this._writableData.circularDependencies = [];
|
825
|
+
this._writableData.diagnosticVersion++;
|
794
826
|
}
|
795
827
|
});
|
796
828
|
}
|
797
829
|
test_enableIPythonMode(enable) {
|
798
830
|
this._ipythonMode = enable ? IPythonMode.CellDocs : IPythonMode.None;
|
799
831
|
}
|
832
|
+
_cachePreEditState() {
|
833
|
+
// If there's no document yet, this change doesn't count as a write yet.
|
834
|
+
if (this._writableData.clientDocumentContents !== undefined) {
|
835
|
+
// If this is our first write, then make a copy of the writable data.
|
836
|
+
if (this._isEditMode && !this._preEditData) {
|
837
|
+
// Copy over the writable data.
|
838
|
+
this._preEditData = this._writableData;
|
839
|
+
// Recreate all the writable data from scratch.
|
840
|
+
this._writableData = new WriteableData();
|
841
|
+
}
|
842
|
+
}
|
843
|
+
}
|
800
844
|
// Get all task list diagnostics for the current file and add them
|
801
845
|
// to the specified diagnostic list
|
802
846
|
_addTaskListDiagnostics(taskListTokens, diagList) {
|
@@ -806,10 +850,10 @@ class SourceFile {
|
|
806
850
|
return;
|
807
851
|
}
|
808
852
|
// if we have no tokens, we're done
|
809
|
-
if (!((_b = (_a = this.
|
853
|
+
if (!((_b = (_a = this._writableData.parseResults) === null || _a === void 0 ? void 0 : _a.tokenizerOutput) === null || _b === void 0 ? void 0 : _b.tokens)) {
|
810
854
|
return;
|
811
855
|
}
|
812
|
-
const tokenizerOutput = this.
|
856
|
+
const tokenizerOutput = this._writableData.parseResults.tokenizerOutput;
|
813
857
|
for (let i = 0; i < tokenizerOutput.tokens.count; i++) {
|
814
858
|
const token = tokenizerOutput.tokens.getItemAt(i);
|
815
859
|
// if there are no comments, skip this token
|
@@ -845,8 +889,8 @@ class SourceFile {
|
|
845
889
|
}
|
846
890
|
}
|
847
891
|
_buildFileInfo(configOptions, fileContents, importLookup, builtinsScope, futureImports) {
|
848
|
-
(0, debug_1.assert)(this.
|
849
|
-
const analysisDiagnostics = new diagnosticSink_1.TextRangeDiagnosticSink(this.
|
892
|
+
(0, debug_1.assert)(this._writableData.parseResults !== undefined, 'Parse results not available');
|
893
|
+
const analysisDiagnostics = new diagnosticSink_1.TextRangeDiagnosticSink(this._writableData.parseResults.tokenizerOutput.lines);
|
850
894
|
const fileInfo = {
|
851
895
|
importLookup,
|
852
896
|
futureImports,
|
@@ -855,8 +899,8 @@ class SourceFile {
|
|
855
899
|
executionEnvironment: configOptions.findExecEnvironment(this._filePath),
|
856
900
|
diagnosticRuleSet: this._diagnosticRuleSet,
|
857
901
|
fileContents,
|
858
|
-
lines: this.
|
859
|
-
typingSymbolAliases: this.
|
902
|
+
lines: this._writableData.parseResults.tokenizerOutput.lines,
|
903
|
+
typingSymbolAliases: this._writableData.parseResults.typingSymbolAliases,
|
860
904
|
definedConstants: configOptions.defineConstant,
|
861
905
|
filePath: this._filePath,
|
862
906
|
moduleName: this._moduleName,
|
@@ -871,11 +915,11 @@ class SourceFile {
|
|
871
915
|
return fileInfo;
|
872
916
|
}
|
873
917
|
_cleanParseTreeIfRequired() {
|
874
|
-
if (this.
|
875
|
-
if (this.
|
876
|
-
const cleanerWalker = new parseTreeCleaner_1.ParseTreeCleanerWalker(this.
|
918
|
+
if (this._writableData.parseResults) {
|
919
|
+
if (this._writableData.parseTreeNeedsCleaning) {
|
920
|
+
const cleanerWalker = new parseTreeCleaner_1.ParseTreeCleanerWalker(this._writableData.parseResults.parseTree);
|
877
921
|
cleanerWalker.clean();
|
878
|
-
this.
|
922
|
+
this._writableData.parseTreeNeedsCleaning = false;
|
879
923
|
}
|
880
924
|
}
|
881
925
|
}
|