@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.
- package/dist/analyzer/backgroundAnalysisProgram.d.ts +4 -1
- 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 +89 -6
- package/dist/analyzer/checker.js.map +1 -1
- package/dist/analyzer/constraintSolver.js +14 -15
- package/dist/analyzer/constraintSolver.js.map +1 -1
- package/dist/analyzer/constructors.d.ts +6 -0
- package/dist/analyzer/constructors.js +513 -0
- package/dist/analyzer/constructors.js.map +1 -0
- package/dist/analyzer/dataClasses.js +86 -2
- package/dist/analyzer/dataClasses.js.map +1 -1
- package/dist/analyzer/docStringConversion.js +1 -1
- package/dist/analyzer/docStringConversion.js.map +1 -1
- package/dist/analyzer/enums.js +62 -8
- package/dist/analyzer/enums.js.map +1 -1
- package/dist/analyzer/importResolver.js +47 -29
- package/dist/analyzer/importResolver.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 +3 -6
- 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 +11 -33
- package/dist/analyzer/program.js +73 -735
- package/dist/analyzer/program.js.map +1 -1
- package/dist/analyzer/protocols.js +1 -1
- package/dist/analyzer/protocols.js.map +1 -1
- package/dist/analyzer/service.d.ts +5 -21
- package/dist/analyzer/service.js +26 -33
- package/dist/analyzer/service.js.map +1 -1
- package/dist/analyzer/sourceFile.d.ts +9 -41
- package/dist/analyzer/sourceFile.js +219 -238
- 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/symbol.d.ts +3 -1
- package/dist/analyzer/symbol.js +5 -0
- package/dist/analyzer/symbol.js.map +1 -1
- package/dist/analyzer/typeEvaluator.js +460 -1425
- package/dist/analyzer/typeEvaluator.js.map +1 -1
- package/dist/analyzer/typeEvaluatorTypes.d.ts +42 -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/typePrinter.d.ts +3 -3
- package/dist/analyzer/typePrinter.js +247 -100
- package/dist/analyzer/typePrinter.js.map +1 -1
- package/dist/analyzer/typeUtils.d.ts +14 -7
- package/dist/analyzer/typeUtils.js +204 -49
- package/dist/analyzer/typeUtils.js.map +1 -1
- package/dist/analyzer/typeVarContext.d.ts +6 -7
- package/dist/analyzer/typeVarContext.js +21 -32
- 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 +7 -4
- package/dist/analyzer/types.js +20 -10
- package/dist/analyzer/types.js.map +1 -1
- package/dist/backgroundAnalysisBase.d.ts +1 -1
- package/dist/backgroundAnalysisBase.js +16 -0
- package/dist/backgroundAnalysisBase.js.map +1 -1
- package/dist/commands/dumpFileDebugInfoCommand.js +0 -1
- package/dist/commands/dumpFileDebugInfoCommand.js.map +1 -1
- package/dist/common/extensibility.d.ts +28 -4
- package/dist/common/extensibility.js.map +1 -1
- package/dist/common/logTracker.d.ts +2 -0
- package/dist/common/logTracker.js +8 -1
- package/dist/common/logTracker.js.map +1 -1
- package/dist/common/lspUtils.d.ts +4 -1
- package/dist/common/lspUtils.js +38 -1
- package/dist/common/lspUtils.js.map +1 -1
- package/dist/common/pathUtils.d.ts +11 -11
- package/dist/common/pathUtils.js.map +1 -1
- package/dist/common/pythonVersion.d.ts +2 -1
- package/dist/common/pythonVersion.js +1 -0
- package/dist/common/pythonVersion.js.map +1 -1
- package/dist/common/workspaceEditUtils.d.ts +8 -8
- package/dist/common/workspaceEditUtils.js +10 -10
- package/dist/common/workspaceEditUtils.js.map +1 -1
- package/dist/languageServerBase.d.ts +3 -7
- package/dist/languageServerBase.js +41 -73
- package/dist/languageServerBase.js.map +1 -1
- package/dist/languageService/autoImporter.d.ts +50 -51
- package/dist/languageService/autoImporter.js +125 -210
- package/dist/languageService/autoImporter.js.map +1 -1
- package/dist/languageService/callHierarchyProvider.d.ts +1 -1
- package/dist/languageService/callHierarchyProvider.js +11 -37
- package/dist/languageService/callHierarchyProvider.js.map +1 -1
- package/dist/languageService/completionProvider.d.ts +39 -81
- package/dist/languageService/completionProvider.js +572 -801
- 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 +47 -28
- package/dist/languageService/documentSymbolCollector.js.map +1 -1
- package/dist/languageService/documentSymbolProvider.d.ts +13 -35
- package/dist/languageService/documentSymbolProvider.js +52 -264
- package/dist/languageService/documentSymbolProvider.js.map +1 -1
- package/dist/languageService/hoverProvider.d.ts +5 -6
- package/dist/languageService/hoverProvider.js +40 -132
- package/dist/languageService/hoverProvider.js.map +1 -1
- package/dist/languageService/referencesProvider.d.ts +6 -11
- package/dist/languageService/referencesProvider.js +23 -17
- package/dist/languageService/referencesProvider.js.map +1 -1
- package/dist/languageService/renameProvider.d.ts +16 -0
- package/dist/languageService/renameProvider.js +139 -0
- package/dist/languageService/renameProvider.js.map +1 -0
- package/dist/languageService/symbolIndexer.d.ts +31 -0
- package/dist/languageService/symbolIndexer.js +105 -0
- package/dist/languageService/symbolIndexer.js.map +1 -0
- package/dist/languageService/tooltipUtils.d.ts +8 -1
- package/dist/languageService/tooltipUtils.js +102 -1
- package/dist/languageService/tooltipUtils.js.map +1 -1
- package/dist/languageService/workspaceSymbolProvider.d.ts +17 -0
- package/dist/languageService/workspaceSymbolProvider.js +133 -0
- package/dist/languageService/workspaceSymbolProvider.js.map +1 -0
- package/dist/localization/localize.d.ts +33 -15
- package/dist/localization/localize.js +13 -7
- package/dist/localization/localize.js.map +1 -1
- package/dist/localization/package.nls.en-us.json +14 -7
- package/dist/parser/parser.js +3 -0
- package/dist/parser/parser.js.map +1 -1
- package/dist/pyright.js +26 -4
- package/dist/pyright.js.map +1 -1
- package/dist/tests/chainedSourceFiles.test.js +15 -20
- package/dist/tests/chainedSourceFiles.test.js.map +1 -1
- package/dist/tests/checker.test.js +14 -0
- package/dist/tests/checker.test.js.map +1 -1
- package/dist/tests/completions.test.js +11 -236
- package/dist/tests/completions.test.js.map +1 -1
- package/dist/tests/docStringConversion.test.js +36 -2
- package/dist/tests/docStringConversion.test.js.map +1 -1
- package/dist/tests/documentSymbolCollector.test.js +3 -3
- package/dist/tests/documentSymbolCollector.test.js.map +1 -1
- package/dist/tests/fourslash/completions.override2.fourslash.js +1 -16
- package/dist/tests/fourslash/completions.override2.fourslash.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 +17 -11
- package/dist/tests/harness/fourslash/testState.js +39 -50
- package/dist/tests/harness/fourslash/testState.js.map +1 -1
- package/dist/tests/importResolver.test.js +81 -1
- package/dist/tests/importResolver.test.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 +13 -1
- package/dist/tests/typeEvaluator2.test.js.map +1 -1
- package/dist/tests/typeEvaluator3.test.js +5 -1
- package/dist/tests/typeEvaluator3.test.js.map +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 +25 -9
- package/dist/tests/typeEvaluator5.test.js.map +1 -1
- package/dist/tests/workspaceEditUtils.test.js +95 -6
- package/dist/tests/workspaceEditUtils.test.js.map +1 -1
- package/package.json +4 -4
- package/dist/languageService/importAdder.d.ts +0 -40
- package/dist/languageService/importAdder.js +0 -388
- package/dist/languageService/importAdder.js.map +0 -1
- 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/fourslash/completions.commitChars.fourslash.d.ts +0 -1
- package/dist/tests/fourslash/completions.commitChars.fourslash.js +0 -81
- package/dist/tests/fourslash/completions.commitChars.fourslash.js.map +0 -1
- package/dist/tests/importAdder.test.d.ts +0 -1
- package/dist/tests/importAdder.test.js +0 -1325
- package/dist/tests/importAdder.test.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
@@ -37,7 +37,6 @@ const docStringConversion_1 = require("../analyzer/docStringConversion");
|
|
37
37
|
const parameterUtils_1 = require("../analyzer/parameterUtils");
|
38
38
|
const ParseTreeUtils = __importStar(require("../analyzer/parseTreeUtils"));
|
39
39
|
const parseTreeUtils_1 = require("../analyzer/parseTreeUtils");
|
40
|
-
const pythonPathUtils_1 = require("../analyzer/pythonPathUtils");
|
41
40
|
const scopeUtils_1 = require("../analyzer/scopeUtils");
|
42
41
|
const sourceMapper_1 = require("../analyzer/sourceMapper");
|
43
42
|
const SymbolNameUtils = __importStar(require("../analyzer/symbolNameUtils"));
|
@@ -48,23 +47,19 @@ const typePrinter_1 = require("../analyzer/typePrinter");
|
|
48
47
|
const types_1 = require("../analyzer/types");
|
49
48
|
const typeUtils_1 = require("../analyzer/typeUtils");
|
50
49
|
const cancellationUtils_1 = require("../common/cancellationUtils");
|
51
|
-
const collectionUtils_1 = require("../common/collectionUtils");
|
52
50
|
const debug = __importStar(require("../common/debug"));
|
53
51
|
const debug_1 = require("../common/debug");
|
54
52
|
const lspUtils_1 = require("../common/lspUtils");
|
55
|
-
const pathUtils_1 = require("../common/pathUtils");
|
56
53
|
const positionUtils_1 = require("../common/positionUtils");
|
57
54
|
const pythonVersion_1 = require("../common/pythonVersion");
|
58
55
|
const StringUtils = __importStar(require("../common/stringUtils"));
|
59
56
|
const textRange_1 = require("../common/textRange");
|
60
57
|
const textRange_2 = require("../common/textRange");
|
61
|
-
const timing_1 = require("../common/timing");
|
62
58
|
const workspaceEditUtils_1 = require("../common/workspaceEditUtils");
|
63
59
|
const parseNodes_1 = require("../parser/parseNodes");
|
64
60
|
const autoImporter_1 = require("./autoImporter");
|
65
61
|
const completionProviderUtils_1 = require("./completionProviderUtils");
|
66
62
|
const documentSymbolCollector_1 = require("./documentSymbolCollector");
|
67
|
-
const importAdder_1 = require("./importAdder");
|
68
63
|
const tooltipUtils_1 = require("./tooltipUtils");
|
69
64
|
var Keywords;
|
70
65
|
(function (Keywords) {
|
@@ -158,31 +153,438 @@ const similarityLimit = 0.25;
|
|
158
153
|
// We'll remember this many completions in the MRU list.
|
159
154
|
const maxRecentCompletions = 128;
|
160
155
|
class CompletionProvider {
|
161
|
-
constructor(
|
156
|
+
constructor(program, _workspacePath, filePath, position, options, cancellationToken) {
|
157
|
+
this.program = program;
|
162
158
|
this._workspacePath = _workspacePath;
|
163
|
-
this.
|
164
|
-
this.
|
165
|
-
this.
|
166
|
-
this.
|
167
|
-
this._filePath = _filePath;
|
168
|
-
this._configOptions = _configOptions;
|
169
|
-
this._importLookup = _importLookup;
|
170
|
-
this._evaluator = _evaluator;
|
171
|
-
this._options = _options;
|
172
|
-
this._sourceMapper = _sourceMapper;
|
173
|
-
this._autoImportMaps = _autoImportMaps;
|
174
|
-
this._cancellationToken = _cancellationToken;
|
159
|
+
this.filePath = filePath;
|
160
|
+
this.position = position;
|
161
|
+
this.options = options;
|
162
|
+
this.cancellationToken = cancellationToken;
|
175
163
|
// Indicate whether invocation is inside of string literal.
|
176
164
|
this._insideStringLiteral = undefined;
|
177
|
-
this.
|
165
|
+
this.execEnv = this.configOptions.findExecEnvironment(this.filePath);
|
166
|
+
this.parseResults = this.program.getParseResults(this.filePath);
|
167
|
+
this.sourceMapper = this.program.getSourceMapper(this.filePath, this.cancellationToken, /* mapCompiled */ true);
|
178
168
|
}
|
179
|
-
|
169
|
+
getCompletions() {
|
170
|
+
if (!this.program.getSourceFileInfo(this.filePath)) {
|
171
|
+
return null;
|
172
|
+
}
|
173
|
+
const completionMap = this._getCompletions();
|
174
|
+
return vscode_languageserver_1.CompletionList.create(completionMap === null || completionMap === void 0 ? void 0 : completionMap.toArray());
|
175
|
+
}
|
176
|
+
// When the user selects a completion, this callback is invoked,
|
177
|
+
// allowing us to record what was selected. This allows us to
|
178
|
+
// build our MRU cache so we can better predict entries.
|
179
|
+
resolveCompletionItem(completionItem) {
|
180
|
+
(0, cancellationUtils_1.throwIfCancellationRequested)(this.cancellationToken);
|
181
|
+
const completionItemData = (0, lspUtils_1.fromLSPAny)(completionItem.data);
|
182
|
+
const label = completionItem.label;
|
183
|
+
let autoImportText = '';
|
184
|
+
if (completionItemData.autoImportText) {
|
185
|
+
autoImportText = completionItemData.autoImportText;
|
186
|
+
}
|
187
|
+
const curIndex = CompletionProvider._mostRecentCompletions.findIndex((item) => item.label === label && item.autoImportText === autoImportText);
|
188
|
+
if (curIndex > 0) {
|
189
|
+
// If there's an existing entry with the same name that's not at the
|
190
|
+
// beginning of the array, remove it.
|
191
|
+
CompletionProvider._mostRecentCompletions = CompletionProvider._mostRecentCompletions.splice(curIndex, 1);
|
192
|
+
}
|
193
|
+
if (curIndex !== 0) {
|
194
|
+
// Add to the start of the array.
|
195
|
+
CompletionProvider._mostRecentCompletions.unshift({ label, autoImportText });
|
196
|
+
}
|
197
|
+
if (CompletionProvider._mostRecentCompletions.length > maxRecentCompletions) {
|
198
|
+
// Prevent the MRU list from growing indefinitely.
|
199
|
+
CompletionProvider._mostRecentCompletions.pop();
|
200
|
+
}
|
201
|
+
if (!completionItemData.symbolLabel) {
|
202
|
+
return;
|
203
|
+
}
|
204
|
+
if (completionItemData.modulePath) {
|
205
|
+
const documentation = (0, typeDocStringUtils_1.getModuleDocStringFromPaths)([completionItemData.modulePath], this.sourceMapper);
|
206
|
+
if (!documentation) {
|
207
|
+
return;
|
208
|
+
}
|
209
|
+
if (this.options.format === vscode_languageserver_1.MarkupKind.Markdown) {
|
210
|
+
const markdownString = (0, docStringConversion_1.convertDocStringToMarkdown)(documentation);
|
211
|
+
completionItem.documentation = {
|
212
|
+
kind: vscode_languageserver_1.MarkupKind.Markdown,
|
213
|
+
value: markdownString,
|
214
|
+
};
|
215
|
+
}
|
216
|
+
else if (this.options.format === vscode_languageserver_1.MarkupKind.PlainText) {
|
217
|
+
const plainTextString = (0, docStringConversion_1.convertDocStringToPlainText)(documentation);
|
218
|
+
completionItem.documentation = {
|
219
|
+
kind: vscode_languageserver_1.MarkupKind.PlainText,
|
220
|
+
value: plainTextString,
|
221
|
+
};
|
222
|
+
}
|
223
|
+
return;
|
224
|
+
}
|
225
|
+
this._itemToResolve = completionItem;
|
226
|
+
if (!completionItemData.autoImportText) {
|
227
|
+
// Rerun the completion lookup. It will fill in additional information
|
228
|
+
// about the item to be resolved. We'll ignore the rest of the returned
|
229
|
+
// list. This is a bit wasteful, but all of that information should be
|
230
|
+
// cached, so it's not as bad as it might seem.
|
231
|
+
this.getCompletions();
|
232
|
+
}
|
233
|
+
else if (!completionItem.additionalTextEdits) {
|
234
|
+
const completionMap = new CompletionMap();
|
235
|
+
this.addAutoImportCompletions(completionItemData.symbolLabel,
|
236
|
+
/* similarityLimit */ 1,
|
237
|
+
/* lazyEdit */ false, completionMap);
|
238
|
+
}
|
239
|
+
}
|
240
|
+
get evaluator() {
|
241
|
+
return this.program.evaluator;
|
242
|
+
}
|
243
|
+
get importResolver() {
|
244
|
+
return this.program.importResolver;
|
245
|
+
}
|
246
|
+
get configOptions() {
|
247
|
+
return this.program.configOptions;
|
248
|
+
}
|
249
|
+
isSimpleDefault(node) {
|
250
|
+
switch (node.nodeType) {
|
251
|
+
case 40 /* Number */:
|
252
|
+
case 11 /* Constant */:
|
253
|
+
case 35 /* MemberAccess */:
|
254
|
+
return true;
|
255
|
+
case 49 /* String */:
|
256
|
+
return (node.token.flags & 64 /* Format */) === 0;
|
257
|
+
case 48 /* StringList */:
|
258
|
+
return node.strings.every(this.isSimpleDefault);
|
259
|
+
case 55 /* UnaryOperation */:
|
260
|
+
return this.isSimpleDefault(node.expression);
|
261
|
+
case 7 /* BinaryOperation */:
|
262
|
+
return this.isSimpleDefault(node.leftExpression) && this.isSimpleDefault(node.rightExpression);
|
263
|
+
default:
|
264
|
+
return false;
|
265
|
+
}
|
266
|
+
}
|
267
|
+
getMethodOverrideCompletions(priorWord, partialName, decorators) {
|
180
268
|
var _a, _b;
|
181
|
-
const
|
269
|
+
const enclosingClass = ParseTreeUtils.getEnclosingClass(partialName, /* stopAtFunction */ true);
|
270
|
+
if (!enclosingClass) {
|
271
|
+
return undefined;
|
272
|
+
}
|
273
|
+
const classResults = this.evaluator.getTypeOfClass(enclosingClass);
|
274
|
+
if (!classResults) {
|
275
|
+
return undefined;
|
276
|
+
}
|
277
|
+
const symbolTable = new Map();
|
278
|
+
for (let i = 1; i < classResults.classType.details.mro.length; i++) {
|
279
|
+
const mroClass = classResults.classType.details.mro[i];
|
280
|
+
if ((0, types_1.isInstantiableClass)(mroClass)) {
|
281
|
+
(0, typeUtils_1.getMembersForClass)(mroClass, symbolTable, /* includeInstanceVars */ false);
|
282
|
+
}
|
283
|
+
}
|
284
|
+
const staticmethod = (_a = decorators === null || decorators === void 0 ? void 0 : decorators.some((d) => this.checkDecorator(d, 'staticmethod'))) !== null && _a !== void 0 ? _a : false;
|
285
|
+
const classmethod = (_b = decorators === null || decorators === void 0 ? void 0 : decorators.some((d) => this.checkDecorator(d, 'classmethod'))) !== null && _b !== void 0 ? _b : false;
|
286
|
+
const completionMap = new CompletionMap();
|
287
|
+
symbolTable.forEach((symbol, name) => {
|
288
|
+
var _a;
|
289
|
+
let decl = (0, symbolUtils_1.getLastTypedDeclaredForSymbol)(symbol);
|
290
|
+
if (decl && decl.type === 5 /* Function */) {
|
291
|
+
if (StringUtils.isPatternInSymbol(partialName.value, name)) {
|
292
|
+
const declaredType = (_a = this.evaluator.getTypeForDeclaration(decl)) === null || _a === void 0 ? void 0 : _a.type;
|
293
|
+
if (!declaredType) {
|
294
|
+
return;
|
295
|
+
}
|
296
|
+
let isProperty = (0, types_1.isClassInstance)(declaredType) && types_1.ClassType.isPropertyClass(declaredType);
|
297
|
+
if (SymbolNameUtils.isDunderName(name)) {
|
298
|
+
// Don't offer suggestions for built-in properties like "__class__", etc.
|
299
|
+
isProperty = false;
|
300
|
+
}
|
301
|
+
if (!(0, types_1.isFunction)(declaredType) && !isProperty) {
|
302
|
+
return;
|
303
|
+
}
|
304
|
+
if (isProperty) {
|
305
|
+
// For properties, we should override the "getter", which is typically
|
306
|
+
// the first declaration.
|
307
|
+
const typedDecls = symbol.getTypedDeclarations();
|
308
|
+
if (typedDecls.length > 0 && typedDecls[0].type === 5 /* Function */) {
|
309
|
+
decl = typedDecls[0];
|
310
|
+
}
|
311
|
+
}
|
312
|
+
const isDeclaredStaticMethod = (0, types_1.isFunction)(declaredType) && types_1.FunctionType.isStaticMethod(declaredType);
|
313
|
+
// Special-case the "__init__subclass__" method because it's an implicit
|
314
|
+
// classmethod that the type evaluator flags as a real classmethod.
|
315
|
+
const isDeclaredClassMethod = (0, types_1.isFunction)(declaredType) &&
|
316
|
+
types_1.FunctionType.isClassMethod(declaredType) &&
|
317
|
+
name !== '__init_subclass__';
|
318
|
+
if (staticmethod !== isDeclaredStaticMethod || classmethod !== isDeclaredClassMethod) {
|
319
|
+
return;
|
320
|
+
}
|
321
|
+
const methodSignature = this._printMethodSignature(classResults.classType, decl);
|
322
|
+
let text;
|
323
|
+
if ((0, sourceMapper_1.isStubFile)(this.filePath)) {
|
324
|
+
text = `${methodSignature}: ...`;
|
325
|
+
}
|
326
|
+
else {
|
327
|
+
const methodBody = this.printOverriddenMethodBody(classResults.classType, isDeclaredStaticMethod, isProperty, decl);
|
328
|
+
text = `${methodSignature}:\n${methodBody}`;
|
329
|
+
}
|
330
|
+
const textEdit = this.createReplaceEdits(priorWord, partialName, text);
|
331
|
+
this.addSymbol(name, symbol, partialName.value, completionMap, {
|
332
|
+
// method signature already contains ()
|
333
|
+
funcParensDisabled: true,
|
334
|
+
edits: {
|
335
|
+
format: this.options.snippet ? vscode_languageserver_1.InsertTextFormat.Snippet : undefined,
|
336
|
+
textEdit,
|
337
|
+
},
|
338
|
+
});
|
339
|
+
}
|
340
|
+
}
|
341
|
+
});
|
342
|
+
return completionMap;
|
343
|
+
}
|
344
|
+
printOverriddenMethodBody(classType, isStaticMethod, isProperty, decl) {
|
345
|
+
let sb = this.parseResults.tokenizerOutput.predominantTabSequence;
|
346
|
+
if (classType.details.baseClasses.length === 1 &&
|
347
|
+
(0, types_1.isClass)(classType.details.baseClasses[0]) &&
|
348
|
+
classType.details.baseClasses[0].details.fullName === 'builtins.object') {
|
349
|
+
sb += this.options.snippet ? '${0:pass}' : 'pass';
|
350
|
+
return sb;
|
351
|
+
}
|
352
|
+
if (decl.node.parameters.length === 0) {
|
353
|
+
sb += this.options.snippet ? '${0:pass}' : 'pass';
|
354
|
+
return sb;
|
355
|
+
}
|
356
|
+
const parameters = getParameters(isStaticMethod ? decl.node.parameters : decl.node.parameters.slice(1));
|
357
|
+
if (decl.node.name.value !== '__init__') {
|
358
|
+
sb += 'return ';
|
359
|
+
}
|
360
|
+
if (decl.node.isAsync) {
|
361
|
+
sb += 'await ';
|
362
|
+
}
|
363
|
+
if (isProperty) {
|
364
|
+
return sb + `super().${decl.node.name.value}`;
|
365
|
+
}
|
366
|
+
return sb + `super().${decl.node.name.value}(${parameters.map(convertToString).join(', ')})`;
|
367
|
+
function getParameters(parameters) {
|
368
|
+
const results = [];
|
369
|
+
let sawKeywordOnlySeparator = false;
|
370
|
+
for (const parameter of parameters) {
|
371
|
+
if (parameter.name) {
|
372
|
+
results.push([
|
373
|
+
parameter,
|
374
|
+
parameter.category === 0 /* Simple */ && !!parameter.name && sawKeywordOnlySeparator,
|
375
|
+
]);
|
376
|
+
}
|
377
|
+
// All simple parameters after a `*` or `*args` parameter
|
378
|
+
// are considered keyword only.
|
379
|
+
if (parameter.category === 1 /* VarArgList */) {
|
380
|
+
sawKeywordOnlySeparator = true;
|
381
|
+
}
|
382
|
+
}
|
383
|
+
return results;
|
384
|
+
}
|
385
|
+
function convertToString(parameter) {
|
386
|
+
var _a;
|
387
|
+
const name = (_a = parameter[0].name) === null || _a === void 0 ? void 0 : _a.value;
|
388
|
+
if (parameter[0].category === 1 /* VarArgList */) {
|
389
|
+
return `*${name}`;
|
390
|
+
}
|
391
|
+
if (parameter[0].category === 2 /* VarArgDictionary */) {
|
392
|
+
return `**${name}`;
|
393
|
+
}
|
394
|
+
return parameter[1] ? `${name}=${name}` : name;
|
395
|
+
}
|
396
|
+
}
|
397
|
+
createReplaceEdits(priorWord, node, text) {
|
398
|
+
const replaceOrInsertEndChar = (node === null || node === void 0 ? void 0 : node.nodeType) === 38 /* Name */
|
399
|
+
? this.position.character - priorWord.length + node.value.length
|
400
|
+
: this.position.character;
|
401
|
+
const range = {
|
402
|
+
start: { line: this.position.line, character: this.position.character - priorWord.length },
|
403
|
+
end: { line: this.position.line, character: replaceOrInsertEndChar },
|
404
|
+
};
|
405
|
+
return vscode_languageserver_1.TextEdit.replace(range, text);
|
406
|
+
}
|
407
|
+
addSymbol(name, symbol, priorWord, completionMap, detail) {
|
408
|
+
var _a, _b, _c, _d;
|
409
|
+
let primaryDecl = (0, symbolUtils_1.getLastTypedDeclaredForSymbol)(symbol);
|
410
|
+
if (!primaryDecl) {
|
411
|
+
const declarations = symbol.getDeclarations();
|
412
|
+
if (declarations.length > 0) {
|
413
|
+
primaryDecl = declarations[declarations.length - 1];
|
414
|
+
}
|
415
|
+
}
|
416
|
+
primaryDecl = primaryDecl
|
417
|
+
? (_a = this.evaluator.resolveAliasDeclaration(primaryDecl, /* resolveLocalNames */ true)) !== null && _a !== void 0 ? _a : primaryDecl
|
418
|
+
: undefined;
|
419
|
+
const autoImportText = detail.autoImportSource
|
420
|
+
? this._getAutoImportText(name, detail.autoImportSource, detail.autoImportAlias)
|
421
|
+
: undefined;
|
422
|
+
// Are we resolving a completion item? If so, see if this symbol
|
423
|
+
// is the one that we're trying to match.
|
424
|
+
if (this._itemToResolve) {
|
425
|
+
const completionItemData = (0, lspUtils_1.fromLSPAny)(this._itemToResolve.data);
|
426
|
+
if (completionItemData.symbolLabel !== name) {
|
427
|
+
// It's not what we are looking for.
|
428
|
+
return;
|
429
|
+
}
|
430
|
+
if (completionItemData.autoImportText) {
|
431
|
+
if (completionItemData.autoImportText === (autoImportText === null || autoImportText === void 0 ? void 0 : autoImportText.importText) &&
|
432
|
+
((_b = detail.edits) === null || _b === void 0 ? void 0 : _b.additionalTextEdits)) {
|
433
|
+
this._itemToResolve.additionalTextEdits = (0, workspaceEditUtils_1.convertToTextEdits)(detail.edits.additionalTextEdits);
|
434
|
+
}
|
435
|
+
return;
|
436
|
+
}
|
437
|
+
// This call can be expensive to perform on every completion item
|
438
|
+
// that we return, so we do it lazily in the "resolve" callback.
|
439
|
+
const type = this.evaluator.getEffectiveTypeOfSymbol(symbol);
|
440
|
+
if (!type) {
|
441
|
+
// Can't resolve. so bail out.
|
442
|
+
return;
|
443
|
+
}
|
444
|
+
const typeDetail = (0, completionProviderUtils_1.getTypeDetail)(this.evaluator, primaryDecl, type, name, detail, this.configOptions.functionSignatureDisplay);
|
445
|
+
const documentation = (0, tooltipUtils_1.getDocumentationPartsForTypeAndDecl)(this.sourceMapper, type, primaryDecl, this.evaluator, {
|
446
|
+
name,
|
447
|
+
symbol,
|
448
|
+
boundObjectOrClass: detail.boundObjectOrClass,
|
449
|
+
});
|
450
|
+
if (this.options.format === vscode_languageserver_1.MarkupKind.Markdown || this.options.format === vscode_languageserver_1.MarkupKind.PlainText) {
|
451
|
+
this._itemToResolve.documentation = (0, completionProviderUtils_1.getCompletionItemDocumentation)(typeDetail, documentation, this.options.format);
|
452
|
+
}
|
453
|
+
else {
|
454
|
+
(0, debug_1.fail)(`Unsupported markup type: ${this.options.format}`);
|
455
|
+
}
|
456
|
+
// Bail out. We don't need to add items to completion.
|
457
|
+
return;
|
458
|
+
}
|
459
|
+
if (primaryDecl) {
|
460
|
+
let itemKind = this._convertDeclarationTypeToItemKind(primaryDecl);
|
461
|
+
// Handle enum members specially. Enum members normally look like
|
462
|
+
// variables, but the are declared using assignment expressions
|
463
|
+
// within an enum class.
|
464
|
+
if (primaryDecl.type === 1 /* Variable */ &&
|
465
|
+
detail.boundObjectOrClass &&
|
466
|
+
(0, types_1.isInstantiableClass)(detail.boundObjectOrClass) &&
|
467
|
+
types_1.ClassType.isEnumClass(detail.boundObjectOrClass) &&
|
468
|
+
((_c = primaryDecl.node.parent) === null || _c === void 0 ? void 0 : _c.nodeType) === 3 /* Assignment */) {
|
469
|
+
itemKind = vscode_languageserver_1.CompletionItemKind.EnumMember;
|
470
|
+
}
|
471
|
+
this._addNameToCompletions((_d = detail.autoImportAlias) !== null && _d !== void 0 ? _d : name, itemKind, priorWord, completionMap, {
|
472
|
+
autoImportText,
|
473
|
+
extraCommitChars: detail.extraCommitChars,
|
474
|
+
funcParensDisabled: detail.funcParensDisabled,
|
475
|
+
edits: detail.edits,
|
476
|
+
});
|
477
|
+
}
|
478
|
+
else {
|
479
|
+
// Does the symbol have no declaration but instead has a synthesized type?
|
480
|
+
const synthesizedType = symbol.getSynthesizedType();
|
481
|
+
if (synthesizedType) {
|
482
|
+
const itemKind = this._convertTypeToItemKind(synthesizedType);
|
483
|
+
this._addNameToCompletions(name, itemKind, priorWord, completionMap, {
|
484
|
+
extraCommitChars: detail.extraCommitChars,
|
485
|
+
funcParensDisabled: detail.funcParensDisabled,
|
486
|
+
edits: detail.edits,
|
487
|
+
});
|
488
|
+
}
|
489
|
+
}
|
490
|
+
}
|
491
|
+
getMemberAccessCompletions(leftExprNode, priorWord) {
|
492
|
+
const symbolTable = new Map();
|
493
|
+
const completionMap = new CompletionMap();
|
494
|
+
let leftType = this.evaluator.getType(leftExprNode);
|
495
|
+
if (!leftType) {
|
496
|
+
return completionMap;
|
497
|
+
}
|
498
|
+
leftType = this.evaluator.makeTopLevelTypeVarsConcrete(leftType);
|
499
|
+
// If this is an unknown type with a "possible type" associated with
|
500
|
+
// it, use the possible type.
|
501
|
+
if ((0, types_1.isUnknown)(leftType) && leftType.possibleType) {
|
502
|
+
leftType = this.evaluator.makeTopLevelTypeVarsConcrete(leftType.possibleType);
|
503
|
+
}
|
504
|
+
(0, typeUtils_1.doForEachSubtype)(leftType, (subtype) => {
|
505
|
+
subtype = this.evaluator.makeTopLevelTypeVarsConcrete(subtype);
|
506
|
+
if ((0, types_1.isClass)(subtype)) {
|
507
|
+
(0, typeUtils_1.getMembersForClass)(subtype, symbolTable, /* includeInstanceVars */ types_1.TypeBase.isInstance(subtype));
|
508
|
+
}
|
509
|
+
else if ((0, types_1.isModule)(subtype)) {
|
510
|
+
(0, typeUtils_1.getMembersForModule)(subtype, symbolTable);
|
511
|
+
}
|
512
|
+
else if ((0, types_1.isFunction)(subtype) || (0, types_1.isOverloadedFunction)(subtype)) {
|
513
|
+
const functionClass = this.evaluator.getBuiltInType(leftExprNode, 'function');
|
514
|
+
if (functionClass && (0, types_1.isInstantiableClass)(functionClass)) {
|
515
|
+
(0, typeUtils_1.getMembersForClass)(functionClass, symbolTable, /* includeInstanceVars */ true);
|
516
|
+
}
|
517
|
+
}
|
518
|
+
else if ((0, types_1.isNoneInstance)(subtype)) {
|
519
|
+
const objectClass = this.evaluator.getBuiltInType(leftExprNode, 'object');
|
520
|
+
if (objectClass && (0, types_1.isInstantiableClass)(objectClass)) {
|
521
|
+
(0, typeUtils_1.getMembersForClass)(objectClass, symbolTable, types_1.TypeBase.isInstance(subtype));
|
522
|
+
}
|
523
|
+
}
|
524
|
+
this._addSymbolsForSymbolTable(symbolTable, () => true, priorWord, leftExprNode,
|
525
|
+
/* isInImport */ false, (0, types_1.isClass)(subtype) ? subtype : undefined, completionMap);
|
526
|
+
});
|
527
|
+
return completionMap;
|
528
|
+
}
|
529
|
+
addAutoImportCompletions(priorWord, similarityLimit, lazyEdit, completionMap) {
|
530
|
+
if (!this.configOptions.autoImportCompletions) {
|
531
|
+
// If auto import on the server is turned off or this particular invocation
|
532
|
+
// is turned off (ex, notebook), don't do any thing.
|
533
|
+
return;
|
534
|
+
}
|
535
|
+
const currentFile = this.program.getSourceFileInfo(this.filePath);
|
536
|
+
const moduleSymbolMap = (0, autoImporter_1.buildModuleSymbolsMap)(this.program.getSourceFileInfoList().filter((s) => s !== currentFile));
|
537
|
+
const autoImporter = new autoImporter_1.AutoImporter(this.execEnv, this.importResolver, this.parseResults, this.position, completionMap, moduleSymbolMap, {
|
538
|
+
lazyEdit,
|
539
|
+
});
|
540
|
+
const results = [];
|
541
|
+
results.push(...autoImporter.getAutoImportCandidates(priorWord, similarityLimit,
|
542
|
+
/* abbrFromUsers */ undefined, this.cancellationToken));
|
543
|
+
this.addImportResults(results, priorWord, completionMap);
|
544
|
+
}
|
545
|
+
addImportResults(results, priorWord, completionMap) {
|
546
|
+
var _a, _b;
|
547
|
+
for (const result of results) {
|
548
|
+
if (result.symbol) {
|
549
|
+
this.addSymbol(result.name, result.symbol, priorWord, completionMap, {
|
550
|
+
extraCommitChars: true,
|
551
|
+
autoImportSource: result.source,
|
552
|
+
autoImportAlias: result.alias,
|
553
|
+
edits: {
|
554
|
+
textEdit: this.createReplaceEdits(priorWord, /* node */ undefined, result.insertionText),
|
555
|
+
additionalTextEdits: result.edits,
|
556
|
+
},
|
557
|
+
});
|
558
|
+
}
|
559
|
+
else {
|
560
|
+
this._addNameToCompletions((_a = result.alias) !== null && _a !== void 0 ? _a : result.name, (_b = result.kind) !== null && _b !== void 0 ? _b : vscode_languageserver_1.CompletionItemKind.Module, priorWord, completionMap, {
|
561
|
+
extraCommitChars: true,
|
562
|
+
autoImportText: this._getAutoImportText(result.name, result.source, result.alias),
|
563
|
+
edits: {
|
564
|
+
textEdit: this.createReplaceEdits(priorWord, /* node */ undefined, result.insertionText),
|
565
|
+
additionalTextEdits: result.edits,
|
566
|
+
},
|
567
|
+
});
|
568
|
+
}
|
569
|
+
}
|
570
|
+
}
|
571
|
+
checkDecorator(node, value) {
|
572
|
+
return node.expression.nodeType === 38 /* Name */ && node.expression.value === value;
|
573
|
+
}
|
574
|
+
addExtraCommitChar(item) {
|
575
|
+
// extra commit char is not supported.
|
576
|
+
}
|
577
|
+
get _fileContents() {
|
578
|
+
var _a, _b;
|
579
|
+
return (_b = (_a = this.parseResults) === null || _a === void 0 ? void 0 : _a.text) !== null && _b !== void 0 ? _b : '';
|
580
|
+
}
|
581
|
+
_getCompletions() {
|
582
|
+
var _a, _b;
|
583
|
+
const offset = (0, positionUtils_1.convertPositionToOffset)(this.position, this.parseResults.tokenizerOutput.lines);
|
182
584
|
if (offset === undefined) {
|
183
585
|
return undefined;
|
184
586
|
}
|
185
|
-
const token = ParseTreeUtils.getTokenOverlapping(this.
|
587
|
+
const token = ParseTreeUtils.getTokenOverlapping(this.parseResults.tokenizerOutput.tokens, offset);
|
186
588
|
if ((token === null || token === void 0 ? void 0 : token.type) === 5 /* String */) {
|
187
589
|
const stringToken = token;
|
188
590
|
this._insideStringLiteral = textRange_2.TextRange.contains(stringToken, offset)
|
@@ -191,7 +593,7 @@ class CompletionProvider {
|
|
191
593
|
? stringToken
|
192
594
|
: undefined;
|
193
595
|
}
|
194
|
-
let node = ParseTreeUtils.findNodeByOffset(this.
|
596
|
+
let node = ParseTreeUtils.findNodeByOffset(this.parseResults.parseTree, offset);
|
195
597
|
// See if we can get to a "better" node by backing up a few columns.
|
196
598
|
// A "better" node is defined as one that's deeper than the current
|
197
599
|
// node.
|
@@ -210,7 +612,7 @@ class CompletionProvider {
|
|
210
612
|
if (curChar === ',') {
|
211
613
|
sawComma = true;
|
212
614
|
}
|
213
|
-
const curNode = ParseTreeUtils.findNodeByOffset(this.
|
615
|
+
const curNode = ParseTreeUtils.findNodeByOffset(this.parseResults.parseTree, curOffset);
|
214
616
|
if (curNode && curNode !== initialNode) {
|
215
617
|
if (ParseTreeUtils.getNodeDepth(curNode) > initialDepth) {
|
216
618
|
node = curNode;
|
@@ -228,10 +630,10 @@ class CompletionProvider {
|
|
228
630
|
return undefined;
|
229
631
|
}
|
230
632
|
// Get the text on that line prior to the insertion point.
|
231
|
-
const lineTextRange = this.
|
633
|
+
const lineTextRange = this.parseResults.tokenizerOutput.lines.getItemAt(this.position.line);
|
232
634
|
const textOnLine = this._fileContents.substr(lineTextRange.start, lineTextRange.length);
|
233
|
-
const priorText = textOnLine.substr(0, this.
|
234
|
-
const postText = textOnLine.substr(this.
|
635
|
+
const priorText = textOnLine.substr(0, this.position.character);
|
636
|
+
const postText = textOnLine.substr(this.position.character);
|
235
637
|
const priorWordIndex = priorText.search(/\w+$/);
|
236
638
|
const priorWord = priorWordIndex >= 0 ? priorText.substr(priorWordIndex) : '';
|
237
639
|
// Don't offer completions if we're within a comment.
|
@@ -251,7 +653,7 @@ class CompletionProvider {
|
|
251
653
|
// that of its ancestors.
|
252
654
|
let curNode = errorNode || node;
|
253
655
|
while (true) {
|
254
|
-
(0, cancellationUtils_1.throwIfCancellationRequested)(this.
|
656
|
+
(0, cancellationUtils_1.throwIfCancellationRequested)(this.cancellationToken);
|
255
657
|
if (curNode.nodeType === 49 /* String */) {
|
256
658
|
return this._getLiteralCompletions(curNode, offset, priorWord, priorText, postText);
|
257
659
|
}
|
@@ -265,13 +667,13 @@ class CompletionProvider {
|
|
265
667
|
return this._getExpressionErrorCompletions(curNode, offset, priorWord, priorText, postText);
|
266
668
|
}
|
267
669
|
if (curNode.nodeType === 35 /* MemberAccess */) {
|
268
|
-
return this.
|
670
|
+
return this.getMemberAccessCompletions(curNode.leftExpression, priorWord);
|
269
671
|
}
|
270
672
|
if (curNode.nodeType === 15 /* Dictionary */) {
|
271
673
|
const completionMap = new CompletionMap();
|
272
674
|
if (this._tryAddTypedDictKeysFromDictionary(curNode,
|
273
675
|
/* stringNode */ undefined, priorWord, priorText, postText, completionMap)) {
|
274
|
-
return
|
676
|
+
return completionMap;
|
275
677
|
}
|
276
678
|
}
|
277
679
|
const dictionaryEntry = ParseTreeUtils.getFirstAncestorOrSelfOfKind(curNode, 17 /* DictionaryKeyEntry */);
|
@@ -282,7 +684,7 @@ class CompletionProvider {
|
|
282
684
|
const completionMap = new CompletionMap();
|
283
685
|
if (this._tryAddTypedDictKeysFromDictionary(dictionaryNode,
|
284
686
|
/* stringNode */ undefined, priorWord, priorText, postText, completionMap)) {
|
285
|
-
return
|
687
|
+
return completionMap;
|
286
688
|
}
|
287
689
|
}
|
288
690
|
}
|
@@ -296,7 +698,7 @@ class CompletionProvider {
|
|
296
698
|
return result;
|
297
699
|
}
|
298
700
|
}
|
299
|
-
if (curNode.nodeType === 31 /* List */ && this.
|
701
|
+
if (curNode.nodeType === 31 /* List */ && this.options.triggerCharacter === '[') {
|
300
702
|
// If this is an empty list, don't start putting completions up yet.
|
301
703
|
return undefined;
|
302
704
|
}
|
@@ -343,72 +745,7 @@ class CompletionProvider {
|
|
343
745
|
}
|
344
746
|
return undefined;
|
345
747
|
}
|
346
|
-
//
|
347
|
-
// allowing us to record what was selected. This allows us to
|
348
|
-
// build our MRU cache so we can better predict entries.
|
349
|
-
resolveCompletionItem(completionItem) {
|
350
|
-
(0, cancellationUtils_1.throwIfCancellationRequested)(this._cancellationToken);
|
351
|
-
const completionItemData = (0, lspUtils_1.fromLSPAny)(completionItem.data);
|
352
|
-
const label = completionItem.label;
|
353
|
-
let autoImportText = '';
|
354
|
-
if (completionItemData.autoImportText) {
|
355
|
-
autoImportText = completionItemData.autoImportText;
|
356
|
-
}
|
357
|
-
const curIndex = CompletionProvider._mostRecentCompletions.findIndex((item) => item.label === label && item.autoImportText === autoImportText);
|
358
|
-
if (curIndex > 0) {
|
359
|
-
// If there's an existing entry with the same name that's not at the
|
360
|
-
// beginning of the array, remove it.
|
361
|
-
CompletionProvider._mostRecentCompletions = CompletionProvider._mostRecentCompletions.splice(curIndex, 1);
|
362
|
-
}
|
363
|
-
if (curIndex !== 0) {
|
364
|
-
// Add to the start of the array.
|
365
|
-
CompletionProvider._mostRecentCompletions.unshift({ label, autoImportText });
|
366
|
-
}
|
367
|
-
if (CompletionProvider._mostRecentCompletions.length > maxRecentCompletions) {
|
368
|
-
// Prevent the MRU list from growing indefinitely.
|
369
|
-
CompletionProvider._mostRecentCompletions.pop();
|
370
|
-
}
|
371
|
-
if (!completionItemData.symbolLabel) {
|
372
|
-
return;
|
373
|
-
}
|
374
|
-
if (completionItemData.modulePath) {
|
375
|
-
const documentation = (0, typeDocStringUtils_1.getModuleDocStringFromPaths)([completionItemData.modulePath], this._sourceMapper);
|
376
|
-
if (!documentation) {
|
377
|
-
return;
|
378
|
-
}
|
379
|
-
if (this._options.format === vscode_languageserver_1.MarkupKind.Markdown) {
|
380
|
-
const markdownString = (0, docStringConversion_1.convertDocStringToMarkdown)(documentation);
|
381
|
-
completionItem.documentation = {
|
382
|
-
kind: vscode_languageserver_1.MarkupKind.Markdown,
|
383
|
-
value: markdownString,
|
384
|
-
};
|
385
|
-
}
|
386
|
-
else if (this._options.format === vscode_languageserver_1.MarkupKind.PlainText) {
|
387
|
-
const plainTextString = (0, docStringConversion_1.convertDocStringToPlainText)(documentation);
|
388
|
-
completionItem.documentation = {
|
389
|
-
kind: vscode_languageserver_1.MarkupKind.PlainText,
|
390
|
-
value: plainTextString,
|
391
|
-
};
|
392
|
-
}
|
393
|
-
return;
|
394
|
-
}
|
395
|
-
this._itemToResolve = completionItem;
|
396
|
-
if (!completionItemData.autoImportText) {
|
397
|
-
// Rerun the completion lookup. It will fill in additional information
|
398
|
-
// about the item to be resolved. We'll ignore the rest of the returned
|
399
|
-
// list. This is a bit wasteful, but all of that information should be
|
400
|
-
// cached, so it's not as bad as it might seem.
|
401
|
-
this.getCompletionsForPosition();
|
402
|
-
}
|
403
|
-
else if (!completionItem.additionalTextEdits) {
|
404
|
-
const completionMap = new CompletionMap();
|
405
|
-
const completionResults = { completionMap };
|
406
|
-
this._addAutoImportCompletions(completionItemData.symbolLabel,
|
407
|
-
/* similarityLimit */ 1,
|
408
|
-
/* lazyEdit */ false, completionResults);
|
409
|
-
}
|
410
|
-
}
|
411
|
-
// This method will return false if it wants
|
748
|
+
// This method will return false if it wants1
|
412
749
|
// caller to walk up the tree. it will return
|
413
750
|
// CompletionResults or undefined if it wants caller
|
414
751
|
// to return.
|
@@ -452,7 +789,7 @@ class CompletionProvider {
|
|
452
789
|
return false;
|
453
790
|
}
|
454
791
|
if (curNode.parent.nodeType === 35 /* MemberAccess */ && curNode === curNode.parent.memberName) {
|
455
|
-
return this.
|
792
|
+
return this.getMemberAccessCompletions(curNode.parent.leftExpression, priorWord);
|
456
793
|
}
|
457
794
|
if (curNode.parent.nodeType === 25 /* Except */ && curNode === curNode.parent.name) {
|
458
795
|
return undefined;
|
@@ -486,15 +823,15 @@ class CompletionProvider {
|
|
486
823
|
if (leftNode !== curNode || priorWord.length === 0) {
|
487
824
|
return false;
|
488
825
|
}
|
489
|
-
const decls = this.
|
826
|
+
const decls = this.evaluator.getDeclarationsForNameNode(curNode);
|
490
827
|
if ((decls === null || decls === void 0 ? void 0 : decls.length) !== 1 || !(0, declaration_1.isVariableDeclaration)(decls[0]) || decls[0].node !== curNode) {
|
491
828
|
return false;
|
492
829
|
}
|
493
|
-
const
|
494
|
-
if (
|
495
|
-
|
830
|
+
const completionMap = this._getExpressionCompletions(curNode, priorWord, priorText, postText);
|
831
|
+
if (completionMap) {
|
832
|
+
completionMap.delete(curNode.value);
|
496
833
|
}
|
497
|
-
return
|
834
|
+
return completionMap;
|
498
835
|
}
|
499
836
|
// Defining class variables.
|
500
837
|
// ex) class A:
|
@@ -511,7 +848,7 @@ class CompletionProvider {
|
|
511
848
|
}
|
512
849
|
_isWithinComment(offset) {
|
513
850
|
var _a, _b;
|
514
|
-
const token = getTokenAfter(offset, this.
|
851
|
+
const token = getTokenAfter(offset, this.parseResults.tokenizerOutput.tokens);
|
515
852
|
if (!token) {
|
516
853
|
// If we're in the middle of a token, we're not in a comment.
|
517
854
|
return false;
|
@@ -561,8 +898,8 @@ class CompletionProvider {
|
|
561
898
|
case 7 /* MissingMemberAccessName */:
|
562
899
|
case 2 /* MissingExpression */: {
|
563
900
|
// Don't show completion after random dots.
|
564
|
-
const tokenizerOutput = this.
|
565
|
-
const offset = (0, positionUtils_1.convertPositionToOffset)(this.
|
901
|
+
const tokenizerOutput = this.parseResults.tokenizerOutput;
|
902
|
+
const offset = (0, positionUtils_1.convertPositionToOffset)(this.position, tokenizerOutput.lines);
|
566
903
|
const index = ParseTreeUtils.getTokenIndexAtLeft(tokenizerOutput.tokens, offset);
|
567
904
|
const token = ParseTreeUtils.getTokenAtIndex(tokenizerOutput.tokens, index);
|
568
905
|
const prevToken = ParseTreeUtils.getTokenAtIndex(tokenizerOutput.tokens, index - 1);
|
@@ -587,7 +924,7 @@ class CompletionProvider {
|
|
587
924
|
return this._getExpressionCompletions(node, priorWord, priorText, postText);
|
588
925
|
}
|
589
926
|
const previousOffset = textRange_2.TextRange.getEnd(prevToken);
|
590
|
-
const previousNode = ParseTreeUtils.findNodeByOffset(this.
|
927
|
+
const previousNode = ParseTreeUtils.findNodeByOffset(this.parseResults.parseTree, previousOffset);
|
591
928
|
if ((previousNode === null || previousNode === void 0 ? void 0 : previousNode.nodeType) !== 0 /* Error */ ||
|
592
929
|
previousNode.category !== 7 /* MissingMemberAccessName */) {
|
593
930
|
return this._getExpressionCompletions(node, priorWord, priorText, postText);
|
@@ -624,7 +961,7 @@ class CompletionProvider {
|
|
624
961
|
}
|
625
962
|
// Determine if the partial name is a method that's overriding
|
626
963
|
// a method in a base class.
|
627
|
-
return this.
|
964
|
+
return this.getMethodOverrideCompletions(priorWord, node.child, node.decorators);
|
628
965
|
}
|
629
966
|
break;
|
630
967
|
}
|
@@ -635,13 +972,10 @@ class CompletionProvider {
|
|
635
972
|
if (!node.child || !(0, parseNodes_1.isExpressionNode)(node.child)) {
|
636
973
|
return undefined;
|
637
974
|
}
|
638
|
-
return this.
|
975
|
+
return this.getMemberAccessCompletions(node.child, priorWord);
|
639
976
|
}
|
640
977
|
_isOverload(node) {
|
641
|
-
return this.
|
642
|
-
}
|
643
|
-
_checkDecorator(node, value) {
|
644
|
-
return node.expression.nodeType === 38 /* Name */ && node.expression.value === value;
|
978
|
+
return this.checkDecorator(node, 'overload');
|
645
979
|
}
|
646
980
|
_createSingleKeywordCompletion(keyword) {
|
647
981
|
const completionItem = vscode_languageserver_1.CompletionItem.create(keyword);
|
@@ -649,7 +983,7 @@ class CompletionProvider {
|
|
649
983
|
completionItem.sortText = this._makeSortText(SortCategory.LikelyKeyword, keyword);
|
650
984
|
const completionMap = new CompletionMap();
|
651
985
|
completionMap.set(completionItem);
|
652
|
-
return
|
986
|
+
return completionMap;
|
653
987
|
}
|
654
988
|
_addClassVariableTypeAnnotationCompletions(priorWord, parseNode, completionMap) {
|
655
989
|
var _a, _b, _c, _d;
|
@@ -668,7 +1002,7 @@ class CompletionProvider {
|
|
668
1002
|
if (!enclosingClass) {
|
669
1003
|
return;
|
670
1004
|
}
|
671
|
-
const classResults = this.
|
1005
|
+
const classResults = this.evaluator.getTypeOfClass(enclosingClass);
|
672
1006
|
if (!classResults) {
|
673
1007
|
return undefined;
|
674
1008
|
}
|
@@ -676,8 +1010,8 @@ class CompletionProvider {
|
|
676
1010
|
const classMember = (0, typeUtils_1.lookUpClassMember)(classResults.classType, classVariableName, 8 /* SkipInstanceVariables */ | 1 /* SkipOriginalClass */);
|
677
1011
|
// First, see whether we can use semantic info to get variable type.
|
678
1012
|
if (classMember) {
|
679
|
-
const memberType = this.
|
680
|
-
const text = this.
|
1013
|
+
const memberType = this.evaluator.getTypeOfMember(classMember);
|
1014
|
+
const text = this.evaluator.printType(memberType, {
|
681
1015
|
enforcePythonSyntax: true,
|
682
1016
|
expandTypeAlias: false,
|
683
1017
|
});
|
@@ -713,7 +1047,7 @@ class CompletionProvider {
|
|
713
1047
|
if (declWithTypeAnnotations.length === 0) {
|
714
1048
|
return;
|
715
1049
|
}
|
716
|
-
const printFlags = (0, sourceMapper_1.isStubFile)(this.
|
1050
|
+
const printFlags = (0, sourceMapper_1.isStubFile)(this.filePath)
|
717
1051
|
? 1 /* ForwardDeclarations */ |
|
718
1052
|
2 /* DoNotLimitStringLength */
|
719
1053
|
: 2 /* DoNotLimitStringLength */;
|
@@ -727,7 +1061,7 @@ class CompletionProvider {
|
|
727
1061
|
if (!enclosingClass) {
|
728
1062
|
return undefined;
|
729
1063
|
}
|
730
|
-
const classResults = this.
|
1064
|
+
const classResults = this.evaluator.getTypeOfClass(enclosingClass);
|
731
1065
|
if (!classResults) {
|
732
1066
|
return undefined;
|
733
1067
|
}
|
@@ -753,13 +1087,13 @@ class CompletionProvider {
|
|
753
1087
|
decls.some((d) => d.node && ParseTreeUtils.getEnclosingClass(d.node, false) === enclosingClass)) {
|
754
1088
|
return;
|
755
1089
|
}
|
756
|
-
this.
|
1090
|
+
this.addSymbol(name, symbol, partialName.value, completionMap, {});
|
757
1091
|
});
|
758
|
-
return completionMap.size > 0 ?
|
1092
|
+
return completionMap.size > 0 ? completionMap : undefined;
|
759
1093
|
}
|
760
1094
|
_getMethodOverloadsCompletions(priorWord, partialName) {
|
761
1095
|
var _a;
|
762
|
-
const symbolTable = getSymbolTable(this.
|
1096
|
+
const symbolTable = getSymbolTable(this.evaluator, partialName);
|
763
1097
|
if (!symbolTable) {
|
764
1098
|
return undefined;
|
765
1099
|
}
|
@@ -781,14 +1115,14 @@ class CompletionProvider {
|
|
781
1115
|
return;
|
782
1116
|
}
|
783
1117
|
if (StringUtils.isPatternInSymbol(partialName.value, name)) {
|
784
|
-
const textEdit = this.
|
785
|
-
this.
|
1118
|
+
const textEdit = this.createReplaceEdits(priorWord, partialName, decl.node.name.value);
|
1119
|
+
this.addSymbol(name, symbol, partialName.value, completionMap, {
|
786
1120
|
funcParensDisabled,
|
787
1121
|
edits: { textEdit },
|
788
1122
|
});
|
789
1123
|
}
|
790
1124
|
});
|
791
|
-
return
|
1125
|
+
return completionMap;
|
792
1126
|
function getSymbolTable(evaluator, partialName) {
|
793
1127
|
const enclosingClass = ParseTreeUtils.getEnclosingClass(partialName, false);
|
794
1128
|
if (enclosingClass) {
|
@@ -799,153 +1133,37 @@ class CompletionProvider {
|
|
799
1133
|
const symbolTable = new Map();
|
800
1134
|
for (const mroClass of classResults.classType.details.mro) {
|
801
1135
|
if ((0, types_1.isInstantiableClass)(mroClass)) {
|
802
|
-
(0, typeUtils_1.getMembersForClass)(mroClass, symbolTable, /* includeInstanceVars */ false);
|
803
|
-
}
|
804
|
-
}
|
805
|
-
return symbolTable;
|
806
|
-
}
|
807
|
-
// For function overload, we only care about top level functions
|
808
|
-
const moduleNode = ParseTreeUtils.getEnclosingModule(partialName);
|
809
|
-
if (moduleNode) {
|
810
|
-
const moduleScope = AnalyzerNodeInfo.getScope(moduleNode);
|
811
|
-
return moduleScope === null || moduleScope === void 0 ? void 0 : moduleScope.symbolTable;
|
812
|
-
}
|
813
|
-
return undefined;
|
814
|
-
}
|
815
|
-
}
|
816
|
-
_getMethodOverrideCompletions(priorWord, partialName, decorators) {
|
817
|
-
var _a, _b;
|
818
|
-
const enclosingClass = ParseTreeUtils.getEnclosingClass(partialName, /* stopAtFunction */ true);
|
819
|
-
if (!enclosingClass) {
|
820
|
-
return undefined;
|
821
|
-
}
|
822
|
-
const classResults = this._evaluator.getTypeOfClass(enclosingClass);
|
823
|
-
if (!classResults) {
|
824
|
-
return undefined;
|
825
|
-
}
|
826
|
-
const staticmethod = (_a = decorators === null || decorators === void 0 ? void 0 : decorators.some((d) => this._checkDecorator(d, 'staticmethod'))) !== null && _a !== void 0 ? _a : false;
|
827
|
-
const classmethod = (_b = decorators === null || decorators === void 0 ? void 0 : decorators.some((d) => this._checkDecorator(d, 'classmethod'))) !== null && _b !== void 0 ? _b : false;
|
828
|
-
const fallbackPath = (0, pythonPathUtils_1.getTypeShedFallbackPath)(this._importResolver.fileSystem);
|
829
|
-
const typingFilePath = fallbackPath ? (0, pathUtils_1.combinePaths)(fallbackPath, 'stdlib/typing.pyi') : undefined;
|
830
|
-
const appendMember = (map, member, name) => {
|
831
|
-
if (!(0, types_1.isInstantiableClass)(member.classType) ||
|
832
|
-
member.classType.details === classResults.classType.details ||
|
833
|
-
!StringUtils.isPatternInSymbol(partialName.value, name)) {
|
834
|
-
// Quick bail out if member is something we don't want to override.
|
835
|
-
return;
|
836
|
-
}
|
837
|
-
const symbol = member.symbol;
|
838
|
-
const decl = (0, symbolUtils_1.getLastTypedDeclaredForSymbol)(symbol);
|
839
|
-
if (!decl || decl.type !== 5 /* Function */) {
|
840
|
-
return;
|
841
|
-
}
|
842
|
-
const declaredType = this._evaluator.getTypeOfMember(member);
|
843
|
-
if (!declaredType) {
|
844
|
-
return;
|
845
|
-
}
|
846
|
-
const isDeclaredStaticMethod = (0, types_1.isFunction)(declaredType) && types_1.FunctionType.isStaticMethod(declaredType);
|
847
|
-
// Special-case the "__init__subclass__" method because it's an implicit
|
848
|
-
// classmethod that the type evaluator flags as a real classmethod.
|
849
|
-
const isDeclaredClassMethod = (0, types_1.isFunction)(declaredType) && types_1.FunctionType.isClassMethod(declaredType) && name !== '__init_subclass__';
|
850
|
-
if (staticmethod !== isDeclaredStaticMethod || classmethod !== isDeclaredClassMethod) {
|
851
|
-
return;
|
852
|
-
}
|
853
|
-
let isProperty = (0, types_1.isClassInstance)(declaredType) && types_1.ClassType.isPropertyClass(declaredType);
|
854
|
-
if (SymbolNameUtils.isDunderName(name)) {
|
855
|
-
// Don't offer suggestions for built-in properties like "__class__", etc.
|
856
|
-
isProperty = false;
|
857
|
-
}
|
858
|
-
let funcType = undefined;
|
859
|
-
if ((0, types_1.isFunction)(declaredType)) {
|
860
|
-
funcType = declaredType;
|
861
|
-
}
|
862
|
-
else if (isProperty) {
|
863
|
-
const getter = (0, typeUtils_1.lookUpClassMember)(declaredType, 'fget');
|
864
|
-
if (!getter) {
|
865
|
-
return;
|
866
|
-
}
|
867
|
-
const member = this._evaluator.getTypeOfMember(getter);
|
868
|
-
if (!(0, types_1.isFunction)(member)) {
|
869
|
-
return;
|
1136
|
+
(0, typeUtils_1.getMembersForClass)(mroClass, symbolTable, /* includeInstanceVars */ false);
|
1137
|
+
}
|
870
1138
|
}
|
871
|
-
|
872
|
-
}
|
873
|
-
if (!funcType || !funcType.details.declaration) {
|
874
|
-
return;
|
1139
|
+
return symbolTable;
|
875
1140
|
}
|
876
|
-
|
877
|
-
const
|
878
|
-
|
879
|
-
|
880
|
-
|
1141
|
+
// For function overload, we only care about top level functions
|
1142
|
+
const moduleNode = ParseTreeUtils.getEnclosingModule(partialName);
|
1143
|
+
if (moduleNode) {
|
1144
|
+
const moduleScope = AnalyzerNodeInfo.getScope(moduleNode);
|
1145
|
+
return moduleScope === null || moduleScope === void 0 ? void 0 : moduleScope.symbolTable;
|
881
1146
|
}
|
882
|
-
|
883
|
-
const methodBody = this._printOverriddenMethodBody(classResults.classType, isDeclaredStaticMethod, isProperty, decl);
|
884
|
-
text = `${result.methodSignature}:\n${methodBody}`;
|
885
|
-
}
|
886
|
-
const textEdit = this._createReplaceEdits(priorWord, partialName, text);
|
887
|
-
// This will add new import statements, but for now, it won't add new
|
888
|
-
// `TypeVar` statement such as TypeVar, TypeVarTuple, ParamSpec even if
|
889
|
-
// the overridden method uses them.
|
890
|
-
const additionalTextEdits = importAdder.applyImports(result.importData, this._filePath, this._parseResults, this._parseResults.parseTree.length, "absolute" /* Absolute */, this._cancellationToken);
|
891
|
-
this._addSymbol(name, symbol, partialName.value, map, {
|
892
|
-
// method signature already contains ()
|
893
|
-
funcParensDisabled: true,
|
894
|
-
edits: {
|
895
|
-
format: this._options.snippet ? vscode_languageserver_1.InsertTextFormat.Snippet : undefined,
|
896
|
-
textEdit,
|
897
|
-
additionalTextEdits,
|
898
|
-
},
|
899
|
-
});
|
900
|
-
};
|
901
|
-
const completionMap = new CompletionMap();
|
902
|
-
const classMemberMap = (0, typeUtils_1.getClassFieldsRecursive)(classResults.classType);
|
903
|
-
classMemberMap.forEach((member, name) => appendMember(completionMap, member, name));
|
904
|
-
if (classResults.classType.details.effectiveMetaclass &&
|
905
|
-
!(0, types_1.isUnknown)(classResults.classType.details.effectiveMetaclass)) {
|
906
|
-
const metaClassMemberMap = (0, typeUtils_1.getClassFieldsRecursive)(classResults.classType.details.effectiveMetaclass);
|
907
|
-
metaClassMemberMap.forEach((member, name) => appendMember(completionMap, member, name));
|
1147
|
+
return undefined;
|
908
1148
|
}
|
909
|
-
return { completionMap };
|
910
|
-
}
|
911
|
-
_createReplaceEdits(priorWord, node, text) {
|
912
|
-
const replaceOrInsertEndChar = (node === null || node === void 0 ? void 0 : node.nodeType) === 38 /* Name */
|
913
|
-
? this._position.character - priorWord.length + node.value.length
|
914
|
-
: this._position.character;
|
915
|
-
const range = {
|
916
|
-
start: { line: this._position.line, character: this._position.character - priorWord.length },
|
917
|
-
end: { line: this._position.line, character: replaceOrInsertEndChar },
|
918
|
-
};
|
919
|
-
return vscode_languageserver_1.TextEdit.replace(range, text);
|
920
1149
|
}
|
921
|
-
_printMethodSignature(
|
922
|
-
const
|
1150
|
+
_printMethodSignature(classType, decl) {
|
1151
|
+
const node = decl.node;
|
923
1152
|
let ellipsisForDefault;
|
924
|
-
if ((0, sourceMapper_1.isStubFile)(this.
|
1153
|
+
if ((0, sourceMapper_1.isStubFile)(this.filePath)) {
|
925
1154
|
// In stubs, always use "...".
|
926
1155
|
ellipsisForDefault = true;
|
927
1156
|
}
|
928
|
-
else if (classType.details.moduleName ===
|
1157
|
+
else if (classType.details.moduleName === decl.moduleName) {
|
929
1158
|
// In the same file, always print the full default.
|
930
1159
|
ellipsisForDefault = false;
|
931
1160
|
}
|
932
|
-
const
|
1161
|
+
const printFlags = (0, sourceMapper_1.isStubFile)(this.filePath)
|
933
1162
|
? 1 /* ForwardDeclarations */ |
|
934
1163
|
2 /* DoNotLimitStringLength */
|
935
1164
|
: 2 /* DoNotLimitStringLength */;
|
936
|
-
const
|
937
|
-
|
938
|
-
expandTypeAlias: false,
|
939
|
-
omitTypeArgumentsIfUnknown: true,
|
940
|
-
printUnknownWithAny: true,
|
941
|
-
};
|
942
|
-
const getTypeToPrint = (mainType, fallbackType) => {
|
943
|
-
return mainType && (!(0, types_1.isUnknown)(mainType) || (fallbackType === null || fallbackType === void 0 ? void 0 : fallbackType.category) === 10 /* TypeVar */)
|
944
|
-
? mainType
|
945
|
-
: fallbackType;
|
946
|
-
};
|
947
|
-
const importData = createImportData(importAdder, funcType, declaration, typingFilePath, (t) => this._sourceMapper.findClassDeclarationsByType(this._filePath, t), this._cancellationToken);
|
948
|
-
const paramList = funcType.details.parameters.map((param, index) => {
|
1165
|
+
const paramList = node.parameters
|
1166
|
+
.map((param, index) => {
|
949
1167
|
let paramString = '';
|
950
1168
|
if (param.category === 1 /* VarArgList */) {
|
951
1169
|
paramString += '*';
|
@@ -954,325 +1172,35 @@ class CompletionProvider {
|
|
954
1172
|
paramString += '**';
|
955
1173
|
}
|
956
1174
|
if (param.name) {
|
957
|
-
paramString += param.name;
|
958
|
-
}
|
959
|
-
if (param.typeAnnotation) {
|
960
|
-
const originalType = funcType.details.parameters[index].type;
|
961
|
-
const typeToPrint = getTypeToPrint(types_1.FunctionType.getEffectiveParameterType(funcType, index), originalType);
|
962
|
-
// If we have actual type, then use type to generate string representation of the type, otherwise, use syntax (text).
|
963
|
-
const strType = isTypeUsableForPrint(typeToPrint, originalType)
|
964
|
-
? this._evaluator.printType(typeToPrint, printOptionsUsingType)
|
965
|
-
: ParseTreeUtils.printExpression(param.typeAnnotation, printOptionsUsingSyntax);
|
966
|
-
paramString += ': ' + strType;
|
967
|
-
}
|
968
|
-
if (param.defaultValueExpression) {
|
969
|
-
paramString += param.typeAnnotation ? ' = ' : '=';
|
970
|
-
const useEllipsis = ellipsisForDefault !== null && ellipsisForDefault !== void 0 ? ellipsisForDefault : !isSimpleDefault(param.defaultValueExpression);
|
971
|
-
paramString += useEllipsis
|
972
|
-
? '...'
|
973
|
-
: ParseTreeUtils.printExpression(param.defaultValueExpression, printOptionsUsingSyntax);
|
974
|
-
}
|
975
|
-
if (!paramString &&
|
976
|
-
!param.name &&
|
977
|
-
param.category === 0 /* Simple */ &&
|
978
|
-
index < funcType.details.parameters.length - 1) {
|
979
|
-
return '/';
|
980
|
-
}
|
981
|
-
return paramString;
|
982
|
-
});
|
983
|
-
// Remove empty parameters at the end.
|
984
|
-
for (let i = paramList.length - 1; i >= 0; i--) {
|
985
|
-
if (paramList[i] !== '') {
|
986
|
-
break;
|
987
|
-
}
|
988
|
-
paramList.pop();
|
989
|
-
}
|
990
|
-
let methodSignature = funcType.details.name + '(' + paramList.join(', ') + ')';
|
991
|
-
const strReturnType = getReturnTypeStr(this._evaluator, funcType, printOptionsUsingSyntax);
|
992
|
-
if (strReturnType) {
|
993
|
-
methodSignature += ' -> ' + strReturnType;
|
994
|
-
}
|
995
|
-
return { methodSignature, importData };
|
996
|
-
function createImportData(importAdder, funcType, declaration, typingFilePath, declarationGetter, token) {
|
997
|
-
var _a, _b;
|
998
|
-
// Handle regular case. In this case, we can get import info from
|
999
|
-
// import used in the file where the function is declared.
|
1000
|
-
const ranges = [];
|
1001
|
-
(0, collectionUtils_1.addIfNotNull)(ranges, textRange_2.TextRange.combine(declaration.node.parameters));
|
1002
|
-
(0, collectionUtils_1.addIfNotNull)(ranges, declaration.node.returnTypeAnnotation);
|
1003
|
-
(0, collectionUtils_1.addIfNotNull)(ranges, declaration.node.functionAnnotationComment);
|
1004
|
-
const moduleNode = ParseTreeUtils.getModuleNode(declaration.node);
|
1005
|
-
const importData = importAdder.collectImportsForSymbolsUsed(moduleNode, ranges, token);
|
1006
|
-
// Handle special case where function has type arguments. In this case,
|
1007
|
-
// we can't use the file the function is declared in because it doesn't
|
1008
|
-
// have those type arguments. It just has the type vars.
|
1009
|
-
// We could walk the mro to discover imports for the type arguments, but
|
1010
|
-
// for now, instead, this creates import statement out of type arguments itself.
|
1011
|
-
const effectiveTypes = [];
|
1012
|
-
funcType.details.parameters.forEach((param, index) => {
|
1013
|
-
if (!param.typeAnnotation) {
|
1014
|
-
return;
|
1015
|
-
}
|
1016
|
-
const originalType = funcType.details.parameters[index].type;
|
1017
|
-
if (!(0, types_1.isTypeVar)(originalType)) {
|
1018
|
-
return;
|
1019
|
-
}
|
1020
|
-
const effectiveType = types_1.FunctionType.getEffectiveParameterType(funcType, index);
|
1021
|
-
effectiveTypes.push([effectiveType, param.typeAnnotation]);
|
1022
|
-
});
|
1023
|
-
const node = declaration.node;
|
1024
|
-
const originalType = funcType.details.declaredReturnType;
|
1025
|
-
if (originalType &&
|
1026
|
-
(0, types_1.isTypeVar)(originalType) &&
|
1027
|
-
(node.returnTypeAnnotation || ((_a = node.functionAnnotationComment) === null || _a === void 0 ? void 0 : _a.returnTypeAnnotation))) {
|
1028
|
-
effectiveTypes.push([
|
1029
|
-
types_1.FunctionType.getSpecializedReturnType(funcType),
|
1030
|
-
(_b = node.returnTypeAnnotation) !== null && _b !== void 0 ? _b : node.functionAnnotationComment.returnTypeAnnotation,
|
1031
|
-
]);
|
1032
|
-
}
|
1033
|
-
const visited = new Set();
|
1034
|
-
const addImport = (t, n) => {
|
1035
|
-
var _a, _b;
|
1036
|
-
if (visited.has(t)) {
|
1037
|
-
return;
|
1038
|
-
}
|
1039
|
-
visited.add(t);
|
1040
|
-
// We need to special case `Any` since we can't get decl from `Any`.
|
1041
|
-
if ((0, types_1.isAny)(t)) {
|
1042
|
-
if (!typingFilePath) {
|
1043
|
-
return;
|
1044
|
-
}
|
1045
|
-
importAdder.addImportInfo({ filePath: typingFilePath, nameInfo: { name: 'Any' } }, importData);
|
1046
|
-
}
|
1047
|
-
if (!(0, types_1.isClass)(t)) {
|
1048
|
-
return;
|
1049
|
-
}
|
1050
|
-
// We need to special case `List`, `Dict` and `Tuple` since user might have
|
1051
|
-
// used typing.List or typing.Dict in the code, but we internally already
|
1052
|
-
// converted them to built-in `list` and `dict`.
|
1053
|
-
// We could avoid doing this if class type holds onto decl it was created from
|
1054
|
-
// if it is not synthesized like func type.
|
1055
|
-
if (typingFilePath && types_1.ClassType.isBuiltIn(t)) {
|
1056
|
-
const name = (_a = t.aliasName) !== null && _a !== void 0 ? _a : t.details.name;
|
1057
|
-
if (t.details.moduleName === 'typing' && name) {
|
1058
|
-
importAdder.addImportInfo({
|
1059
|
-
filePath: typingFilePath,
|
1060
|
-
nameInfo: { name },
|
1061
|
-
}, importData);
|
1062
|
-
}
|
1063
|
-
else if (t.details.moduleName === 'builtins' && t.aliasName) {
|
1064
|
-
importAdder.addImportInfo({
|
1065
|
-
filePath: typingFilePath,
|
1066
|
-
nameInfo: { name },
|
1067
|
-
}, importData);
|
1068
|
-
}
|
1069
|
-
}
|
1070
|
-
else {
|
1071
|
-
const decls = declarationGetter(t);
|
1072
|
-
if (decls.length === 0) {
|
1073
|
-
return;
|
1074
|
-
}
|
1075
|
-
importAdder.addDeclaration(decls[0], n, importData);
|
1076
|
-
}
|
1077
|
-
if (t.isTypeArgumentExplicit) {
|
1078
|
-
(_b = t.typeArguments) === null || _b === void 0 ? void 0 : _b.forEach((ta) => {
|
1079
|
-
addImport(ta, n);
|
1080
|
-
(0, typeUtils_1.doForEachSubtype)(ta, (subtype) => {
|
1081
|
-
addImport(subtype, n);
|
1082
|
-
});
|
1083
|
-
});
|
1084
|
-
}
|
1085
|
-
};
|
1086
|
-
effectiveTypes.forEach(([t, n]) => {
|
1087
|
-
addImport(t, n);
|
1088
|
-
(0, typeUtils_1.doForEachSubtype)(t, (subtype) => {
|
1089
|
-
addImport(subtype, n);
|
1090
|
-
});
|
1091
|
-
});
|
1092
|
-
return importData;
|
1093
|
-
}
|
1094
|
-
function getReturnTypeStr(evaluator, funcType, printFlags) {
|
1095
|
-
var _a;
|
1096
|
-
const originalType = funcType.details.declaredReturnType;
|
1097
|
-
const typeToPrint = getTypeToPrint(types_1.FunctionType.getSpecializedReturnType(funcType), originalType);
|
1098
|
-
const node = funcType.details.declaration.node;
|
1099
|
-
if (!node.returnTypeAnnotation && !((_a = node.functionAnnotationComment) === null || _a === void 0 ? void 0 : _a.returnTypeAnnotation)) {
|
1100
|
-
return undefined;
|
1101
|
-
}
|
1102
|
-
if (typeToPrint && isTypeUsableForPrint(typeToPrint, originalType)) {
|
1103
|
-
return evaluator.printType(typeToPrint, printOptionsUsingType);
|
1104
|
-
}
|
1105
|
-
if (node.returnTypeAnnotation) {
|
1106
|
-
return ParseTreeUtils.printExpression(node.returnTypeAnnotation, printFlags);
|
1107
|
-
}
|
1108
|
-
if (node.functionAnnotationComment) {
|
1109
|
-
return ParseTreeUtils.printExpression(node.functionAnnotationComment.returnTypeAnnotation, printFlags);
|
1110
|
-
}
|
1111
|
-
return undefined;
|
1112
|
-
}
|
1113
|
-
function isTypeUsableForPrint(effectiveType, originalType) {
|
1114
|
-
if (!effectiveType) {
|
1115
|
-
return false;
|
1116
|
-
}
|
1117
|
-
// If original type was `TypeVar`, we want to use `Unknown` as `Any`
|
1118
|
-
return !(0, types_1.isUnknown)(effectiveType) || (originalType === null || originalType === void 0 ? void 0 : originalType.category) === 10 /* TypeVar */;
|
1119
|
-
}
|
1120
|
-
function isSimpleDefault(node) {
|
1121
|
-
switch (node.nodeType) {
|
1122
|
-
case 40 /* Number */:
|
1123
|
-
case 11 /* Constant */:
|
1124
|
-
case 35 /* MemberAccess */:
|
1125
|
-
return true;
|
1126
|
-
case 49 /* String */:
|
1127
|
-
return (node.token.flags & 64 /* Format */) === 0;
|
1128
|
-
case 48 /* StringList */:
|
1129
|
-
return node.strings.every(isSimpleDefault);
|
1130
|
-
case 55 /* UnaryOperation */:
|
1131
|
-
return isSimpleDefault(node.expression);
|
1132
|
-
case 7 /* BinaryOperation */:
|
1133
|
-
return isSimpleDefault(node.leftExpression) && isSimpleDefault(node.rightExpression);
|
1134
|
-
default:
|
1135
|
-
return false;
|
1136
|
-
}
|
1137
|
-
}
|
1138
|
-
}
|
1139
|
-
_printOverriddenMethodBody(classType, isStaticMethod, isProperty, decl) {
|
1140
|
-
let sb = this._parseResults.tokenizerOutput.predominantTabSequence;
|
1141
|
-
if (classType.details.baseClasses.length === 1 &&
|
1142
|
-
(0, types_1.isClass)(classType.details.baseClasses[0]) &&
|
1143
|
-
classType.details.baseClasses[0].details.fullName === 'builtins.object') {
|
1144
|
-
sb += this._options.snippet ? '${0:pass}' : 'pass';
|
1145
|
-
return sb;
|
1146
|
-
}
|
1147
|
-
if (decl.node.parameters.length === 0) {
|
1148
|
-
sb += this._options.snippet ? '${0:pass}' : 'pass';
|
1149
|
-
return sb;
|
1150
|
-
}
|
1151
|
-
const parameters = getParameters(isStaticMethod ? decl.node.parameters : decl.node.parameters.slice(1));
|
1152
|
-
if (decl.node.name.value !== '__init__') {
|
1153
|
-
sb += 'return ';
|
1154
|
-
}
|
1155
|
-
if (decl.node.isAsync) {
|
1156
|
-
sb += 'await ';
|
1157
|
-
}
|
1158
|
-
if (isProperty) {
|
1159
|
-
return sb + `super().${decl.node.name.value}`;
|
1160
|
-
}
|
1161
|
-
return sb + `super().${decl.node.name.value}(${parameters.map(convertToString).join(', ')})`;
|
1162
|
-
function getParameters(parameters) {
|
1163
|
-
const results = [];
|
1164
|
-
let sawKeywordOnlySeparator = false;
|
1165
|
-
for (const parameter of parameters) {
|
1166
|
-
if (parameter.name) {
|
1167
|
-
results.push([
|
1168
|
-
parameter,
|
1169
|
-
parameter.category === 0 /* Simple */ && !!parameter.name && sawKeywordOnlySeparator,
|
1170
|
-
]);
|
1171
|
-
}
|
1172
|
-
// All simple parameters after a `*` or `*args` parameter
|
1173
|
-
// are considered keyword only.
|
1174
|
-
if (parameter.category === 1 /* VarArgList */) {
|
1175
|
-
sawKeywordOnlySeparator = true;
|
1176
|
-
}
|
1177
|
-
}
|
1178
|
-
return results;
|
1179
|
-
}
|
1180
|
-
function convertToString(parameter) {
|
1181
|
-
var _a;
|
1182
|
-
const name = (_a = parameter[0].name) === null || _a === void 0 ? void 0 : _a.value;
|
1183
|
-
if (parameter[0].category === 1 /* VarArgList */) {
|
1184
|
-
return `*${name}`;
|
1185
|
-
}
|
1186
|
-
if (parameter[0].category === 2 /* VarArgDictionary */) {
|
1187
|
-
return `**${name}`;
|
1175
|
+
paramString += param.name.value;
|
1188
1176
|
}
|
1189
|
-
|
1190
|
-
|
1191
|
-
|
1192
|
-
|
1193
|
-
|
1194
|
-
const completionMap = new CompletionMap();
|
1195
|
-
let memberAccessInfo = {};
|
1196
|
-
let leftType = this._evaluator.getType(leftExprNode);
|
1197
|
-
if (leftType) {
|
1198
|
-
leftType = this._evaluator.makeTopLevelTypeVarsConcrete(leftType);
|
1199
|
-
// If this is an unknown type with a "possible type" associated with
|
1200
|
-
// it, use the possible type.
|
1201
|
-
if ((0, types_1.isUnknown)(leftType) && leftType.possibleType) {
|
1202
|
-
leftType = this._evaluator.makeTopLevelTypeVarsConcrete(leftType.possibleType);
|
1203
|
-
}
|
1204
|
-
(0, typeUtils_1.doForEachSubtype)(leftType, (subtype) => {
|
1205
|
-
subtype = this._evaluator.makeTopLevelTypeVarsConcrete(subtype);
|
1206
|
-
if ((0, types_1.isClass)(subtype)) {
|
1207
|
-
(0, typeUtils_1.getMembersForClass)(subtype, symbolTable, /* includeInstanceVars */ types_1.TypeBase.isInstance(subtype));
|
1208
|
-
}
|
1209
|
-
else if ((0, types_1.isModule)(subtype)) {
|
1210
|
-
(0, typeUtils_1.getMembersForModule)(subtype, symbolTable);
|
1211
|
-
}
|
1212
|
-
else if ((0, types_1.isFunction)(subtype) || (0, types_1.isOverloadedFunction)(subtype)) {
|
1213
|
-
const functionClass = this._evaluator.getBuiltInType(leftExprNode, 'function');
|
1214
|
-
if (functionClass && (0, types_1.isInstantiableClass)(functionClass)) {
|
1215
|
-
(0, typeUtils_1.getMembersForClass)(functionClass, symbolTable, /* includeInstanceVars */ true);
|
1216
|
-
}
|
1217
|
-
}
|
1218
|
-
else if ((0, types_1.isNoneInstance)(subtype)) {
|
1219
|
-
const objectClass = this._evaluator.getBuiltInType(leftExprNode, 'object');
|
1220
|
-
if (objectClass && (0, types_1.isInstantiableClass)(objectClass)) {
|
1221
|
-
(0, typeUtils_1.getMembersForClass)(objectClass, symbolTable, types_1.TypeBase.isInstance(subtype));
|
1222
|
-
}
|
1223
|
-
}
|
1224
|
-
this._addSymbolsForSymbolTable(symbolTable, () => true, priorWord, leftExprNode,
|
1225
|
-
/* isInImport */ false, (0, types_1.isClass)(subtype) ? subtype : undefined, completionMap);
|
1226
|
-
});
|
1227
|
-
}
|
1228
|
-
// Save member access info for every request
|
1229
|
-
memberAccessInfo = this._getLastKnownModule(leftExprNode, leftType);
|
1230
|
-
return { completionMap, memberAccessInfo };
|
1231
|
-
}
|
1232
|
-
_getLastKnownModule(leftExprNode, leftType) {
|
1233
|
-
var _a;
|
1234
|
-
let curNode = leftExprNode;
|
1235
|
-
let curType = leftType;
|
1236
|
-
let unknownMemberName = leftExprNode.nodeType === 35 /* MemberAccess */ ? leftExprNode === null || leftExprNode === void 0 ? void 0 : leftExprNode.memberName.value : undefined;
|
1237
|
-
// Walk left of the expression scope till we find a known type. A.B.Unknown.<-- return B.
|
1238
|
-
while (curNode) {
|
1239
|
-
if (curNode.nodeType === 9 /* Call */ || curNode.nodeType === 35 /* MemberAccess */) {
|
1240
|
-
// Move left
|
1241
|
-
curNode = curNode.leftExpression;
|
1242
|
-
// First time in the loop remember the name of the unknown type.
|
1243
|
-
if (unknownMemberName === undefined) {
|
1244
|
-
unknownMemberName =
|
1245
|
-
curNode.nodeType === 35 /* MemberAccess */ ? (_a = curNode === null || curNode === void 0 ? void 0 : curNode.memberName.value) !== null && _a !== void 0 ? _a : '' : '';
|
1246
|
-
}
|
1177
|
+
// Currently, we don't automatically add import if the type used in the annotation is not imported
|
1178
|
+
// in current file.
|
1179
|
+
const paramTypeAnnotation = ParseTreeUtils.getTypeAnnotationForParameter(node, index);
|
1180
|
+
if (paramTypeAnnotation) {
|
1181
|
+
paramString += ': ' + ParseTreeUtils.printExpression(paramTypeAnnotation, printFlags);
|
1247
1182
|
}
|
1248
|
-
|
1249
|
-
|
1183
|
+
if (param.defaultValue) {
|
1184
|
+
paramString += paramTypeAnnotation ? ' = ' : '=';
|
1185
|
+
const useEllipsis = ellipsisForDefault !== null && ellipsisForDefault !== void 0 ? ellipsisForDefault : !this.isSimpleDefault(param.defaultValue);
|
1186
|
+
paramString += useEllipsis ? '...' : ParseTreeUtils.printExpression(param.defaultValue, printFlags);
|
1250
1187
|
}
|
1251
|
-
if (
|
1252
|
-
|
1253
|
-
// Breakout if we found a known type.
|
1254
|
-
if (curType !== undefined && !(0, types_1.isUnknown)(curType) && !(0, types_1.isUnbound)(curType)) {
|
1255
|
-
break;
|
1256
|
-
}
|
1188
|
+
if (!paramString && !param.name && param.category === 0 /* Simple */) {
|
1189
|
+
return '/';
|
1257
1190
|
}
|
1191
|
+
return paramString;
|
1192
|
+
})
|
1193
|
+
.join(', ');
|
1194
|
+
let methodSignature = node.name.value + '(' + paramList + ')';
|
1195
|
+
if (node.returnTypeAnnotation) {
|
1196
|
+
methodSignature += ' -> ' + ParseTreeUtils.printExpression(node.returnTypeAnnotation, printFlags);
|
1258
1197
|
}
|
1259
|
-
|
1260
|
-
|
1261
|
-
|
1262
|
-
|
1263
|
-
memberAccessInfo.lastKnownModule = moduleNamesForType.find((n) => n !== 'typing');
|
1264
|
-
if (curNode.nodeType === 35 /* MemberAccess */) {
|
1265
|
-
memberAccessInfo.lastKnownMemberName = curNode.memberName.value;
|
1266
|
-
}
|
1267
|
-
else if (curNode.nodeType === 38 /* Name */ && (0, types_1.isInstantiableClass)(curType)) {
|
1268
|
-
memberAccessInfo.lastKnownMemberName = curType.details.name;
|
1269
|
-
}
|
1270
|
-
else if (curNode.nodeType === 38 /* Name */ && (0, types_1.isClassInstance)(curType)) {
|
1271
|
-
memberAccessInfo.lastKnownMemberName = curType.details.name;
|
1272
|
-
}
|
1273
|
-
memberAccessInfo.unknownMemberName = unknownMemberName;
|
1198
|
+
else if (node.functionAnnotationComment) {
|
1199
|
+
methodSignature +=
|
1200
|
+
' -> ' +
|
1201
|
+
ParseTreeUtils.printExpression(node.functionAnnotationComment.returnTypeAnnotation, printFlags);
|
1274
1202
|
}
|
1275
|
-
return
|
1203
|
+
return methodSignature;
|
1276
1204
|
}
|
1277
1205
|
_getStatementCompletions(parseNode, priorWord, priorText, postText) {
|
1278
1206
|
// For now, use the same logic for expressions and statements.
|
@@ -1293,10 +1221,9 @@ class CompletionProvider {
|
|
1293
1221
|
return undefined;
|
1294
1222
|
}
|
1295
1223
|
const completionMap = new CompletionMap();
|
1296
|
-
const completionResults = { completionMap };
|
1297
1224
|
// Return empty completionList for Ellipsis
|
1298
1225
|
if (priorText.slice(-2) === '..') {
|
1299
|
-
return
|
1226
|
+
return completionMap;
|
1300
1227
|
}
|
1301
1228
|
// Defining type annotation for class variables.
|
1302
1229
|
// ex) class A:
|
@@ -1308,7 +1235,7 @@ class CompletionProvider {
|
|
1308
1235
|
// Add symbols that are in scope.
|
1309
1236
|
this._addSymbols(parseNode, priorWord, completionMap);
|
1310
1237
|
// Add keywords.
|
1311
|
-
this._findMatchingKeywords(Keywords.forVersion(this.
|
1238
|
+
this._findMatchingKeywords(Keywords.forVersion(this.execEnv.pythonVersion), priorWord).map((keyword) => {
|
1312
1239
|
if (completionMap.has(keyword)) {
|
1313
1240
|
return;
|
1314
1241
|
}
|
@@ -1320,11 +1247,11 @@ class CompletionProvider {
|
|
1320
1247
|
// Add auto-import suggestions from other modules.
|
1321
1248
|
// Ignore this check for privates, since they are not imported.
|
1322
1249
|
if (!priorWord.startsWith('_') && !this._itemToResolve) {
|
1323
|
-
this.
|
1250
|
+
this.addAutoImportCompletions(priorWord, similarityLimit, this.options.lazyEdit, completionMap);
|
1324
1251
|
}
|
1325
1252
|
// Add literal values if appropriate.
|
1326
1253
|
this._tryAddLiterals(parseNode, priorWord, priorText, postText, completionMap);
|
1327
|
-
return
|
1254
|
+
return completionMap;
|
1328
1255
|
}
|
1329
1256
|
_isIndexArgument(node) {
|
1330
1257
|
const currentNode = node.parent;
|
@@ -1338,16 +1265,16 @@ class CompletionProvider {
|
|
1338
1265
|
}
|
1339
1266
|
_addCallArgumentCompletions(parseNode, priorWord, priorText, postText, atArgument, completionMap) {
|
1340
1267
|
// If we're within the argument list of a call, add parameter names.
|
1341
|
-
const offset = (0, positionUtils_1.convertPositionToOffset)(this.
|
1342
|
-
const callInfo = (0, parseTreeUtils_1.getCallNodeAndActiveParameterIndex)(parseNode, offset, this.
|
1268
|
+
const offset = (0, positionUtils_1.convertPositionToOffset)(this.position, this.parseResults.tokenizerOutput.lines);
|
1269
|
+
const callInfo = (0, parseTreeUtils_1.getCallNodeAndActiveParameterIndex)(parseNode, offset, this.parseResults.tokenizerOutput.tokens);
|
1343
1270
|
if (!callInfo) {
|
1344
1271
|
return;
|
1345
1272
|
}
|
1346
|
-
const signatureInfo = this.
|
1273
|
+
const signatureInfo = this.evaluator.getCallSignatureInfo(callInfo.callNode, callInfo.activeIndex, callInfo.activeOrFake);
|
1347
1274
|
if (signatureInfo) {
|
1348
1275
|
// Are we past the call expression and within the argument list?
|
1349
|
-
const callNameEnd = (0, positionUtils_1.convertOffsetToPosition)(signatureInfo.callNode.leftExpression.start + signatureInfo.callNode.leftExpression.length, this.
|
1350
|
-
if ((0, textRange_1.comparePositions)(this.
|
1276
|
+
const callNameEnd = (0, positionUtils_1.convertOffsetToPosition)(signatureInfo.callNode.leftExpression.start + signatureInfo.callNode.leftExpression.length, this.parseResults.tokenizerOutput.lines);
|
1277
|
+
if ((0, textRange_1.comparePositions)(this.position, callNameEnd) > 0) {
|
1351
1278
|
if (!atArgument) {
|
1352
1279
|
this._addNamedParameters(signatureInfo, priorWord, completionMap);
|
1353
1280
|
}
|
@@ -1438,7 +1365,7 @@ class CompletionProvider {
|
|
1438
1365
|
if (member === null || member === void 0 ? void 0 : member.symbol.hasDeclarations()) {
|
1439
1366
|
const declaration = member.symbol.getDeclarations()[0];
|
1440
1367
|
if ((0, declaration_1.isFunctionDeclaration)(declaration) && declaration.isMethod) {
|
1441
|
-
const getItemType = (_b = this.
|
1368
|
+
const getItemType = (_b = this.evaluator.getTypeForDeclaration(declaration)) === null || _b === void 0 ? void 0 : _b.type;
|
1442
1369
|
if (getItemType && (0, types_1.isFunction)(getItemType) && getItemType.details.parameters.length === 2) {
|
1443
1370
|
return getItemType.details.parameters[1].type;
|
1444
1371
|
}
|
@@ -1448,7 +1375,7 @@ class CompletionProvider {
|
|
1448
1375
|
}
|
1449
1376
|
_getIndexerKeys(indexNode, invocationNode) {
|
1450
1377
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
1451
|
-
const baseType = this.
|
1378
|
+
const baseType = this.evaluator.getType(indexNode.baseExpression);
|
1452
1379
|
if (!baseType || !(0, types_1.isClassInstance)(baseType)) {
|
1453
1380
|
return [];
|
1454
1381
|
}
|
@@ -1464,7 +1391,7 @@ class CompletionProvider {
|
|
1464
1391
|
!types_1.ClassType.isEnumClass(v)) {
|
1465
1392
|
return;
|
1466
1393
|
}
|
1467
|
-
keys.push((0, typePrinter_1.printLiteralValue)(v, this.
|
1394
|
+
keys.push((0, typePrinter_1.printLiteralValue)(v, this.parseResults.tokenizerOutput.predominantSingleQuoteCharacter));
|
1468
1395
|
});
|
1469
1396
|
if (keys.length > 0) {
|
1470
1397
|
return keys;
|
@@ -1475,13 +1402,13 @@ class CompletionProvider {
|
|
1475
1402
|
return [];
|
1476
1403
|
}
|
1477
1404
|
// Must be local variable/parameter
|
1478
|
-
const declarations = (_a = this.
|
1405
|
+
const declarations = (_a = this.evaluator.getDeclarationsForNameNode(indexNode.baseExpression)) !== null && _a !== void 0 ? _a : [];
|
1479
1406
|
const declaration = declarations.length > 0 ? declarations[0] : undefined;
|
1480
1407
|
if (!declaration ||
|
1481
1408
|
(declaration.type !== 1 /* Variable */ && declaration.type !== 2 /* Parameter */)) {
|
1482
1409
|
return [];
|
1483
1410
|
}
|
1484
|
-
if (declaration.path !== this.
|
1411
|
+
if (declaration.path !== this.filePath) {
|
1485
1412
|
return [];
|
1486
1413
|
}
|
1487
1414
|
let startingNode = indexNode.baseExpression;
|
@@ -1493,7 +1420,7 @@ class CompletionProvider {
|
|
1493
1420
|
startingNode = scopeRoot;
|
1494
1421
|
}
|
1495
1422
|
}
|
1496
|
-
const results = documentSymbolCollector_1.DocumentSymbolCollector.collectFromNode(
|
1423
|
+
const results = documentSymbolCollector_1.DocumentSymbolCollector.collectFromNode(this.program, indexNode.baseExpression, this.cancellationToken, startingNode);
|
1497
1424
|
const keys = new Set();
|
1498
1425
|
for (const result of results) {
|
1499
1426
|
const node = ((_d = result.node.parent) === null || _d === void 0 ? void 0 : _d.nodeType) === 54 /* TypeAnnotation */ ? result.node.parent : result.node;
|
@@ -1502,7 +1429,7 @@ class CompletionProvider {
|
|
1502
1429
|
if (node.parent.rightExpression.nodeType === 15 /* Dictionary */) {
|
1503
1430
|
const dictionary = node.parent.rightExpression;
|
1504
1431
|
for (const entry of dictionary.entries.filter((e) => e.nodeType === 17 /* DictionaryKeyEntry */)) {
|
1505
|
-
const key = this.
|
1432
|
+
const key = this.parseResults.text
|
1506
1433
|
.substr(entry.keyExpression.start, entry.keyExpression.length)
|
1507
1434
|
.trim();
|
1508
1435
|
if (key.length > 0)
|
@@ -1511,13 +1438,13 @@ class CompletionProvider {
|
|
1511
1438
|
}
|
1512
1439
|
if (node.parent.rightExpression.nodeType === 9 /* Call */) {
|
1513
1440
|
const call = node.parent.rightExpression;
|
1514
|
-
const type = this.
|
1441
|
+
const type = this.evaluator.getType(call.leftExpression);
|
1515
1442
|
if (!type || !(0, types_1.isInstantiableClass)(type) || !types_1.ClassType.isBuiltIn(type, 'dict')) {
|
1516
1443
|
continue;
|
1517
1444
|
}
|
1518
1445
|
for (const arg of call.arguments) {
|
1519
1446
|
const key = (_h = (_g = arg.name) === null || _g === void 0 ? void 0 : _g.value.trim()) !== null && _h !== void 0 ? _h : '';
|
1520
|
-
const quote = this.
|
1447
|
+
const quote = this.parseResults.tokenizerOutput.predominantSingleQuoteCharacter;
|
1521
1448
|
if (key.length > 0) {
|
1522
1449
|
keys.add(`${quote}${key}${quote}`);
|
1523
1450
|
}
|
@@ -1529,7 +1456,7 @@ class CompletionProvider {
|
|
1529
1456
|
node.parent.items[0].valueExpression.nodeType !== 0 /* Error */ &&
|
1530
1457
|
!textRange_2.TextRange.containsRange(node.parent, invocationNode)) {
|
1531
1458
|
const indexArgument = node.parent.items[0];
|
1532
|
-
const key = this.
|
1459
|
+
const key = this.parseResults.text
|
1533
1460
|
.substr(indexArgument.valueExpression.start, indexArgument.valueExpression.length)
|
1534
1461
|
.trim();
|
1535
1462
|
if (key.length > 0)
|
@@ -1539,7 +1466,7 @@ class CompletionProvider {
|
|
1539
1466
|
return [...keys];
|
1540
1467
|
}
|
1541
1468
|
_getLiteralCompletions(parseNode, offset, priorWord, priorText, postText) {
|
1542
|
-
if (this.
|
1469
|
+
if (this.options.triggerCharacter === '"' || this.options.triggerCharacter === "'") {
|
1543
1470
|
if (parseNode.start !== offset - 1) {
|
1544
1471
|
// If completion is triggered by typing " or ', it must be the one that starts a string
|
1545
1472
|
// literal. In another word, it can't be something inside of another string or comment
|
@@ -1550,7 +1477,7 @@ class CompletionProvider {
|
|
1550
1477
|
if (!this._tryAddLiterals(parseNode, priorWord, priorText, postText, completionMap)) {
|
1551
1478
|
return undefined;
|
1552
1479
|
}
|
1553
|
-
return
|
1480
|
+
return completionMap;
|
1554
1481
|
}
|
1555
1482
|
_tryAddLiterals(parseNode, priorWord, priorText, postText, completionMap) {
|
1556
1483
|
var _a, _b, _c, _d, _e, _f;
|
@@ -1568,7 +1495,7 @@ class CompletionProvider {
|
|
1568
1495
|
? parentAndChild.child
|
1569
1496
|
: undefined;
|
1570
1497
|
if (nodeForExpectedType) {
|
1571
|
-
const expectedTypeResult = this.
|
1498
|
+
const expectedTypeResult = this.evaluator.getExpectedType(nodeForExpectedType);
|
1572
1499
|
if (expectedTypeResult && (0, typeUtils_1.isLiteralTypeOrUnion)(expectedTypeResult.type)) {
|
1573
1500
|
this._addLiteralValuesForTargetType(expectedTypeResult.type, priorWord, priorText, postText, completionMap);
|
1574
1501
|
return true;
|
@@ -1637,7 +1564,7 @@ class CompletionProvider {
|
|
1637
1564
|
const comparison = parentAndChild.parent;
|
1638
1565
|
const supportedOperators = [2 /* Assign */, 12 /* Equals */, 28 /* NotEquals */];
|
1639
1566
|
if (comparison.nodeType === 7 /* BinaryOperation */ && supportedOperators.includes(comparison.operator)) {
|
1640
|
-
const type = this.
|
1567
|
+
const type = this.evaluator.getType(comparison.leftExpression);
|
1641
1568
|
if (type && (0, typeUtils_1.isLiteralTypeOrUnion)(type)) {
|
1642
1569
|
this._addLiteralValuesForTargetType(type, priorWord, priorText, postText, completionMap);
|
1643
1570
|
return true;
|
@@ -1647,7 +1574,7 @@ class CompletionProvider {
|
|
1647
1574
|
const assignmentExpression = parentAndChild.parent;
|
1648
1575
|
if (assignmentExpression.nodeType === 4 /* AssignmentExpression */ &&
|
1649
1576
|
assignmentExpression.rightExpression === parentAndChild.child) {
|
1650
|
-
const type = this.
|
1577
|
+
const type = this.evaluator.getType(assignmentExpression.name);
|
1651
1578
|
if (type && (0, typeUtils_1.isLiteralTypeOrUnion)(type)) {
|
1652
1579
|
this._addLiteralValuesForTargetType(type, priorWord, priorText, postText, completionMap);
|
1653
1580
|
return true;
|
@@ -1662,7 +1589,7 @@ class CompletionProvider {
|
|
1662
1589
|
caseNode.pattern.category === 11 /* MissingPattern */ &&
|
1663
1590
|
caseNode.suite === parentAndChild.child &&
|
1664
1591
|
((_c = caseNode.parent) === null || _c === void 0 ? void 0 : _c.nodeType) === 63 /* Match */) {
|
1665
|
-
const type = this.
|
1592
|
+
const type = this.evaluator.getType(caseNode.parent.subjectExpression);
|
1666
1593
|
if (type && (0, typeUtils_1.isLiteralTypeOrUnion)(type)) {
|
1667
1594
|
this._addLiteralValuesForTargetType(type, priorWord, priorText, postText, completionMap);
|
1668
1595
|
return true;
|
@@ -1677,14 +1604,14 @@ class CompletionProvider {
|
|
1677
1604
|
((_d = patternLiteral.parent) === null || _d === void 0 ? void 0 : _d.nodeType) === 66 /* PatternAs */ &&
|
1678
1605
|
((_e = patternLiteral.parent.parent) === null || _e === void 0 ? void 0 : _e.nodeType) === 64 /* Case */ &&
|
1679
1606
|
((_f = patternLiteral.parent.parent.parent) === null || _f === void 0 ? void 0 : _f.nodeType) === 63 /* Match */) {
|
1680
|
-
const type = this.
|
1607
|
+
const type = this.evaluator.getType(patternLiteral.parent.parent.parent.subjectExpression);
|
1681
1608
|
if (type && (0, typeUtils_1.isLiteralTypeOrUnion)(type)) {
|
1682
1609
|
this._addLiteralValuesForTargetType(type, priorWord, priorText, postText, completionMap);
|
1683
1610
|
return true;
|
1684
1611
|
}
|
1685
1612
|
}
|
1686
1613
|
if (parseNode.nodeType === 49 /* String */) {
|
1687
|
-
const offset = (0, positionUtils_1.convertPositionToOffset)(this.
|
1614
|
+
const offset = (0, positionUtils_1.convertPositionToOffset)(this.position, this.parseResults.tokenizerOutput.lines);
|
1688
1615
|
const atArgument = parseNode.parent.start < offset && offset < textRange_2.TextRange.getEnd(parseNode);
|
1689
1616
|
this._addCallArgumentCompletions(parseNode, priorWord, priorText, postText, atArgument, completionMap);
|
1690
1617
|
return true;
|
@@ -1721,7 +1648,7 @@ class CompletionProvider {
|
|
1721
1648
|
const quoteInfo = this._getQuoteInfo(priorWord, priorText);
|
1722
1649
|
const excludes = new Set(existingKeys);
|
1723
1650
|
typedDicts.forEach((typedDict) => {
|
1724
|
-
(0, typedDicts_1.getTypedDictMembersForClass)(this.
|
1651
|
+
(0, typedDicts_1.getTypedDictMembersForClass)(this.evaluator, typedDict, /* allowNarrowed */ true).forEach((_, key) => {
|
1725
1652
|
// Unions of TypedDicts may define the same key.
|
1726
1653
|
if (excludes.has(key) || completionMap.has(key)) {
|
1727
1654
|
return;
|
@@ -1734,7 +1661,7 @@ class CompletionProvider {
|
|
1734
1661
|
}
|
1735
1662
|
_tryAddTypedDictKeysFromDictionary(dictionaryNode, stringNode, priorWord, priorText, postText, completionMap) {
|
1736
1663
|
var _a;
|
1737
|
-
const expectedTypeResult = this.
|
1664
|
+
const expectedTypeResult = this.evaluator.getExpectedType(dictionaryNode);
|
1738
1665
|
if (!expectedTypeResult) {
|
1739
1666
|
return false;
|
1740
1667
|
}
|
@@ -1748,7 +1675,7 @@ class CompletionProvider {
|
|
1748
1675
|
}
|
1749
1676
|
_tryNarrowTypedDicts(types, keys) {
|
1750
1677
|
const newTypes = types.flatMap((type) => {
|
1751
|
-
const entries = (0, typedDicts_1.getTypedDictMembersForClass)(this.
|
1678
|
+
const entries = (0, typedDicts_1.getTypedDictMembersForClass)(this.evaluator, type, /* allowNarrowed */ true);
|
1752
1679
|
for (let index = 0; index < keys.length; index++) {
|
1753
1680
|
if (!entries.has(keys[index])) {
|
1754
1681
|
return [];
|
@@ -1767,7 +1694,7 @@ class CompletionProvider {
|
|
1767
1694
|
_getQuoteInfo(priorWord, priorText) {
|
1768
1695
|
let filterText = priorWord;
|
1769
1696
|
let stringValue = undefined;
|
1770
|
-
let quoteCharacter = this.
|
1697
|
+
let quoteCharacter = this.parseResults.tokenizerOutput.predominantSingleQuoteCharacter;
|
1771
1698
|
// If completion is not inside of the existing string literal
|
1772
1699
|
// ex) typedDict[ |<= here
|
1773
1700
|
// use default quotation char without any string prefix.
|
@@ -1811,7 +1738,7 @@ class CompletionProvider {
|
|
1811
1738
|
if (!indexNode) {
|
1812
1739
|
return false;
|
1813
1740
|
}
|
1814
|
-
const baseType = this.
|
1741
|
+
const baseType = this.evaluator.getType(indexNode.baseExpression);
|
1815
1742
|
if (!baseType) {
|
1816
1743
|
return false;
|
1817
1744
|
}
|
@@ -1826,7 +1753,7 @@ class CompletionProvider {
|
|
1826
1753
|
const completionItem = vscode_languageserver_1.CompletionItem.create(valueWithQuotes);
|
1827
1754
|
completionItem.kind = vscode_languageserver_1.CompletionItemKind.Constant;
|
1828
1755
|
completionItem.sortText = this._makeSortText(SortCategory.LiteralValue, valueWithQuotes);
|
1829
|
-
let rangeStartCol = this.
|
1756
|
+
let rangeStartCol = this.position.character;
|
1830
1757
|
if (quoteInfo.stringValue !== undefined) {
|
1831
1758
|
rangeStartCol -= quoteInfo.stringValue.length + 1;
|
1832
1759
|
}
|
@@ -1835,80 +1762,23 @@ class CompletionProvider {
|
|
1835
1762
|
}
|
1836
1763
|
// If the text after the insertion point is the closing quote,
|
1837
1764
|
// replace it.
|
1838
|
-
let rangeEndCol = this.
|
1765
|
+
let rangeEndCol = this.position.character;
|
1839
1766
|
if (postText !== undefined) {
|
1840
1767
|
if (postText.startsWith(quoteInfo.quoteCharacter)) {
|
1841
1768
|
rangeEndCol++;
|
1842
1769
|
}
|
1843
1770
|
}
|
1844
1771
|
const range = {
|
1845
|
-
start: { line: this.
|
1846
|
-
end: { line: this.
|
1772
|
+
start: { line: this.position.line, character: rangeStartCol },
|
1773
|
+
end: { line: this.position.line, character: rangeEndCol },
|
1847
1774
|
};
|
1848
1775
|
completionItem.textEdit = vscode_languageserver_1.TextEdit.replace(range, valueWithQuotes);
|
1849
1776
|
completionItem.detail = detail;
|
1850
1777
|
completionMap.set(completionItem);
|
1851
1778
|
}
|
1852
1779
|
}
|
1853
|
-
_addAutoImportCompletions(priorWord, similarityLimit, lazyEdit, completionResults) {
|
1854
|
-
var _a, _b, _c;
|
1855
|
-
if (!this._configOptions.autoImportCompletions || !this._options.autoImport) {
|
1856
|
-
// If auto import on the server is turned off or this particular invocation
|
1857
|
-
// is turned off (ex, notebook), don't do any thing.
|
1858
|
-
return;
|
1859
|
-
}
|
1860
|
-
const moduleSymbolMap = this._autoImportMaps.getModuleSymbolsMap();
|
1861
|
-
const autoImporter = new autoImporter_1.AutoImporter(this._execEnv, this._importResolver, this._parseResults, this._position, completionResults.completionMap, moduleSymbolMap, {
|
1862
|
-
libraryMap: this._autoImportMaps.libraryMap,
|
1863
|
-
lazyEdit,
|
1864
|
-
importFormat: this._options.importFormat,
|
1865
|
-
});
|
1866
|
-
const results = [];
|
1867
|
-
const info = (_a = this._autoImportMaps.nameMap) === null || _a === void 0 ? void 0 : _a.get(priorWord);
|
1868
|
-
if (info && priorWord.length > 1 && !completionResults.completionMap.has(priorWord)) {
|
1869
|
-
(0, collectionUtils_1.appendArray)(results, autoImporter.getAutoImportCandidatesForAbbr(priorWord, info, this._cancellationToken));
|
1870
|
-
}
|
1871
|
-
results.push(...autoImporter.getAutoImportCandidates(priorWord, similarityLimit,
|
1872
|
-
/* abbrFromUsers */ undefined, this._cancellationToken));
|
1873
|
-
const perfInfo = autoImporter.getPerfInfo();
|
1874
|
-
const additionDuration = new timing_1.Duration();
|
1875
|
-
for (const result of results) {
|
1876
|
-
if (result.symbol) {
|
1877
|
-
this._addSymbol(result.name, result.symbol, priorWord, completionResults.completionMap, {
|
1878
|
-
extraCommitChars: true,
|
1879
|
-
autoImportSource: result.source,
|
1880
|
-
autoImportAlias: result.alias,
|
1881
|
-
edits: {
|
1882
|
-
textEdit: this._createReplaceEdits(priorWord, /* node */ undefined, result.insertionText),
|
1883
|
-
additionalTextEdits: result.edits,
|
1884
|
-
},
|
1885
|
-
});
|
1886
|
-
}
|
1887
|
-
else {
|
1888
|
-
this._addNameToCompletions((_b = result.alias) !== null && _b !== void 0 ? _b : result.name, (_c = result.kind) !== null && _c !== void 0 ? _c : vscode_languageserver_1.CompletionItemKind.Module, priorWord, completionResults.completionMap, {
|
1889
|
-
extraCommitChars: true,
|
1890
|
-
autoImportText: this._getAutoImportText(result.name, result.source, result.alias),
|
1891
|
-
edits: {
|
1892
|
-
textEdit: this._createReplaceEdits(priorWord, /* node */ undefined, result.insertionText),
|
1893
|
-
additionalTextEdits: result.edits,
|
1894
|
-
},
|
1895
|
-
});
|
1896
|
-
}
|
1897
|
-
}
|
1898
|
-
completionResults.autoImportInfo = {
|
1899
|
-
indexUsed: perfInfo.indexUsed,
|
1900
|
-
totalTimeInMS: perfInfo.totalInMs,
|
1901
|
-
moduleTimeInMS: perfInfo.moduleTimeInMS,
|
1902
|
-
indexTimeInMS: perfInfo.indexTimeInMS,
|
1903
|
-
importAliasTimeInMS: perfInfo.importAliasTimeInMS,
|
1904
|
-
itemCount: results.length,
|
1905
|
-
symbolCount: perfInfo.symbolCount,
|
1906
|
-
indexCount: perfInfo.indexCount,
|
1907
|
-
importAliasCount: perfInfo.importAliasCount,
|
1908
|
-
additionTimeInMS: additionDuration.getDurationInMilliseconds(),
|
1909
|
-
};
|
1910
|
-
}
|
1911
1780
|
_getImportFromCompletions(importFromNode, priorWord) {
|
1781
|
+
var _a;
|
1912
1782
|
// Don't attempt to provide completions for "from X import *".
|
1913
1783
|
if (importFromNode.isWildcardImport) {
|
1914
1784
|
return undefined;
|
@@ -1921,16 +1791,21 @@ class CompletionProvider {
|
|
1921
1791
|
}
|
1922
1792
|
const completionMap = new CompletionMap();
|
1923
1793
|
const resolvedPath = importInfo.resolvedPaths.length > 0 ? importInfo.resolvedPaths[importInfo.resolvedPaths.length - 1] : '';
|
1924
|
-
const
|
1925
|
-
if (
|
1926
|
-
|
1927
|
-
// Don't suggest built in symbols or ones that have already been imported.
|
1928
|
-
return (symbol.getDeclarations().some((d) => !(0, declaration_1.isIntrinsicDeclaration)(d)) &&
|
1929
|
-
!importFromNode.imports.find((imp) => imp.name.value === name));
|
1930
|
-
}, priorWord, importFromNode,
|
1931
|
-
/* isInImport */ true,
|
1932
|
-
/* boundObject */ undefined, completionMap);
|
1794
|
+
const parseResults = this.program.getParseResults(resolvedPath);
|
1795
|
+
if (!parseResults) {
|
1796
|
+
return completionMap;
|
1933
1797
|
}
|
1798
|
+
const symbolTable = (_a = AnalyzerNodeInfo.getScope(parseResults.parseTree)) === null || _a === void 0 ? void 0 : _a.symbolTable;
|
1799
|
+
if (!symbolTable) {
|
1800
|
+
return completionMap;
|
1801
|
+
}
|
1802
|
+
this._addSymbolsForSymbolTable(symbolTable, (symbol, name) => {
|
1803
|
+
// Don't suggest built in symbols or ones that have already been imported.
|
1804
|
+
return (symbol.getDeclarations().some((d) => !(0, declaration_1.isIntrinsicDeclaration)(d)) &&
|
1805
|
+
!importFromNode.imports.find((imp) => imp.name.value === name));
|
1806
|
+
}, priorWord, importFromNode,
|
1807
|
+
/* isInImport */ true,
|
1808
|
+
/* boundObject */ undefined, completionMap);
|
1934
1809
|
// Add the implicit imports.
|
1935
1810
|
importInfo.implicitImports.forEach((implImport) => {
|
1936
1811
|
if (!importFromNode.imports.find((imp) => imp.name.value === implImport.name)) {
|
@@ -1939,7 +1814,7 @@ class CompletionProvider {
|
|
1939
1814
|
});
|
1940
1815
|
}
|
1941
1816
|
});
|
1942
|
-
return
|
1817
|
+
return completionMap;
|
1943
1818
|
}
|
1944
1819
|
_findMatchingKeywords(keywordList, partialMatch) {
|
1945
1820
|
return keywordList.filter((keyword) => {
|
@@ -1973,8 +1848,8 @@ class CompletionProvider {
|
|
1973
1848
|
completionItem.kind = vscode_languageserver_1.CompletionItemKind.Variable;
|
1974
1849
|
const completionItemData = {
|
1975
1850
|
workspacePath: this._workspacePath,
|
1976
|
-
filePath: this.
|
1977
|
-
position: this.
|
1851
|
+
filePath: this.filePath,
|
1852
|
+
position: this.position,
|
1978
1853
|
};
|
1979
1854
|
completionItem.data = (0, lspUtils_1.toLSPAny)(completionItemData);
|
1980
1855
|
completionItem.sortText = this._makeSortText(SortCategory.NamedParameter, argName);
|
@@ -2013,7 +1888,7 @@ class CompletionProvider {
|
|
2013
1888
|
}
|
2014
1889
|
// If this is a class scope, add symbols from parent classes.
|
2015
1890
|
if (curNode.nodeType === 10 /* Class */) {
|
2016
|
-
const classType = this.
|
1891
|
+
const classType = this.evaluator.getTypeOfClass(curNode);
|
2017
1892
|
if (classType && (0, types_1.isInstantiableClass)(classType.classType)) {
|
2018
1893
|
classType.classType.details.mro.forEach((baseClass, index) => {
|
2019
1894
|
if ((0, types_1.isInstantiableClass)(baseClass)) {
|
@@ -2045,14 +1920,14 @@ class CompletionProvider {
|
|
2045
1920
|
// exported from this scope, don't include it in the
|
2046
1921
|
// suggestion list unless we are in the same file.
|
2047
1922
|
const hidden = !(0, symbolUtils_1.isVisibleExternally)(symbol) &&
|
2048
|
-
!symbol.getDeclarations().some((d) => (0, declarationUtils_1.isDefinedInFile)(d, this.
|
1923
|
+
!symbol.getDeclarations().some((d) => (0, declarationUtils_1.isDefinedInFile)(d, this.filePath));
|
2049
1924
|
if (!hidden && includeSymbolCallback(symbol, name)) {
|
2050
1925
|
// Don't add a symbol more than once. It may have already been
|
2051
1926
|
// added from an inner scope's symbol table.
|
2052
1927
|
if (!completionMap.has(name)) {
|
2053
1928
|
// Skip func parens for classes when not a direct assignment or an argument (passed as a value)
|
2054
1929
|
const skipForClass = !this._shouldShowAutoParensForClass(symbol, node);
|
2055
|
-
this.
|
1930
|
+
this.addSymbol(name, symbol, priorWord, completionMap, {
|
2056
1931
|
boundObjectOrClass,
|
2057
1932
|
funcParensDisabled: isInImport || insideTypeAnnotation || skipForClass,
|
2058
1933
|
extraCommitChars: !isInImport && !!priorWord,
|
@@ -2072,107 +1947,23 @@ class CompletionProvider {
|
|
2072
1947
|
return true;
|
2073
1948
|
}
|
2074
1949
|
// Otherwise only show when the class is being assigned to a variable.
|
2075
|
-
const nodeIndex = ParseTreeUtils.getTokenIndexAtLeft(this.
|
2076
|
-
const prevToken = ParseTreeUtils.getTokenAtIndex(this.
|
1950
|
+
const nodeIndex = ParseTreeUtils.getTokenIndexAtLeft(this.parseResults.tokenizerOutput.tokens, node.start);
|
1951
|
+
const prevToken = ParseTreeUtils.getTokenAtIndex(this.parseResults.tokenizerOutput.tokens, nodeIndex);
|
2077
1952
|
return (prevToken &&
|
2078
1953
|
prevToken.type === 9 /* Operator */ &&
|
2079
1954
|
prevToken.operatorType === 2 /* Assign */);
|
2080
1955
|
}
|
2081
|
-
_addSymbol(name, symbol, priorWord, completionMap, detail) {
|
2082
|
-
var _a, _b, _c, _d;
|
2083
|
-
let primaryDecl = (0, symbolUtils_1.getLastTypedDeclaredForSymbol)(symbol);
|
2084
|
-
if (!primaryDecl) {
|
2085
|
-
const declarations = symbol.getDeclarations();
|
2086
|
-
if (declarations.length > 0) {
|
2087
|
-
primaryDecl = declarations[declarations.length - 1];
|
2088
|
-
}
|
2089
|
-
}
|
2090
|
-
primaryDecl = primaryDecl
|
2091
|
-
? (_a = this._evaluator.resolveAliasDeclaration(primaryDecl, /* resolveLocalNames */ true)) !== null && _a !== void 0 ? _a : primaryDecl
|
2092
|
-
: undefined;
|
2093
|
-
const autoImportText = detail.autoImportSource
|
2094
|
-
? this._getAutoImportText(name, detail.autoImportSource, detail.autoImportAlias)
|
2095
|
-
: undefined;
|
2096
|
-
// Are we resolving a completion item? If so, see if this symbol
|
2097
|
-
// is the one that we're trying to match.
|
2098
|
-
if (this._itemToResolve) {
|
2099
|
-
const completionItemData = (0, lspUtils_1.fromLSPAny)(this._itemToResolve.data);
|
2100
|
-
if (completionItemData.symbolLabel !== name) {
|
2101
|
-
// It's not what we are looking for.
|
2102
|
-
return;
|
2103
|
-
}
|
2104
|
-
if (completionItemData.autoImportText) {
|
2105
|
-
if (completionItemData.autoImportText === (autoImportText === null || autoImportText === void 0 ? void 0 : autoImportText.importText) &&
|
2106
|
-
((_b = detail.edits) === null || _b === void 0 ? void 0 : _b.additionalTextEdits)) {
|
2107
|
-
this._itemToResolve.additionalTextEdits = (0, workspaceEditUtils_1.convertToTextEdits)(detail.edits.additionalTextEdits);
|
2108
|
-
}
|
2109
|
-
return;
|
2110
|
-
}
|
2111
|
-
// This call can be expensive to perform on every completion item
|
2112
|
-
// that we return, so we do it lazily in the "resolve" callback.
|
2113
|
-
const type = this._evaluator.getEffectiveTypeOfSymbol(symbol);
|
2114
|
-
if (!type) {
|
2115
|
-
// Can't resolve. so bail out.
|
2116
|
-
return;
|
2117
|
-
}
|
2118
|
-
const typeDetail = (0, completionProviderUtils_1.getTypeDetail)(this._evaluator, primaryDecl, type, name, detail, this._configOptions.functionSignatureDisplay);
|
2119
|
-
const documentation = (0, tooltipUtils_1.getDocumentationPartsForTypeAndDecl)(this._sourceMapper, type, primaryDecl, this._evaluator, {
|
2120
|
-
name,
|
2121
|
-
symbol,
|
2122
|
-
boundObjectOrClass: detail.boundObjectOrClass,
|
2123
|
-
});
|
2124
|
-
if (this._options.format === vscode_languageserver_1.MarkupKind.Markdown || this._options.format === vscode_languageserver_1.MarkupKind.PlainText) {
|
2125
|
-
this._itemToResolve.documentation = (0, completionProviderUtils_1.getCompletionItemDocumentation)(typeDetail, documentation, this._options.format);
|
2126
|
-
}
|
2127
|
-
else {
|
2128
|
-
(0, debug_1.fail)(`Unsupported markup type: ${this._options.format}`);
|
2129
|
-
}
|
2130
|
-
// Bail out. We don't need to add items to completion.
|
2131
|
-
return;
|
2132
|
-
}
|
2133
|
-
if (primaryDecl) {
|
2134
|
-
let itemKind = this._convertDeclarationTypeToItemKind(primaryDecl);
|
2135
|
-
// Handle enum members specially. Enum members normally look like
|
2136
|
-
// variables, but the are declared using assignment expressions
|
2137
|
-
// within an enum class.
|
2138
|
-
if (primaryDecl.type === 1 /* Variable */ &&
|
2139
|
-
detail.boundObjectOrClass &&
|
2140
|
-
(0, types_1.isInstantiableClass)(detail.boundObjectOrClass) &&
|
2141
|
-
types_1.ClassType.isEnumClass(detail.boundObjectOrClass) &&
|
2142
|
-
((_c = primaryDecl.node.parent) === null || _c === void 0 ? void 0 : _c.nodeType) === 3 /* Assignment */) {
|
2143
|
-
itemKind = vscode_languageserver_1.CompletionItemKind.EnumMember;
|
2144
|
-
}
|
2145
|
-
this._addNameToCompletions((_d = detail.autoImportAlias) !== null && _d !== void 0 ? _d : name, itemKind, priorWord, completionMap, {
|
2146
|
-
autoImportText,
|
2147
|
-
extraCommitChars: detail.extraCommitChars,
|
2148
|
-
funcParensDisabled: detail.funcParensDisabled,
|
2149
|
-
edits: detail.edits,
|
2150
|
-
});
|
2151
|
-
}
|
2152
|
-
else {
|
2153
|
-
// Does the symbol have no declaration but instead has a synthesized type?
|
2154
|
-
const synthesizedType = symbol.getSynthesizedType();
|
2155
|
-
if (synthesizedType) {
|
2156
|
-
const itemKind = this._convertTypeToItemKind(synthesizedType);
|
2157
|
-
this._addNameToCompletions(name, itemKind, priorWord, completionMap, {
|
2158
|
-
extraCommitChars: detail.extraCommitChars,
|
2159
|
-
funcParensDisabled: detail.funcParensDisabled,
|
2160
|
-
edits: detail.edits,
|
2161
|
-
});
|
2162
|
-
}
|
2163
|
-
}
|
2164
|
-
}
|
2165
1956
|
_getAutoImportText(importName, importFrom, importAlias) {
|
2166
1957
|
const autoImportText = (0, tooltipUtils_1.getAutoImportText)(importName, importFrom, importAlias);
|
2167
1958
|
let importText = '';
|
2168
|
-
if (this.
|
1959
|
+
if (this.options.format === vscode_languageserver_1.MarkupKind.Markdown) {
|
2169
1960
|
importText = `\`\`\`\n${autoImportText}\n\`\`\``;
|
2170
1961
|
}
|
2171
|
-
else if (this.
|
1962
|
+
else if (this.options.format === vscode_languageserver_1.MarkupKind.PlainText) {
|
2172
1963
|
importText = autoImportText;
|
2173
1964
|
}
|
2174
1965
|
else {
|
2175
|
-
(0, debug_1.fail)(`Unsupported markup type: ${this.
|
1966
|
+
(0, debug_1.fail)(`Unsupported markup type: ${this.options.format}`);
|
2176
1967
|
}
|
2177
1968
|
return {
|
2178
1969
|
source: importFrom !== null && importFrom !== void 0 ? importFrom : '',
|
@@ -2192,14 +1983,14 @@ class CompletionProvider {
|
|
2192
1983
|
const completionItem = vscode_languageserver_1.CompletionItem.create(name);
|
2193
1984
|
completionItem.kind = itemKind;
|
2194
1985
|
if (detail === null || detail === void 0 ? void 0 : detail.extraCommitChars) {
|
2195
|
-
this.
|
1986
|
+
this.addExtraCommitChar(completionItem);
|
2196
1987
|
}
|
2197
1988
|
const completionItemData = {
|
2198
1989
|
workspacePath: this._workspacePath,
|
2199
|
-
filePath: this.
|
2200
|
-
position: this.
|
1990
|
+
filePath: this.filePath,
|
1991
|
+
position: this.position,
|
2201
1992
|
};
|
2202
|
-
if ((detail === null || detail === void 0 ? void 0 : detail.funcParensDisabled) || !this.
|
1993
|
+
if ((detail === null || detail === void 0 ? void 0 : detail.funcParensDisabled) || !this.options.snippet) {
|
2203
1994
|
completionItemData.funcParensDisabled = true;
|
2204
1995
|
}
|
2205
1996
|
if (detail === null || detail === void 0 ? void 0 : detail.modulePath) {
|
@@ -2237,7 +2028,7 @@ class CompletionProvider {
|
|
2237
2028
|
completionItem.sortText = this._makeSortText(SortCategory.NormalSymbol, name);
|
2238
2029
|
}
|
2239
2030
|
completionItemData.symbolLabel = name;
|
2240
|
-
if (this.
|
2031
|
+
if (this.options.format === vscode_languageserver_1.MarkupKind.Markdown) {
|
2241
2032
|
let markdownString = '';
|
2242
2033
|
if (detail === null || detail === void 0 ? void 0 : detail.autoImportText) {
|
2243
2034
|
markdownString += detail.autoImportText.importText;
|
@@ -2261,7 +2052,7 @@ class CompletionProvider {
|
|
2261
2052
|
};
|
2262
2053
|
}
|
2263
2054
|
}
|
2264
|
-
else if (this.
|
2055
|
+
else if (this.options.format === vscode_languageserver_1.MarkupKind.PlainText) {
|
2265
2056
|
let plainTextString = '';
|
2266
2057
|
if (detail === null || detail === void 0 ? void 0 : detail.autoImportText) {
|
2267
2058
|
plainTextString += detail.autoImportText.importText;
|
@@ -2285,7 +2076,7 @@ class CompletionProvider {
|
|
2285
2076
|
}
|
2286
2077
|
}
|
2287
2078
|
else {
|
2288
|
-
(0, debug_1.fail)(`Unsupported markup type: ${this.
|
2079
|
+
(0, debug_1.fail)(`Unsupported markup type: ${this.options.format}`);
|
2289
2080
|
}
|
2290
2081
|
if ((_b = detail === null || detail === void 0 ? void 0 : detail.edits) === null || _b === void 0 ? void 0 : _b.format) {
|
2291
2082
|
completionItem.insertTextFormat = detail.edits.format;
|
@@ -2347,7 +2138,7 @@ class CompletionProvider {
|
|
2347
2138
|
return result;
|
2348
2139
|
}
|
2349
2140
|
_convertDeclarationTypeToItemKind(declaration) {
|
2350
|
-
const resolvedDeclaration = this.
|
2141
|
+
const resolvedDeclaration = this.evaluator.resolveAliasDeclaration(declaration, /* resolveLocalNames */ true);
|
2351
2142
|
if (!resolvedDeclaration) {
|
2352
2143
|
return vscode_languageserver_1.CompletionItemKind.Variable;
|
2353
2144
|
}
|
@@ -2368,7 +2159,7 @@ class CompletionProvider {
|
|
2368
2159
|
return vscode_languageserver_1.CompletionItemKind.Variable;
|
2369
2160
|
case 5 /* Function */: {
|
2370
2161
|
if (this._isPossiblePropertyDeclaration(resolvedDeclaration)) {
|
2371
|
-
const functionType = this.
|
2162
|
+
const functionType = this.evaluator.getTypeOfFunction(resolvedDeclaration.node);
|
2372
2163
|
if (functionType &&
|
2373
2164
|
(0, typeUtils_1.isMaybeDescriptorInstance)(functionType.decoratedType, /* requireSetter */ false)) {
|
2374
2165
|
return vscode_languageserver_1.CompletionItemKind.Property;
|
@@ -2408,7 +2199,7 @@ class CompletionProvider {
|
|
2408
2199
|
nameParts: node.nameParts.map((part) => part.value),
|
2409
2200
|
importedSymbols: [],
|
2410
2201
|
};
|
2411
|
-
const completions = this.
|
2202
|
+
const completions = this.importResolver.getCompletionSuggestions(this.filePath, this.execEnv, moduleDescriptor);
|
2412
2203
|
const completionMap = new CompletionMap();
|
2413
2204
|
// If we're in the middle of a "from X import Y" statement, offer
|
2414
2205
|
// the "import" keyword as a completion.
|
@@ -2428,27 +2219,7 @@ class CompletionProvider {
|
|
2428
2219
|
modulePath,
|
2429
2220
|
});
|
2430
2221
|
});
|
2431
|
-
return
|
2432
|
-
}
|
2433
|
-
_getExtraCommitCharsForKind(kind) {
|
2434
|
-
switch (kind) {
|
2435
|
-
case vscode_languageserver_1.CompletionItemKind.Class:
|
2436
|
-
return ['.', '('];
|
2437
|
-
case vscode_languageserver_1.CompletionItemKind.Function:
|
2438
|
-
case vscode_languageserver_1.CompletionItemKind.Method:
|
2439
|
-
return ['('];
|
2440
|
-
case vscode_languageserver_1.CompletionItemKind.Module:
|
2441
|
-
case vscode_languageserver_1.CompletionItemKind.Enum:
|
2442
|
-
return ['.'];
|
2443
|
-
default:
|
2444
|
-
return [];
|
2445
|
-
}
|
2446
|
-
}
|
2447
|
-
_addExtraCommitChar(item, ...commitChars) {
|
2448
|
-
if (!this._options.extraCommitChars || commitChars.length === 0) {
|
2449
|
-
return;
|
2450
|
-
}
|
2451
|
-
item.commitCharacters = commitChars;
|
2222
|
+
return completionMap;
|
2452
2223
|
}
|
2453
2224
|
_isPossiblePropertyDeclaration(decl) {
|
2454
2225
|
// Do cheap check using only nodes that will cover 99.9% cases
|