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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. package/dist/analyzer/backgroundAnalysisProgram.d.ts +1 -1
  2. package/dist/analyzer/checker.js +37 -2
  3. package/dist/analyzer/checker.js.map +1 -1
  4. package/dist/analyzer/constraintSolver.js +14 -15
  5. package/dist/analyzer/constraintSolver.js.map +1 -1
  6. package/dist/analyzer/constructors.js +246 -189
  7. package/dist/analyzer/constructors.js.map +1 -1
  8. package/dist/analyzer/dataClasses.js +2 -2
  9. package/dist/analyzer/dataClasses.js.map +1 -1
  10. package/dist/analyzer/docStringConversion.js +1 -1
  11. package/dist/analyzer/docStringConversion.js.map +1 -1
  12. package/dist/analyzer/enums.js +8 -0
  13. package/dist/analyzer/enums.js.map +1 -1
  14. package/dist/analyzer/importResolver.js +47 -29
  15. package/dist/analyzer/importResolver.js.map +1 -1
  16. package/dist/analyzer/namedTuples.js +2 -5
  17. package/dist/analyzer/namedTuples.js.map +1 -1
  18. package/dist/analyzer/program.d.ts +7 -17
  19. package/dist/analyzer/program.js +32 -247
  20. package/dist/analyzer/program.js.map +1 -1
  21. package/dist/analyzer/protocols.js +1 -1
  22. package/dist/analyzer/protocols.js.map +1 -1
  23. package/dist/analyzer/service.d.ts +4 -12
  24. package/dist/analyzer/service.js +12 -23
  25. package/dist/analyzer/service.js.map +1 -1
  26. package/dist/analyzer/sourceFile.d.ts +2 -11
  27. package/dist/analyzer/sourceFile.js +11 -74
  28. package/dist/analyzer/sourceFile.js.map +1 -1
  29. package/dist/analyzer/symbol.d.ts +3 -1
  30. package/dist/analyzer/symbol.js +5 -0
  31. package/dist/analyzer/symbol.js.map +1 -1
  32. package/dist/analyzer/typeEvaluator.js +362 -142
  33. package/dist/analyzer/typeEvaluator.js.map +1 -1
  34. package/dist/analyzer/typeEvaluatorTypes.d.ts +4 -0
  35. package/dist/analyzer/typeEvaluatorTypes.js.map +1 -1
  36. package/dist/analyzer/typePrinter.d.ts +3 -3
  37. package/dist/analyzer/typePrinter.js +247 -100
  38. package/dist/analyzer/typePrinter.js.map +1 -1
  39. package/dist/analyzer/typeUtils.d.ts +12 -7
  40. package/dist/analyzer/typeUtils.js +173 -48
  41. package/dist/analyzer/typeUtils.js.map +1 -1
  42. package/dist/analyzer/typeVarContext.d.ts +1 -2
  43. package/dist/analyzer/typeVarContext.js +14 -32
  44. package/dist/analyzer/typeVarContext.js.map +1 -1
  45. package/dist/analyzer/types.d.ts +3 -2
  46. package/dist/analyzer/types.js +13 -10
  47. package/dist/analyzer/types.js.map +1 -1
  48. package/dist/backgroundAnalysisBase.d.ts +1 -1
  49. package/dist/backgroundAnalysisBase.js +16 -0
  50. package/dist/backgroundAnalysisBase.js.map +1 -1
  51. package/dist/commands/dumpFileDebugInfoCommand.js +0 -1
  52. package/dist/commands/dumpFileDebugInfoCommand.js.map +1 -1
  53. package/dist/common/extensibility.d.ts +26 -3
  54. package/dist/common/extensibility.js.map +1 -1
  55. package/dist/common/logTracker.d.ts +2 -0
  56. package/dist/common/logTracker.js +8 -1
  57. package/dist/common/logTracker.js.map +1 -1
  58. package/dist/common/lspUtils.d.ts +4 -1
  59. package/dist/common/lspUtils.js +38 -1
  60. package/dist/common/lspUtils.js.map +1 -1
  61. package/dist/common/pythonVersion.d.ts +2 -1
  62. package/dist/common/pythonVersion.js +1 -0
  63. package/dist/common/pythonVersion.js.map +1 -1
  64. package/dist/common/workspaceEditUtils.d.ts +3 -3
  65. package/dist/common/workspaceEditUtils.js +10 -10
  66. package/dist/common/workspaceEditUtils.js.map +1 -1
  67. package/dist/languageServerBase.d.ts +2 -5
  68. package/dist/languageServerBase.js +33 -60
  69. package/dist/languageServerBase.js.map +1 -1
  70. package/dist/languageService/autoImporter.d.ts +50 -51
  71. package/dist/languageService/autoImporter.js +125 -210
  72. package/dist/languageService/autoImporter.js.map +1 -1
  73. package/dist/languageService/callHierarchyProvider.js +6 -32
  74. package/dist/languageService/callHierarchyProvider.js.map +1 -1
  75. package/dist/languageService/completionProvider.d.ts +40 -79
  76. package/dist/languageService/completionProvider.js +571 -811
  77. package/dist/languageService/completionProvider.js.map +1 -1
  78. package/dist/languageService/documentSymbolCollector.d.ts +2 -2
  79. package/dist/languageService/documentSymbolCollector.js +33 -23
  80. package/dist/languageService/documentSymbolCollector.js.map +1 -1
  81. package/dist/languageService/documentSymbolProvider.d.ts +13 -35
  82. package/dist/languageService/documentSymbolProvider.js +52 -264
  83. package/dist/languageService/documentSymbolProvider.js.map +1 -1
  84. package/dist/languageService/hoverProvider.d.ts +1 -3
  85. package/dist/languageService/hoverProvider.js +11 -97
  86. package/dist/languageService/hoverProvider.js.map +1 -1
  87. package/dist/languageService/referencesProvider.d.ts +3 -3
  88. package/dist/languageService/referencesProvider.js +5 -7
  89. package/dist/languageService/referencesProvider.js.map +1 -1
  90. package/dist/languageService/renameProvider.d.ts +0 -1
  91. package/dist/languageService/renameProvider.js +2 -6
  92. package/dist/languageService/renameProvider.js.map +1 -1
  93. package/dist/languageService/symbolIndexer.d.ts +31 -0
  94. package/dist/languageService/symbolIndexer.js +105 -0
  95. package/dist/languageService/symbolIndexer.js.map +1 -0
  96. package/dist/languageService/tooltipUtils.d.ts +8 -1
  97. package/dist/languageService/tooltipUtils.js +102 -1
  98. package/dist/languageService/tooltipUtils.js.map +1 -1
  99. package/dist/languageService/workspaceSymbolProvider.d.ts +17 -0
  100. package/dist/languageService/workspaceSymbolProvider.js +133 -0
  101. package/dist/languageService/workspaceSymbolProvider.js.map +1 -0
  102. package/dist/localization/localize.d.ts +16 -1
  103. package/dist/localization/localize.js +9 -1
  104. package/dist/localization/localize.js.map +1 -1
  105. package/dist/localization/package.nls.en-us.json +9 -1
  106. package/dist/parser/parser.js +3 -0
  107. package/dist/parser/parser.js.map +1 -1
  108. package/dist/pyright.js +26 -4
  109. package/dist/pyright.js.map +1 -1
  110. package/dist/tests/chainedSourceFiles.test.js +15 -20
  111. package/dist/tests/chainedSourceFiles.test.js.map +1 -1
  112. package/dist/tests/checker.test.js +14 -0
  113. package/dist/tests/checker.test.js.map +1 -1
  114. package/dist/tests/completions.test.js +11 -236
  115. package/dist/tests/completions.test.js.map +1 -1
  116. package/dist/tests/docStringConversion.test.js +36 -2
  117. package/dist/tests/docStringConversion.test.js.map +1 -1
  118. package/dist/tests/fourslash/completions.override2.fourslash.js +1 -16
  119. package/dist/tests/fourslash/completions.override2.fourslash.js.map +1 -1
  120. package/dist/tests/harness/fourslash/testState.d.ts +14 -8
  121. package/dist/tests/harness/fourslash/testState.js +25 -36
  122. package/dist/tests/harness/fourslash/testState.js.map +1 -1
  123. package/dist/tests/importResolver.test.js +81 -1
  124. package/dist/tests/importResolver.test.js.map +1 -1
  125. package/dist/tests/typeEvaluator2.test.js +12 -0
  126. package/dist/tests/typeEvaluator2.test.js.map +1 -1
  127. package/dist/tests/typeEvaluator3.test.js +4 -0
  128. package/dist/tests/typeEvaluator3.test.js.map +1 -1
  129. package/dist/tests/typeEvaluator5.test.js +21 -9
  130. package/dist/tests/typeEvaluator5.test.js.map +1 -1
  131. package/dist/tests/workspaceEditUtils.test.js +15 -10
  132. package/dist/tests/workspaceEditUtils.test.js.map +1 -1
  133. package/package.json +1 -1
  134. package/dist/languageService/importAdder.d.ts +0 -40
  135. package/dist/languageService/importAdder.js +0 -388
  136. package/dist/languageService/importAdder.js.map +0 -1
  137. package/dist/tests/fourslash/completions.commitChars.fourslash.d.ts +0 -1
  138. package/dist/tests/fourslash/completions.commitChars.fourslash.js +0 -81
  139. package/dist/tests/fourslash/completions.commitChars.fourslash.js.map +0 -1
  140. package/dist/tests/importAdder.test.d.ts +0 -1
  141. package/dist/tests/importAdder.test.js +0 -1325
  142. package/dist/tests/importAdder.test.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,29 +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(_program, _workspacePath, _filePath, _position, _importLookup, _options, _autoImportMaps, _cancellationToken) {
162
- this._program = _program;
156
+ constructor(program, _workspacePath, filePath, position, options, cancellationToken) {
157
+ this.program = program;
163
158
  this._workspacePath = _workspacePath;
164
- this._filePath = _filePath;
165
- this._position = _position;
166
- this._importLookup = _importLookup;
167
- this._options = _options;
168
- this._autoImportMaps = _autoImportMaps;
169
- this._cancellationToken = _cancellationToken;
159
+ this.filePath = filePath;
160
+ this.position = position;
161
+ this.options = options;
162
+ this.cancellationToken = cancellationToken;
170
163
  // Indicate whether invocation is inside of string literal.
171
164
  this._insideStringLiteral = undefined;
172
- this._execEnv = this._configOptions.findExecEnvironment(this._filePath);
173
- this._parseResults = this._program.getParseResults(this._filePath);
174
- this._sourceMapper = this._program.getSourceMapper(this._filePath, this._cancellationToken,
175
- /* mapCompiled */ true);
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);
176
168
  }
177
- getCompletionsForPosition() {
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) {
268
+ var _a, _b;
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) {
178
546
  var _a, _b;
179
- const offset = (0, positionUtils_1.convertPositionToOffset)(this._position, this._parseResults.tokenizerOutput.lines);
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);
180
584
  if (offset === undefined) {
181
585
  return undefined;
182
586
  }
183
- const token = ParseTreeUtils.getTokenOverlapping(this._parseResults.tokenizerOutput.tokens, offset);
587
+ const token = ParseTreeUtils.getTokenOverlapping(this.parseResults.tokenizerOutput.tokens, offset);
184
588
  if ((token === null || token === void 0 ? void 0 : token.type) === 5 /* String */) {
185
589
  const stringToken = token;
186
590
  this._insideStringLiteral = textRange_2.TextRange.contains(stringToken, offset)
@@ -189,7 +593,7 @@ class CompletionProvider {
189
593
  ? stringToken
190
594
  : undefined;
191
595
  }
192
- let node = ParseTreeUtils.findNodeByOffset(this._parseResults.parseTree, offset);
596
+ let node = ParseTreeUtils.findNodeByOffset(this.parseResults.parseTree, offset);
193
597
  // See if we can get to a "better" node by backing up a few columns.
194
598
  // A "better" node is defined as one that's deeper than the current
195
599
  // node.
@@ -208,7 +612,7 @@ class CompletionProvider {
208
612
  if (curChar === ',') {
209
613
  sawComma = true;
210
614
  }
211
- const curNode = ParseTreeUtils.findNodeByOffset(this._parseResults.parseTree, curOffset);
615
+ const curNode = ParseTreeUtils.findNodeByOffset(this.parseResults.parseTree, curOffset);
212
616
  if (curNode && curNode !== initialNode) {
213
617
  if (ParseTreeUtils.getNodeDepth(curNode) > initialDepth) {
214
618
  node = curNode;
@@ -226,10 +630,10 @@ class CompletionProvider {
226
630
  return undefined;
227
631
  }
228
632
  // Get the text on that line prior to the insertion point.
229
- const lineTextRange = this._parseResults.tokenizerOutput.lines.getItemAt(this._position.line);
633
+ const lineTextRange = this.parseResults.tokenizerOutput.lines.getItemAt(this.position.line);
230
634
  const textOnLine = this._fileContents.substr(lineTextRange.start, lineTextRange.length);
231
- const priorText = textOnLine.substr(0, this._position.character);
232
- const postText = textOnLine.substr(this._position.character);
635
+ const priorText = textOnLine.substr(0, this.position.character);
636
+ const postText = textOnLine.substr(this.position.character);
233
637
  const priorWordIndex = priorText.search(/\w+$/);
234
638
  const priorWord = priorWordIndex >= 0 ? priorText.substr(priorWordIndex) : '';
235
639
  // Don't offer completions if we're within a comment.
@@ -249,7 +653,7 @@ class CompletionProvider {
249
653
  // that of its ancestors.
250
654
  let curNode = errorNode || node;
251
655
  while (true) {
252
- (0, cancellationUtils_1.throwIfCancellationRequested)(this._cancellationToken);
656
+ (0, cancellationUtils_1.throwIfCancellationRequested)(this.cancellationToken);
253
657
  if (curNode.nodeType === 49 /* String */) {
254
658
  return this._getLiteralCompletions(curNode, offset, priorWord, priorText, postText);
255
659
  }
@@ -263,13 +667,13 @@ class CompletionProvider {
263
667
  return this._getExpressionErrorCompletions(curNode, offset, priorWord, priorText, postText);
264
668
  }
265
669
  if (curNode.nodeType === 35 /* MemberAccess */) {
266
- return this._getMemberAccessCompletions(curNode.leftExpression, priorWord);
670
+ return this.getMemberAccessCompletions(curNode.leftExpression, priorWord);
267
671
  }
268
672
  if (curNode.nodeType === 15 /* Dictionary */) {
269
673
  const completionMap = new CompletionMap();
270
674
  if (this._tryAddTypedDictKeysFromDictionary(curNode,
271
675
  /* stringNode */ undefined, priorWord, priorText, postText, completionMap)) {
272
- return { completionMap };
676
+ return completionMap;
273
677
  }
274
678
  }
275
679
  const dictionaryEntry = ParseTreeUtils.getFirstAncestorOrSelfOfKind(curNode, 17 /* DictionaryKeyEntry */);
@@ -280,7 +684,7 @@ class CompletionProvider {
280
684
  const completionMap = new CompletionMap();
281
685
  if (this._tryAddTypedDictKeysFromDictionary(dictionaryNode,
282
686
  /* stringNode */ undefined, priorWord, priorText, postText, completionMap)) {
283
- return { completionMap };
687
+ return completionMap;
284
688
  }
285
689
  }
286
690
  }
@@ -294,7 +698,7 @@ class CompletionProvider {
294
698
  return result;
295
699
  }
296
700
  }
297
- if (curNode.nodeType === 31 /* List */ && this._options.triggerCharacter === '[') {
701
+ if (curNode.nodeType === 31 /* List */ && this.options.triggerCharacter === '[') {
298
702
  // If this is an empty list, don't start putting completions up yet.
299
703
  return undefined;
300
704
  }
@@ -341,84 +745,6 @@ class CompletionProvider {
341
745
  }
342
746
  return undefined;
343
747
  }
344
- // When the user selects a completion, this callback is invoked,
345
- // allowing us to record what was selected. This allows us to
346
- // build our MRU cache so we can better predict entries.
347
- resolveCompletionItem(completionItem) {
348
- (0, cancellationUtils_1.throwIfCancellationRequested)(this._cancellationToken);
349
- const completionItemData = (0, lspUtils_1.fromLSPAny)(completionItem.data);
350
- const label = completionItem.label;
351
- let autoImportText = '';
352
- if (completionItemData.autoImportText) {
353
- autoImportText = completionItemData.autoImportText;
354
- }
355
- const curIndex = CompletionProvider._mostRecentCompletions.findIndex((item) => item.label === label && item.autoImportText === autoImportText);
356
- if (curIndex > 0) {
357
- // If there's an existing entry with the same name that's not at the
358
- // beginning of the array, remove it.
359
- CompletionProvider._mostRecentCompletions = CompletionProvider._mostRecentCompletions.splice(curIndex, 1);
360
- }
361
- if (curIndex !== 0) {
362
- // Add to the start of the array.
363
- CompletionProvider._mostRecentCompletions.unshift({ label, autoImportText });
364
- }
365
- if (CompletionProvider._mostRecentCompletions.length > maxRecentCompletions) {
366
- // Prevent the MRU list from growing indefinitely.
367
- CompletionProvider._mostRecentCompletions.pop();
368
- }
369
- if (!completionItemData.symbolLabel) {
370
- return;
371
- }
372
- if (completionItemData.modulePath) {
373
- const documentation = (0, typeDocStringUtils_1.getModuleDocStringFromPaths)([completionItemData.modulePath], this._sourceMapper);
374
- if (!documentation) {
375
- return;
376
- }
377
- if (this._options.format === vscode_languageserver_1.MarkupKind.Markdown) {
378
- const markdownString = (0, docStringConversion_1.convertDocStringToMarkdown)(documentation);
379
- completionItem.documentation = {
380
- kind: vscode_languageserver_1.MarkupKind.Markdown,
381
- value: markdownString,
382
- };
383
- }
384
- else if (this._options.format === vscode_languageserver_1.MarkupKind.PlainText) {
385
- const plainTextString = (0, docStringConversion_1.convertDocStringToPlainText)(documentation);
386
- completionItem.documentation = {
387
- kind: vscode_languageserver_1.MarkupKind.PlainText,
388
- value: plainTextString,
389
- };
390
- }
391
- return;
392
- }
393
- this._itemToResolve = completionItem;
394
- if (!completionItemData.autoImportText) {
395
- // Rerun the completion lookup. It will fill in additional information
396
- // about the item to be resolved. We'll ignore the rest of the returned
397
- // list. This is a bit wasteful, but all of that information should be
398
- // cached, so it's not as bad as it might seem.
399
- this.getCompletionsForPosition();
400
- }
401
- else if (!completionItem.additionalTextEdits) {
402
- const completionMap = new CompletionMap();
403
- const completionResults = { completionMap };
404
- this._addAutoImportCompletions(completionItemData.symbolLabel,
405
- /* similarityLimit */ 1,
406
- /* lazyEdit */ false, completionResults);
407
- }
408
- }
409
- get _importResolver() {
410
- return this._program.importResolver;
411
- }
412
- get _configOptions() {
413
- return this._program.configOptions;
414
- }
415
- get _evaluator() {
416
- return this._program.evaluator;
417
- }
418
- get _fileContents() {
419
- var _a, _b;
420
- return (_b = (_a = this._parseResults) === null || _a === void 0 ? void 0 : _a.text) !== null && _b !== void 0 ? _b : '';
421
- }
422
748
  // This method will return false if it wants1
423
749
  // caller to walk up the tree. it will return
424
750
  // CompletionResults or undefined if it wants caller
@@ -463,7 +789,7 @@ class CompletionProvider {
463
789
  return false;
464
790
  }
465
791
  if (curNode.parent.nodeType === 35 /* MemberAccess */ && curNode === curNode.parent.memberName) {
466
- return this._getMemberAccessCompletions(curNode.parent.leftExpression, priorWord);
792
+ return this.getMemberAccessCompletions(curNode.parent.leftExpression, priorWord);
467
793
  }
468
794
  if (curNode.parent.nodeType === 25 /* Except */ && curNode === curNode.parent.name) {
469
795
  return undefined;
@@ -497,15 +823,15 @@ class CompletionProvider {
497
823
  if (leftNode !== curNode || priorWord.length === 0) {
498
824
  return false;
499
825
  }
500
- const decls = this._evaluator.getDeclarationsForNameNode(curNode);
826
+ const decls = this.evaluator.getDeclarationsForNameNode(curNode);
501
827
  if ((decls === null || decls === void 0 ? void 0 : decls.length) !== 1 || !(0, declaration_1.isVariableDeclaration)(decls[0]) || decls[0].node !== curNode) {
502
828
  return false;
503
829
  }
504
- const completionList = this._getExpressionCompletions(curNode, priorWord, priorText, postText);
505
- if (completionList) {
506
- completionList.completionMap.delete(curNode.value);
830
+ const completionMap = this._getExpressionCompletions(curNode, priorWord, priorText, postText);
831
+ if (completionMap) {
832
+ completionMap.delete(curNode.value);
507
833
  }
508
- return completionList;
834
+ return completionMap;
509
835
  }
510
836
  // Defining class variables.
511
837
  // ex) class A:
@@ -522,7 +848,7 @@ class CompletionProvider {
522
848
  }
523
849
  _isWithinComment(offset) {
524
850
  var _a, _b;
525
- const token = getTokenAfter(offset, this._parseResults.tokenizerOutput.tokens);
851
+ const token = getTokenAfter(offset, this.parseResults.tokenizerOutput.tokens);
526
852
  if (!token) {
527
853
  // If we're in the middle of a token, we're not in a comment.
528
854
  return false;
@@ -572,8 +898,8 @@ class CompletionProvider {
572
898
  case 7 /* MissingMemberAccessName */:
573
899
  case 2 /* MissingExpression */: {
574
900
  // Don't show completion after random dots.
575
- const tokenizerOutput = this._parseResults.tokenizerOutput;
576
- const offset = (0, positionUtils_1.convertPositionToOffset)(this._position, tokenizerOutput.lines);
901
+ const tokenizerOutput = this.parseResults.tokenizerOutput;
902
+ const offset = (0, positionUtils_1.convertPositionToOffset)(this.position, tokenizerOutput.lines);
577
903
  const index = ParseTreeUtils.getTokenIndexAtLeft(tokenizerOutput.tokens, offset);
578
904
  const token = ParseTreeUtils.getTokenAtIndex(tokenizerOutput.tokens, index);
579
905
  const prevToken = ParseTreeUtils.getTokenAtIndex(tokenizerOutput.tokens, index - 1);
@@ -598,7 +924,7 @@ class CompletionProvider {
598
924
  return this._getExpressionCompletions(node, priorWord, priorText, postText);
599
925
  }
600
926
  const previousOffset = textRange_2.TextRange.getEnd(prevToken);
601
- const previousNode = ParseTreeUtils.findNodeByOffset(this._parseResults.parseTree, previousOffset);
927
+ const previousNode = ParseTreeUtils.findNodeByOffset(this.parseResults.parseTree, previousOffset);
602
928
  if ((previousNode === null || previousNode === void 0 ? void 0 : previousNode.nodeType) !== 0 /* Error */ ||
603
929
  previousNode.category !== 7 /* MissingMemberAccessName */) {
604
930
  return this._getExpressionCompletions(node, priorWord, priorText, postText);
@@ -635,7 +961,7 @@ class CompletionProvider {
635
961
  }
636
962
  // Determine if the partial name is a method that's overriding
637
963
  // a method in a base class.
638
- return this._getMethodOverrideCompletions(priorWord, node.child, node.decorators);
964
+ return this.getMethodOverrideCompletions(priorWord, node.child, node.decorators);
639
965
  }
640
966
  break;
641
967
  }
@@ -646,13 +972,10 @@ class CompletionProvider {
646
972
  if (!node.child || !(0, parseNodes_1.isExpressionNode)(node.child)) {
647
973
  return undefined;
648
974
  }
649
- return this._getMemberAccessCompletions(node.child, priorWord);
975
+ return this.getMemberAccessCompletions(node.child, priorWord);
650
976
  }
651
977
  _isOverload(node) {
652
- return this._checkDecorator(node, 'overload');
653
- }
654
- _checkDecorator(node, value) {
655
- return node.expression.nodeType === 38 /* Name */ && node.expression.value === value;
978
+ return this.checkDecorator(node, 'overload');
656
979
  }
657
980
  _createSingleKeywordCompletion(keyword) {
658
981
  const completionItem = vscode_languageserver_1.CompletionItem.create(keyword);
@@ -660,7 +983,7 @@ class CompletionProvider {
660
983
  completionItem.sortText = this._makeSortText(SortCategory.LikelyKeyword, keyword);
661
984
  const completionMap = new CompletionMap();
662
985
  completionMap.set(completionItem);
663
- return { completionMap };
986
+ return completionMap;
664
987
  }
665
988
  _addClassVariableTypeAnnotationCompletions(priorWord, parseNode, completionMap) {
666
989
  var _a, _b, _c, _d;
@@ -679,7 +1002,7 @@ class CompletionProvider {
679
1002
  if (!enclosingClass) {
680
1003
  return;
681
1004
  }
682
- const classResults = this._evaluator.getTypeOfClass(enclosingClass);
1005
+ const classResults = this.evaluator.getTypeOfClass(enclosingClass);
683
1006
  if (!classResults) {
684
1007
  return undefined;
685
1008
  }
@@ -687,8 +1010,8 @@ class CompletionProvider {
687
1010
  const classMember = (0, typeUtils_1.lookUpClassMember)(classResults.classType, classVariableName, 8 /* SkipInstanceVariables */ | 1 /* SkipOriginalClass */);
688
1011
  // First, see whether we can use semantic info to get variable type.
689
1012
  if (classMember) {
690
- const memberType = this._evaluator.getTypeOfMember(classMember);
691
- const text = this._evaluator.printType(memberType, {
1013
+ const memberType = this.evaluator.getTypeOfMember(classMember);
1014
+ const text = this.evaluator.printType(memberType, {
692
1015
  enforcePythonSyntax: true,
693
1016
  expandTypeAlias: false,
694
1017
  });
@@ -724,7 +1047,7 @@ class CompletionProvider {
724
1047
  if (declWithTypeAnnotations.length === 0) {
725
1048
  return;
726
1049
  }
727
- const printFlags = (0, sourceMapper_1.isStubFile)(this._filePath)
1050
+ const printFlags = (0, sourceMapper_1.isStubFile)(this.filePath)
728
1051
  ? 1 /* ForwardDeclarations */ |
729
1052
  2 /* DoNotLimitStringLength */
730
1053
  : 2 /* DoNotLimitStringLength */;
@@ -738,7 +1061,7 @@ class CompletionProvider {
738
1061
  if (!enclosingClass) {
739
1062
  return undefined;
740
1063
  }
741
- const classResults = this._evaluator.getTypeOfClass(enclosingClass);
1064
+ const classResults = this.evaluator.getTypeOfClass(enclosingClass);
742
1065
  if (!classResults) {
743
1066
  return undefined;
744
1067
  }
@@ -764,13 +1087,13 @@ class CompletionProvider {
764
1087
  decls.some((d) => d.node && ParseTreeUtils.getEnclosingClass(d.node, false) === enclosingClass)) {
765
1088
  return;
766
1089
  }
767
- this._addSymbol(name, symbol, partialName.value, completionMap, {});
1090
+ this.addSymbol(name, symbol, partialName.value, completionMap, {});
768
1091
  });
769
- return completionMap.size > 0 ? { completionMap } : undefined;
1092
+ return completionMap.size > 0 ? completionMap : undefined;
770
1093
  }
771
1094
  _getMethodOverloadsCompletions(priorWord, partialName) {
772
1095
  var _a;
773
- const symbolTable = getSymbolTable(this._evaluator, partialName);
1096
+ const symbolTable = getSymbolTable(this.evaluator, partialName);
774
1097
  if (!symbolTable) {
775
1098
  return undefined;
776
1099
  }
@@ -792,14 +1115,14 @@ class CompletionProvider {
792
1115
  return;
793
1116
  }
794
1117
  if (StringUtils.isPatternInSymbol(partialName.value, name)) {
795
- const textEdit = this._createReplaceEdits(priorWord, partialName, decl.node.name.value);
796
- this._addSymbol(name, symbol, partialName.value, completionMap, {
1118
+ const textEdit = this.createReplaceEdits(priorWord, partialName, decl.node.name.value);
1119
+ this.addSymbol(name, symbol, partialName.value, completionMap, {
797
1120
  funcParensDisabled,
798
1121
  edits: { textEdit },
799
1122
  });
800
1123
  }
801
1124
  });
802
- return { completionMap };
1125
+ return completionMap;
803
1126
  function getSymbolTable(evaluator, partialName) {
804
1127
  const enclosingClass = ParseTreeUtils.getEnclosingClass(partialName, false);
805
1128
  if (enclosingClass) {
@@ -810,153 +1133,37 @@ class CompletionProvider {
810
1133
  const symbolTable = new Map();
811
1134
  for (const mroClass of classResults.classType.details.mro) {
812
1135
  if ((0, types_1.isInstantiableClass)(mroClass)) {
813
- (0, typeUtils_1.getMembersForClass)(mroClass, symbolTable, /* includeInstanceVars */ false);
814
- }
815
- }
816
- return symbolTable;
817
- }
818
- // For function overload, we only care about top level functions
819
- const moduleNode = ParseTreeUtils.getEnclosingModule(partialName);
820
- if (moduleNode) {
821
- const moduleScope = AnalyzerNodeInfo.getScope(moduleNode);
822
- return moduleScope === null || moduleScope === void 0 ? void 0 : moduleScope.symbolTable;
823
- }
824
- return undefined;
825
- }
826
- }
827
- _getMethodOverrideCompletions(priorWord, partialName, decorators) {
828
- var _a, _b;
829
- const enclosingClass = ParseTreeUtils.getEnclosingClass(partialName, /* stopAtFunction */ true);
830
- if (!enclosingClass) {
831
- return undefined;
832
- }
833
- const classResults = this._evaluator.getTypeOfClass(enclosingClass);
834
- if (!classResults) {
835
- return undefined;
836
- }
837
- const staticmethod = (_a = decorators === null || decorators === void 0 ? void 0 : decorators.some((d) => this._checkDecorator(d, 'staticmethod'))) !== null && _a !== void 0 ? _a : false;
838
- const classmethod = (_b = decorators === null || decorators === void 0 ? void 0 : decorators.some((d) => this._checkDecorator(d, 'classmethod'))) !== null && _b !== void 0 ? _b : false;
839
- const fallbackPath = (0, pythonPathUtils_1.getTypeShedFallbackPath)(this._importResolver.fileSystem);
840
- const typingFilePath = fallbackPath ? (0, pathUtils_1.combinePaths)(fallbackPath, 'stdlib/typing.pyi') : undefined;
841
- const appendMember = (map, member, name) => {
842
- if (!(0, types_1.isInstantiableClass)(member.classType) ||
843
- member.classType.details === classResults.classType.details ||
844
- !StringUtils.isPatternInSymbol(partialName.value, name)) {
845
- // Quick bail out if member is something we don't want to override.
846
- return;
847
- }
848
- const symbol = member.symbol;
849
- const decl = (0, symbolUtils_1.getLastTypedDeclaredForSymbol)(symbol);
850
- if (!decl || decl.type !== 5 /* Function */) {
851
- return;
852
- }
853
- const declaredType = this._evaluator.getTypeOfMember(member);
854
- if (!declaredType) {
855
- return;
856
- }
857
- const isDeclaredStaticMethod = (0, types_1.isFunction)(declaredType) && types_1.FunctionType.isStaticMethod(declaredType);
858
- // Special-case the "__init__subclass__" method because it's an implicit
859
- // classmethod that the type evaluator flags as a real classmethod.
860
- const isDeclaredClassMethod = (0, types_1.isFunction)(declaredType) && types_1.FunctionType.isClassMethod(declaredType) && name !== '__init_subclass__';
861
- if (staticmethod !== isDeclaredStaticMethod || classmethod !== isDeclaredClassMethod) {
862
- return;
863
- }
864
- let isProperty = (0, types_1.isClassInstance)(declaredType) && types_1.ClassType.isPropertyClass(declaredType);
865
- if (SymbolNameUtils.isDunderName(name)) {
866
- // Don't offer suggestions for built-in properties like "__class__", etc.
867
- isProperty = false;
868
- }
869
- let funcType = undefined;
870
- if ((0, types_1.isFunction)(declaredType)) {
871
- funcType = declaredType;
872
- }
873
- else if (isProperty) {
874
- const getter = (0, typeUtils_1.lookUpClassMember)(declaredType, 'fget');
875
- if (!getter) {
876
- return;
877
- }
878
- const member = this._evaluator.getTypeOfMember(getter);
879
- if (!(0, types_1.isFunction)(member)) {
880
- return;
1136
+ (0, typeUtils_1.getMembersForClass)(mroClass, symbolTable, /* includeInstanceVars */ false);
1137
+ }
881
1138
  }
882
- funcType = member;
883
- }
884
- if (!funcType || !funcType.details.declaration) {
885
- return;
1139
+ return symbolTable;
886
1140
  }
887
- const importAdder = new importAdder_1.ImportAdder(this._configOptions, this._importResolver, this._evaluator);
888
- const result = this._printMethodSignature(importAdder, classResults.classType, funcType, typingFilePath);
889
- let text;
890
- if ((0, sourceMapper_1.isStubFile)(this._filePath)) {
891
- text = `${result.methodSignature}: ...`;
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;
892
1146
  }
893
- else {
894
- const methodBody = this._printOverriddenMethodBody(classResults.classType, isDeclaredStaticMethod, isProperty, decl);
895
- text = `${result.methodSignature}:\n${methodBody}`;
896
- }
897
- const textEdit = this._createReplaceEdits(priorWord, partialName, text);
898
- // This will add new import statements, but for now, it won't add new
899
- // `TypeVar` statement such as TypeVar, TypeVarTuple, ParamSpec even if
900
- // the overridden method uses them.
901
- const additionalTextEdits = importAdder.applyImports(result.importData, this._filePath, this._parseResults, this._parseResults.parseTree.length, "absolute" /* Absolute */, this._cancellationToken);
902
- this._addSymbol(name, symbol, partialName.value, map, {
903
- // method signature already contains ()
904
- funcParensDisabled: true,
905
- edits: {
906
- format: this._options.snippet ? vscode_languageserver_1.InsertTextFormat.Snippet : undefined,
907
- textEdit,
908
- additionalTextEdits,
909
- },
910
- });
911
- };
912
- const completionMap = new CompletionMap();
913
- const classMemberMap = (0, typeUtils_1.getClassFieldsRecursive)(classResults.classType);
914
- classMemberMap.forEach((member, name) => appendMember(completionMap, member, name));
915
- if (classResults.classType.details.effectiveMetaclass &&
916
- !(0, types_1.isUnknown)(classResults.classType.details.effectiveMetaclass)) {
917
- const metaClassMemberMap = (0, typeUtils_1.getClassFieldsRecursive)(classResults.classType.details.effectiveMetaclass);
918
- metaClassMemberMap.forEach((member, name) => appendMember(completionMap, member, name));
1147
+ return undefined;
919
1148
  }
920
- return { completionMap };
921
- }
922
- _createReplaceEdits(priorWord, node, text) {
923
- const replaceOrInsertEndChar = (node === null || node === void 0 ? void 0 : node.nodeType) === 38 /* Name */
924
- ? this._position.character - priorWord.length + node.value.length
925
- : this._position.character;
926
- const range = {
927
- start: { line: this._position.line, character: this._position.character - priorWord.length },
928
- end: { line: this._position.line, character: replaceOrInsertEndChar },
929
- };
930
- return vscode_languageserver_1.TextEdit.replace(range, text);
931
1149
  }
932
- _printMethodSignature(importAdder, classType, funcType, typingFilePath) {
933
- const declaration = funcType.details.declaration;
1150
+ _printMethodSignature(classType, decl) {
1151
+ const node = decl.node;
934
1152
  let ellipsisForDefault;
935
- if ((0, sourceMapper_1.isStubFile)(this._filePath)) {
1153
+ if ((0, sourceMapper_1.isStubFile)(this.filePath)) {
936
1154
  // In stubs, always use "...".
937
1155
  ellipsisForDefault = true;
938
1156
  }
939
- else if (classType.details.moduleName === declaration.moduleName) {
1157
+ else if (classType.details.moduleName === decl.moduleName) {
940
1158
  // In the same file, always print the full default.
941
1159
  ellipsisForDefault = false;
942
1160
  }
943
- const printOptionsUsingSyntax = (0, sourceMapper_1.isStubFile)(this._filePath)
1161
+ const printFlags = (0, sourceMapper_1.isStubFile)(this.filePath)
944
1162
  ? 1 /* ForwardDeclarations */ |
945
1163
  2 /* DoNotLimitStringLength */
946
1164
  : 2 /* DoNotLimitStringLength */;
947
- const printOptionsUsingType = {
948
- enforcePythonSyntax: true,
949
- expandTypeAlias: false,
950
- omitTypeArgumentsIfUnknown: true,
951
- printUnknownWithAny: true,
952
- };
953
- const getTypeToPrint = (mainType, fallbackType) => {
954
- return mainType && (!(0, types_1.isUnknown)(mainType) || (fallbackType === null || fallbackType === void 0 ? void 0 : fallbackType.category) === 10 /* TypeVar */)
955
- ? mainType
956
- : fallbackType;
957
- };
958
- const importData = createImportData(importAdder, funcType, declaration, typingFilePath, (t) => this._sourceMapper.findClassDeclarationsByType(this._filePath, t), this._cancellationToken);
959
- const paramList = funcType.details.parameters.map((param, index) => {
1165
+ const paramList = node.parameters
1166
+ .map((param, index) => {
960
1167
  let paramString = '';
961
1168
  if (param.category === 1 /* VarArgList */) {
962
1169
  paramString += '*';
@@ -965,325 +1172,35 @@ class CompletionProvider {
965
1172
  paramString += '**';
966
1173
  }
967
1174
  if (param.name) {
968
- paramString += param.name;
969
- }
970
- if (param.typeAnnotation) {
971
- const originalType = funcType.details.parameters[index].type;
972
- const typeToPrint = getTypeToPrint(types_1.FunctionType.getEffectiveParameterType(funcType, index), originalType);
973
- // If we have actual type, then use type to generate string representation of the type, otherwise, use syntax (text).
974
- const strType = isTypeUsableForPrint(typeToPrint, originalType)
975
- ? this._evaluator.printType(typeToPrint, printOptionsUsingType)
976
- : ParseTreeUtils.printExpression(param.typeAnnotation, printOptionsUsingSyntax);
977
- paramString += ': ' + strType;
978
- }
979
- if (param.defaultValueExpression) {
980
- paramString += param.typeAnnotation ? ' = ' : '=';
981
- const useEllipsis = ellipsisForDefault !== null && ellipsisForDefault !== void 0 ? ellipsisForDefault : !isSimpleDefault(param.defaultValueExpression);
982
- paramString += useEllipsis
983
- ? '...'
984
- : ParseTreeUtils.printExpression(param.defaultValueExpression, printOptionsUsingSyntax);
985
- }
986
- if (!paramString &&
987
- !param.name &&
988
- param.category === 0 /* Simple */ &&
989
- index < funcType.details.parameters.length - 1) {
990
- return '/';
991
- }
992
- return paramString;
993
- });
994
- // Remove empty parameters at the end.
995
- for (let i = paramList.length - 1; i >= 0; i--) {
996
- if (paramList[i] !== '') {
997
- break;
998
- }
999
- paramList.pop();
1000
- }
1001
- let methodSignature = funcType.details.name + '(' + paramList.join(', ') + ')';
1002
- const strReturnType = getReturnTypeStr(this._evaluator, funcType, printOptionsUsingSyntax);
1003
- if (strReturnType) {
1004
- methodSignature += ' -> ' + strReturnType;
1005
- }
1006
- return { methodSignature, importData };
1007
- function createImportData(importAdder, funcType, declaration, typingFilePath, declarationGetter, token) {
1008
- var _a, _b;
1009
- // Handle regular case. In this case, we can get import info from
1010
- // import used in the file where the function is declared.
1011
- const ranges = [];
1012
- (0, collectionUtils_1.addIfNotNull)(ranges, textRange_2.TextRange.combine(declaration.node.parameters));
1013
- (0, collectionUtils_1.addIfNotNull)(ranges, declaration.node.returnTypeAnnotation);
1014
- (0, collectionUtils_1.addIfNotNull)(ranges, declaration.node.functionAnnotationComment);
1015
- const moduleNode = ParseTreeUtils.getModuleNode(declaration.node);
1016
- const importData = importAdder.collectImportsForSymbolsUsed(moduleNode, ranges, token);
1017
- // Handle special case where function has type arguments. In this case,
1018
- // we can't use the file the function is declared in because it doesn't
1019
- // have those type arguments. It just has the type vars.
1020
- // We could walk the mro to discover imports for the type arguments, but
1021
- // for now, instead, this creates import statement out of type arguments itself.
1022
- const effectiveTypes = [];
1023
- funcType.details.parameters.forEach((param, index) => {
1024
- if (!param.typeAnnotation) {
1025
- return;
1026
- }
1027
- const originalType = funcType.details.parameters[index].type;
1028
- if (!(0, types_1.isTypeVar)(originalType)) {
1029
- return;
1030
- }
1031
- const effectiveType = types_1.FunctionType.getEffectiveParameterType(funcType, index);
1032
- effectiveTypes.push([effectiveType, param.typeAnnotation]);
1033
- });
1034
- const node = declaration.node;
1035
- const originalType = funcType.details.declaredReturnType;
1036
- if (originalType &&
1037
- (0, types_1.isTypeVar)(originalType) &&
1038
- (node.returnTypeAnnotation || ((_a = node.functionAnnotationComment) === null || _a === void 0 ? void 0 : _a.returnTypeAnnotation))) {
1039
- effectiveTypes.push([
1040
- types_1.FunctionType.getSpecializedReturnType(funcType),
1041
- (_b = node.returnTypeAnnotation) !== null && _b !== void 0 ? _b : node.functionAnnotationComment.returnTypeAnnotation,
1042
- ]);
1043
- }
1044
- const visited = new Set();
1045
- const addImport = (t, n) => {
1046
- var _a, _b;
1047
- if (visited.has(t)) {
1048
- return;
1049
- }
1050
- visited.add(t);
1051
- // We need to special case `Any` since we can't get decl from `Any`.
1052
- if ((0, types_1.isAny)(t)) {
1053
- if (!typingFilePath) {
1054
- return;
1055
- }
1056
- importAdder.addImportInfo({ filePath: typingFilePath, nameInfo: { name: 'Any' } }, importData);
1057
- }
1058
- if (!(0, types_1.isClass)(t)) {
1059
- return;
1060
- }
1061
- // We need to special case `List`, `Dict` and `Tuple` since user might have
1062
- // used typing.List or typing.Dict in the code, but we internally already
1063
- // converted them to built-in `list` and `dict`.
1064
- // We could avoid doing this if class type holds onto decl it was created from
1065
- // if it is not synthesized like func type.
1066
- if (typingFilePath && types_1.ClassType.isBuiltIn(t)) {
1067
- const name = (_a = t.aliasName) !== null && _a !== void 0 ? _a : t.details.name;
1068
- if (t.details.moduleName === 'typing' && name) {
1069
- importAdder.addImportInfo({
1070
- filePath: typingFilePath,
1071
- nameInfo: { name },
1072
- }, importData);
1073
- }
1074
- else if (t.details.moduleName === 'builtins' && t.aliasName) {
1075
- importAdder.addImportInfo({
1076
- filePath: typingFilePath,
1077
- nameInfo: { name },
1078
- }, importData);
1079
- }
1080
- }
1081
- else {
1082
- const decls = declarationGetter(t);
1083
- if (decls.length === 0) {
1084
- return;
1085
- }
1086
- importAdder.addDeclaration(decls[0], n, importData);
1087
- }
1088
- if (t.isTypeArgumentExplicit) {
1089
- (_b = t.typeArguments) === null || _b === void 0 ? void 0 : _b.forEach((ta) => {
1090
- addImport(ta, n);
1091
- (0, typeUtils_1.doForEachSubtype)(ta, (subtype) => {
1092
- addImport(subtype, n);
1093
- });
1094
- });
1095
- }
1096
- };
1097
- effectiveTypes.forEach(([t, n]) => {
1098
- addImport(t, n);
1099
- (0, typeUtils_1.doForEachSubtype)(t, (subtype) => {
1100
- addImport(subtype, n);
1101
- });
1102
- });
1103
- return importData;
1104
- }
1105
- function getReturnTypeStr(evaluator, funcType, printFlags) {
1106
- var _a;
1107
- const originalType = funcType.details.declaredReturnType;
1108
- const typeToPrint = getTypeToPrint(types_1.FunctionType.getSpecializedReturnType(funcType), originalType);
1109
- const node = funcType.details.declaration.node;
1110
- if (!node.returnTypeAnnotation && !((_a = node.functionAnnotationComment) === null || _a === void 0 ? void 0 : _a.returnTypeAnnotation)) {
1111
- return undefined;
1112
- }
1113
- if (typeToPrint && isTypeUsableForPrint(typeToPrint, originalType)) {
1114
- return evaluator.printType(typeToPrint, printOptionsUsingType);
1115
- }
1116
- if (node.returnTypeAnnotation) {
1117
- return ParseTreeUtils.printExpression(node.returnTypeAnnotation, printFlags);
1118
- }
1119
- if (node.functionAnnotationComment) {
1120
- return ParseTreeUtils.printExpression(node.functionAnnotationComment.returnTypeAnnotation, printFlags);
1121
- }
1122
- return undefined;
1123
- }
1124
- function isTypeUsableForPrint(effectiveType, originalType) {
1125
- if (!effectiveType) {
1126
- return false;
1127
- }
1128
- // If original type was `TypeVar`, we want to use `Unknown` as `Any`
1129
- return !(0, types_1.isUnknown)(effectiveType) || (originalType === null || originalType === void 0 ? void 0 : originalType.category) === 10 /* TypeVar */;
1130
- }
1131
- function isSimpleDefault(node) {
1132
- switch (node.nodeType) {
1133
- case 40 /* Number */:
1134
- case 11 /* Constant */:
1135
- case 35 /* MemberAccess */:
1136
- return true;
1137
- case 49 /* String */:
1138
- return (node.token.flags & 64 /* Format */) === 0;
1139
- case 48 /* StringList */:
1140
- return node.strings.every(isSimpleDefault);
1141
- case 55 /* UnaryOperation */:
1142
- return isSimpleDefault(node.expression);
1143
- case 7 /* BinaryOperation */:
1144
- return isSimpleDefault(node.leftExpression) && isSimpleDefault(node.rightExpression);
1145
- default:
1146
- return false;
1147
- }
1148
- }
1149
- }
1150
- _printOverriddenMethodBody(classType, isStaticMethod, isProperty, decl) {
1151
- let sb = this._parseResults.tokenizerOutput.predominantTabSequence;
1152
- if (classType.details.baseClasses.length === 1 &&
1153
- (0, types_1.isClass)(classType.details.baseClasses[0]) &&
1154
- classType.details.baseClasses[0].details.fullName === 'builtins.object') {
1155
- sb += this._options.snippet ? '${0:pass}' : 'pass';
1156
- return sb;
1157
- }
1158
- if (decl.node.parameters.length === 0) {
1159
- sb += this._options.snippet ? '${0:pass}' : 'pass';
1160
- return sb;
1161
- }
1162
- const parameters = getParameters(isStaticMethod ? decl.node.parameters : decl.node.parameters.slice(1));
1163
- if (decl.node.name.value !== '__init__') {
1164
- sb += 'return ';
1165
- }
1166
- if (decl.node.isAsync) {
1167
- sb += 'await ';
1168
- }
1169
- if (isProperty) {
1170
- return sb + `super().${decl.node.name.value}`;
1171
- }
1172
- return sb + `super().${decl.node.name.value}(${parameters.map(convertToString).join(', ')})`;
1173
- function getParameters(parameters) {
1174
- const results = [];
1175
- let sawKeywordOnlySeparator = false;
1176
- for (const parameter of parameters) {
1177
- if (parameter.name) {
1178
- results.push([
1179
- parameter,
1180
- parameter.category === 0 /* Simple */ && !!parameter.name && sawKeywordOnlySeparator,
1181
- ]);
1182
- }
1183
- // All simple parameters after a `*` or `*args` parameter
1184
- // are considered keyword only.
1185
- if (parameter.category === 1 /* VarArgList */) {
1186
- sawKeywordOnlySeparator = true;
1187
- }
1188
- }
1189
- return results;
1190
- }
1191
- function convertToString(parameter) {
1192
- var _a;
1193
- const name = (_a = parameter[0].name) === null || _a === void 0 ? void 0 : _a.value;
1194
- if (parameter[0].category === 1 /* VarArgList */) {
1195
- return `*${name}`;
1196
- }
1197
- if (parameter[0].category === 2 /* VarArgDictionary */) {
1198
- return `**${name}`;
1175
+ paramString += param.name.value;
1199
1176
  }
1200
- return parameter[1] ? `${name}=${name}` : name;
1201
- }
1202
- }
1203
- _getMemberAccessCompletions(leftExprNode, priorWord) {
1204
- const symbolTable = new Map();
1205
- const completionMap = new CompletionMap();
1206
- let memberAccessInfo = {};
1207
- let leftType = this._evaluator.getType(leftExprNode);
1208
- if (leftType) {
1209
- leftType = this._evaluator.makeTopLevelTypeVarsConcrete(leftType);
1210
- // If this is an unknown type with a "possible type" associated with
1211
- // it, use the possible type.
1212
- if ((0, types_1.isUnknown)(leftType) && leftType.possibleType) {
1213
- leftType = this._evaluator.makeTopLevelTypeVarsConcrete(leftType.possibleType);
1214
- }
1215
- (0, typeUtils_1.doForEachSubtype)(leftType, (subtype) => {
1216
- subtype = this._evaluator.makeTopLevelTypeVarsConcrete(subtype);
1217
- if ((0, types_1.isClass)(subtype)) {
1218
- (0, typeUtils_1.getMembersForClass)(subtype, symbolTable, /* includeInstanceVars */ types_1.TypeBase.isInstance(subtype));
1219
- }
1220
- else if ((0, types_1.isModule)(subtype)) {
1221
- (0, typeUtils_1.getMembersForModule)(subtype, symbolTable);
1222
- }
1223
- else if ((0, types_1.isFunction)(subtype) || (0, types_1.isOverloadedFunction)(subtype)) {
1224
- const functionClass = this._evaluator.getBuiltInType(leftExprNode, 'function');
1225
- if (functionClass && (0, types_1.isInstantiableClass)(functionClass)) {
1226
- (0, typeUtils_1.getMembersForClass)(functionClass, symbolTable, /* includeInstanceVars */ true);
1227
- }
1228
- }
1229
- else if ((0, types_1.isNoneInstance)(subtype)) {
1230
- const objectClass = this._evaluator.getBuiltInType(leftExprNode, 'object');
1231
- if (objectClass && (0, types_1.isInstantiableClass)(objectClass)) {
1232
- (0, typeUtils_1.getMembersForClass)(objectClass, symbolTable, types_1.TypeBase.isInstance(subtype));
1233
- }
1234
- }
1235
- this._addSymbolsForSymbolTable(symbolTable, () => true, priorWord, leftExprNode,
1236
- /* isInImport */ false, (0, types_1.isClass)(subtype) ? subtype : undefined, completionMap);
1237
- });
1238
- }
1239
- // Save member access info for every request
1240
- memberAccessInfo = this._getLastKnownModule(leftExprNode, leftType);
1241
- return { completionMap, memberAccessInfo };
1242
- }
1243
- _getLastKnownModule(leftExprNode, leftType) {
1244
- var _a;
1245
- let curNode = leftExprNode;
1246
- let curType = leftType;
1247
- let unknownMemberName = leftExprNode.nodeType === 35 /* MemberAccess */ ? leftExprNode === null || leftExprNode === void 0 ? void 0 : leftExprNode.memberName.value : undefined;
1248
- // Walk left of the expression scope till we find a known type. A.B.Unknown.<-- return B.
1249
- while (curNode) {
1250
- if (curNode.nodeType === 9 /* Call */ || curNode.nodeType === 35 /* MemberAccess */) {
1251
- // Move left
1252
- curNode = curNode.leftExpression;
1253
- // First time in the loop remember the name of the unknown type.
1254
- if (unknownMemberName === undefined) {
1255
- unknownMemberName =
1256
- curNode.nodeType === 35 /* MemberAccess */ ? (_a = curNode === null || curNode === void 0 ? void 0 : curNode.memberName.value) !== null && _a !== void 0 ? _a : '' : '';
1257
- }
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);
1258
1182
  }
1259
- else {
1260
- break;
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);
1261
1187
  }
1262
- if (curNode) {
1263
- curType = this._evaluator.getType(curNode);
1264
- // Breakout if we found a known type.
1265
- if (curType !== undefined && !(0, types_1.isUnknown)(curType) && !(0, types_1.isUnbound)(curType)) {
1266
- break;
1267
- }
1188
+ if (!paramString && !param.name && param.category === 0 /* Simple */) {
1189
+ return '/';
1268
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);
1269
1197
  }
1270
- const memberAccessInfo = {};
1271
- if (curType && !(0, types_1.isUnknown)(curType) && !(0, types_1.isUnbound)(curType) && curNode) {
1272
- const moduleNamesForType = (0, typeUtils_1.getDeclaringModulesForType)(curType);
1273
- // For union types we only care about non 'typing' modules.
1274
- memberAccessInfo.lastKnownModule = moduleNamesForType.find((n) => n !== 'typing');
1275
- if (curNode.nodeType === 35 /* MemberAccess */) {
1276
- memberAccessInfo.lastKnownMemberName = curNode.memberName.value;
1277
- }
1278
- else if (curNode.nodeType === 38 /* Name */ && (0, types_1.isInstantiableClass)(curType)) {
1279
- memberAccessInfo.lastKnownMemberName = curType.details.name;
1280
- }
1281
- else if (curNode.nodeType === 38 /* Name */ && (0, types_1.isClassInstance)(curType)) {
1282
- memberAccessInfo.lastKnownMemberName = curType.details.name;
1283
- }
1284
- memberAccessInfo.unknownMemberName = unknownMemberName;
1198
+ else if (node.functionAnnotationComment) {
1199
+ methodSignature +=
1200
+ ' -> ' +
1201
+ ParseTreeUtils.printExpression(node.functionAnnotationComment.returnTypeAnnotation, printFlags);
1285
1202
  }
1286
- return memberAccessInfo;
1203
+ return methodSignature;
1287
1204
  }
1288
1205
  _getStatementCompletions(parseNode, priorWord, priorText, postText) {
1289
1206
  // For now, use the same logic for expressions and statements.
@@ -1304,10 +1221,9 @@ class CompletionProvider {
1304
1221
  return undefined;
1305
1222
  }
1306
1223
  const completionMap = new CompletionMap();
1307
- const completionResults = { completionMap };
1308
1224
  // Return empty completionList for Ellipsis
1309
1225
  if (priorText.slice(-2) === '..') {
1310
- return completionResults;
1226
+ return completionMap;
1311
1227
  }
1312
1228
  // Defining type annotation for class variables.
1313
1229
  // ex) class A:
@@ -1319,7 +1235,7 @@ class CompletionProvider {
1319
1235
  // Add symbols that are in scope.
1320
1236
  this._addSymbols(parseNode, priorWord, completionMap);
1321
1237
  // Add keywords.
1322
- this._findMatchingKeywords(Keywords.forVersion(this._execEnv.pythonVersion), priorWord).map((keyword) => {
1238
+ this._findMatchingKeywords(Keywords.forVersion(this.execEnv.pythonVersion), priorWord).map((keyword) => {
1323
1239
  if (completionMap.has(keyword)) {
1324
1240
  return;
1325
1241
  }
@@ -1331,11 +1247,11 @@ class CompletionProvider {
1331
1247
  // Add auto-import suggestions from other modules.
1332
1248
  // Ignore this check for privates, since they are not imported.
1333
1249
  if (!priorWord.startsWith('_') && !this._itemToResolve) {
1334
- this._addAutoImportCompletions(priorWord, similarityLimit, this._options.lazyEdit, completionResults);
1250
+ this.addAutoImportCompletions(priorWord, similarityLimit, this.options.lazyEdit, completionMap);
1335
1251
  }
1336
1252
  // Add literal values if appropriate.
1337
1253
  this._tryAddLiterals(parseNode, priorWord, priorText, postText, completionMap);
1338
- return completionResults;
1254
+ return completionMap;
1339
1255
  }
1340
1256
  _isIndexArgument(node) {
1341
1257
  const currentNode = node.parent;
@@ -1349,16 +1265,16 @@ class CompletionProvider {
1349
1265
  }
1350
1266
  _addCallArgumentCompletions(parseNode, priorWord, priorText, postText, atArgument, completionMap) {
1351
1267
  // If we're within the argument list of a call, add parameter names.
1352
- const offset = (0, positionUtils_1.convertPositionToOffset)(this._position, this._parseResults.tokenizerOutput.lines);
1353
- const callInfo = (0, parseTreeUtils_1.getCallNodeAndActiveParameterIndex)(parseNode, offset, this._parseResults.tokenizerOutput.tokens);
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);
1354
1270
  if (!callInfo) {
1355
1271
  return;
1356
1272
  }
1357
- const signatureInfo = this._evaluator.getCallSignatureInfo(callInfo.callNode, callInfo.activeIndex, callInfo.activeOrFake);
1273
+ const signatureInfo = this.evaluator.getCallSignatureInfo(callInfo.callNode, callInfo.activeIndex, callInfo.activeOrFake);
1358
1274
  if (signatureInfo) {
1359
1275
  // Are we past the call expression and within the argument list?
1360
- const callNameEnd = (0, positionUtils_1.convertOffsetToPosition)(signatureInfo.callNode.leftExpression.start + signatureInfo.callNode.leftExpression.length, this._parseResults.tokenizerOutput.lines);
1361
- if ((0, textRange_1.comparePositions)(this._position, callNameEnd) > 0) {
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) {
1362
1278
  if (!atArgument) {
1363
1279
  this._addNamedParameters(signatureInfo, priorWord, completionMap);
1364
1280
  }
@@ -1449,7 +1365,7 @@ class CompletionProvider {
1449
1365
  if (member === null || member === void 0 ? void 0 : member.symbol.hasDeclarations()) {
1450
1366
  const declaration = member.symbol.getDeclarations()[0];
1451
1367
  if ((0, declaration_1.isFunctionDeclaration)(declaration) && declaration.isMethod) {
1452
- const getItemType = (_b = this._evaluator.getTypeForDeclaration(declaration)) === null || _b === void 0 ? void 0 : _b.type;
1368
+ const getItemType = (_b = this.evaluator.getTypeForDeclaration(declaration)) === null || _b === void 0 ? void 0 : _b.type;
1453
1369
  if (getItemType && (0, types_1.isFunction)(getItemType) && getItemType.details.parameters.length === 2) {
1454
1370
  return getItemType.details.parameters[1].type;
1455
1371
  }
@@ -1459,7 +1375,7 @@ class CompletionProvider {
1459
1375
  }
1460
1376
  _getIndexerKeys(indexNode, invocationNode) {
1461
1377
  var _a, _b, _c, _d, _e, _f, _g, _h, _j;
1462
- const baseType = this._evaluator.getType(indexNode.baseExpression);
1378
+ const baseType = this.evaluator.getType(indexNode.baseExpression);
1463
1379
  if (!baseType || !(0, types_1.isClassInstance)(baseType)) {
1464
1380
  return [];
1465
1381
  }
@@ -1475,7 +1391,7 @@ class CompletionProvider {
1475
1391
  !types_1.ClassType.isEnumClass(v)) {
1476
1392
  return;
1477
1393
  }
1478
- keys.push((0, typePrinter_1.printLiteralValue)(v, this._parseResults.tokenizerOutput.predominantSingleQuoteCharacter));
1394
+ keys.push((0, typePrinter_1.printLiteralValue)(v, this.parseResults.tokenizerOutput.predominantSingleQuoteCharacter));
1479
1395
  });
1480
1396
  if (keys.length > 0) {
1481
1397
  return keys;
@@ -1486,13 +1402,13 @@ class CompletionProvider {
1486
1402
  return [];
1487
1403
  }
1488
1404
  // Must be local variable/parameter
1489
- const declarations = (_a = this._evaluator.getDeclarationsForNameNode(indexNode.baseExpression)) !== null && _a !== void 0 ? _a : [];
1405
+ const declarations = (_a = this.evaluator.getDeclarationsForNameNode(indexNode.baseExpression)) !== null && _a !== void 0 ? _a : [];
1490
1406
  const declaration = declarations.length > 0 ? declarations[0] : undefined;
1491
1407
  if (!declaration ||
1492
1408
  (declaration.type !== 1 /* Variable */ && declaration.type !== 2 /* Parameter */)) {
1493
1409
  return [];
1494
1410
  }
1495
- if (declaration.path !== this._filePath) {
1411
+ if (declaration.path !== this.filePath) {
1496
1412
  return [];
1497
1413
  }
1498
1414
  let startingNode = indexNode.baseExpression;
@@ -1504,7 +1420,7 @@ class CompletionProvider {
1504
1420
  startingNode = scopeRoot;
1505
1421
  }
1506
1422
  }
1507
- const results = documentSymbolCollector_1.DocumentSymbolCollector.collectFromNode(this._program, indexNode.baseExpression, this._cancellationToken, startingNode);
1423
+ const results = documentSymbolCollector_1.DocumentSymbolCollector.collectFromNode(this.program, indexNode.baseExpression, this.cancellationToken, startingNode);
1508
1424
  const keys = new Set();
1509
1425
  for (const result of results) {
1510
1426
  const node = ((_d = result.node.parent) === null || _d === void 0 ? void 0 : _d.nodeType) === 54 /* TypeAnnotation */ ? result.node.parent : result.node;
@@ -1513,7 +1429,7 @@ class CompletionProvider {
1513
1429
  if (node.parent.rightExpression.nodeType === 15 /* Dictionary */) {
1514
1430
  const dictionary = node.parent.rightExpression;
1515
1431
  for (const entry of dictionary.entries.filter((e) => e.nodeType === 17 /* DictionaryKeyEntry */)) {
1516
- const key = this._parseResults.text
1432
+ const key = this.parseResults.text
1517
1433
  .substr(entry.keyExpression.start, entry.keyExpression.length)
1518
1434
  .trim();
1519
1435
  if (key.length > 0)
@@ -1522,13 +1438,13 @@ class CompletionProvider {
1522
1438
  }
1523
1439
  if (node.parent.rightExpression.nodeType === 9 /* Call */) {
1524
1440
  const call = node.parent.rightExpression;
1525
- const type = this._evaluator.getType(call.leftExpression);
1441
+ const type = this.evaluator.getType(call.leftExpression);
1526
1442
  if (!type || !(0, types_1.isInstantiableClass)(type) || !types_1.ClassType.isBuiltIn(type, 'dict')) {
1527
1443
  continue;
1528
1444
  }
1529
1445
  for (const arg of call.arguments) {
1530
1446
  const key = (_h = (_g = arg.name) === null || _g === void 0 ? void 0 : _g.value.trim()) !== null && _h !== void 0 ? _h : '';
1531
- const quote = this._parseResults.tokenizerOutput.predominantSingleQuoteCharacter;
1447
+ const quote = this.parseResults.tokenizerOutput.predominantSingleQuoteCharacter;
1532
1448
  if (key.length > 0) {
1533
1449
  keys.add(`${quote}${key}${quote}`);
1534
1450
  }
@@ -1540,7 +1456,7 @@ class CompletionProvider {
1540
1456
  node.parent.items[0].valueExpression.nodeType !== 0 /* Error */ &&
1541
1457
  !textRange_2.TextRange.containsRange(node.parent, invocationNode)) {
1542
1458
  const indexArgument = node.parent.items[0];
1543
- const key = this._parseResults.text
1459
+ const key = this.parseResults.text
1544
1460
  .substr(indexArgument.valueExpression.start, indexArgument.valueExpression.length)
1545
1461
  .trim();
1546
1462
  if (key.length > 0)
@@ -1550,7 +1466,7 @@ class CompletionProvider {
1550
1466
  return [...keys];
1551
1467
  }
1552
1468
  _getLiteralCompletions(parseNode, offset, priorWord, priorText, postText) {
1553
- if (this._options.triggerCharacter === '"' || this._options.triggerCharacter === "'") {
1469
+ if (this.options.triggerCharacter === '"' || this.options.triggerCharacter === "'") {
1554
1470
  if (parseNode.start !== offset - 1) {
1555
1471
  // If completion is triggered by typing " or ', it must be the one that starts a string
1556
1472
  // literal. In another word, it can't be something inside of another string or comment
@@ -1561,7 +1477,7 @@ class CompletionProvider {
1561
1477
  if (!this._tryAddLiterals(parseNode, priorWord, priorText, postText, completionMap)) {
1562
1478
  return undefined;
1563
1479
  }
1564
- return { completionMap };
1480
+ return completionMap;
1565
1481
  }
1566
1482
  _tryAddLiterals(parseNode, priorWord, priorText, postText, completionMap) {
1567
1483
  var _a, _b, _c, _d, _e, _f;
@@ -1579,7 +1495,7 @@ class CompletionProvider {
1579
1495
  ? parentAndChild.child
1580
1496
  : undefined;
1581
1497
  if (nodeForExpectedType) {
1582
- const expectedTypeResult = this._evaluator.getExpectedType(nodeForExpectedType);
1498
+ const expectedTypeResult = this.evaluator.getExpectedType(nodeForExpectedType);
1583
1499
  if (expectedTypeResult && (0, typeUtils_1.isLiteralTypeOrUnion)(expectedTypeResult.type)) {
1584
1500
  this._addLiteralValuesForTargetType(expectedTypeResult.type, priorWord, priorText, postText, completionMap);
1585
1501
  return true;
@@ -1648,7 +1564,7 @@ class CompletionProvider {
1648
1564
  const comparison = parentAndChild.parent;
1649
1565
  const supportedOperators = [2 /* Assign */, 12 /* Equals */, 28 /* NotEquals */];
1650
1566
  if (comparison.nodeType === 7 /* BinaryOperation */ && supportedOperators.includes(comparison.operator)) {
1651
- const type = this._evaluator.getType(comparison.leftExpression);
1567
+ const type = this.evaluator.getType(comparison.leftExpression);
1652
1568
  if (type && (0, typeUtils_1.isLiteralTypeOrUnion)(type)) {
1653
1569
  this._addLiteralValuesForTargetType(type, priorWord, priorText, postText, completionMap);
1654
1570
  return true;
@@ -1658,7 +1574,7 @@ class CompletionProvider {
1658
1574
  const assignmentExpression = parentAndChild.parent;
1659
1575
  if (assignmentExpression.nodeType === 4 /* AssignmentExpression */ &&
1660
1576
  assignmentExpression.rightExpression === parentAndChild.child) {
1661
- const type = this._evaluator.getType(assignmentExpression.name);
1577
+ const type = this.evaluator.getType(assignmentExpression.name);
1662
1578
  if (type && (0, typeUtils_1.isLiteralTypeOrUnion)(type)) {
1663
1579
  this._addLiteralValuesForTargetType(type, priorWord, priorText, postText, completionMap);
1664
1580
  return true;
@@ -1673,7 +1589,7 @@ class CompletionProvider {
1673
1589
  caseNode.pattern.category === 11 /* MissingPattern */ &&
1674
1590
  caseNode.suite === parentAndChild.child &&
1675
1591
  ((_c = caseNode.parent) === null || _c === void 0 ? void 0 : _c.nodeType) === 63 /* Match */) {
1676
- const type = this._evaluator.getType(caseNode.parent.subjectExpression);
1592
+ const type = this.evaluator.getType(caseNode.parent.subjectExpression);
1677
1593
  if (type && (0, typeUtils_1.isLiteralTypeOrUnion)(type)) {
1678
1594
  this._addLiteralValuesForTargetType(type, priorWord, priorText, postText, completionMap);
1679
1595
  return true;
@@ -1688,14 +1604,14 @@ class CompletionProvider {
1688
1604
  ((_d = patternLiteral.parent) === null || _d === void 0 ? void 0 : _d.nodeType) === 66 /* PatternAs */ &&
1689
1605
  ((_e = patternLiteral.parent.parent) === null || _e === void 0 ? void 0 : _e.nodeType) === 64 /* Case */ &&
1690
1606
  ((_f = patternLiteral.parent.parent.parent) === null || _f === void 0 ? void 0 : _f.nodeType) === 63 /* Match */) {
1691
- const type = this._evaluator.getType(patternLiteral.parent.parent.parent.subjectExpression);
1607
+ const type = this.evaluator.getType(patternLiteral.parent.parent.parent.subjectExpression);
1692
1608
  if (type && (0, typeUtils_1.isLiteralTypeOrUnion)(type)) {
1693
1609
  this._addLiteralValuesForTargetType(type, priorWord, priorText, postText, completionMap);
1694
1610
  return true;
1695
1611
  }
1696
1612
  }
1697
1613
  if (parseNode.nodeType === 49 /* String */) {
1698
- const offset = (0, positionUtils_1.convertPositionToOffset)(this._position, this._parseResults.tokenizerOutput.lines);
1614
+ const offset = (0, positionUtils_1.convertPositionToOffset)(this.position, this.parseResults.tokenizerOutput.lines);
1699
1615
  const atArgument = parseNode.parent.start < offset && offset < textRange_2.TextRange.getEnd(parseNode);
1700
1616
  this._addCallArgumentCompletions(parseNode, priorWord, priorText, postText, atArgument, completionMap);
1701
1617
  return true;
@@ -1732,7 +1648,7 @@ class CompletionProvider {
1732
1648
  const quoteInfo = this._getQuoteInfo(priorWord, priorText);
1733
1649
  const excludes = new Set(existingKeys);
1734
1650
  typedDicts.forEach((typedDict) => {
1735
- (0, typedDicts_1.getTypedDictMembersForClass)(this._evaluator, typedDict, /* allowNarrowed */ true).forEach((_, key) => {
1651
+ (0, typedDicts_1.getTypedDictMembersForClass)(this.evaluator, typedDict, /* allowNarrowed */ true).forEach((_, key) => {
1736
1652
  // Unions of TypedDicts may define the same key.
1737
1653
  if (excludes.has(key) || completionMap.has(key)) {
1738
1654
  return;
@@ -1745,7 +1661,7 @@ class CompletionProvider {
1745
1661
  }
1746
1662
  _tryAddTypedDictKeysFromDictionary(dictionaryNode, stringNode, priorWord, priorText, postText, completionMap) {
1747
1663
  var _a;
1748
- const expectedTypeResult = this._evaluator.getExpectedType(dictionaryNode);
1664
+ const expectedTypeResult = this.evaluator.getExpectedType(dictionaryNode);
1749
1665
  if (!expectedTypeResult) {
1750
1666
  return false;
1751
1667
  }
@@ -1759,7 +1675,7 @@ class CompletionProvider {
1759
1675
  }
1760
1676
  _tryNarrowTypedDicts(types, keys) {
1761
1677
  const newTypes = types.flatMap((type) => {
1762
- const entries = (0, typedDicts_1.getTypedDictMembersForClass)(this._evaluator, type, /* allowNarrowed */ true);
1678
+ const entries = (0, typedDicts_1.getTypedDictMembersForClass)(this.evaluator, type, /* allowNarrowed */ true);
1763
1679
  for (let index = 0; index < keys.length; index++) {
1764
1680
  if (!entries.has(keys[index])) {
1765
1681
  return [];
@@ -1778,7 +1694,7 @@ class CompletionProvider {
1778
1694
  _getQuoteInfo(priorWord, priorText) {
1779
1695
  let filterText = priorWord;
1780
1696
  let stringValue = undefined;
1781
- let quoteCharacter = this._parseResults.tokenizerOutput.predominantSingleQuoteCharacter;
1697
+ let quoteCharacter = this.parseResults.tokenizerOutput.predominantSingleQuoteCharacter;
1782
1698
  // If completion is not inside of the existing string literal
1783
1699
  // ex) typedDict[ |<= here
1784
1700
  // use default quotation char without any string prefix.
@@ -1822,7 +1738,7 @@ class CompletionProvider {
1822
1738
  if (!indexNode) {
1823
1739
  return false;
1824
1740
  }
1825
- const baseType = this._evaluator.getType(indexNode.baseExpression);
1741
+ const baseType = this.evaluator.getType(indexNode.baseExpression);
1826
1742
  if (!baseType) {
1827
1743
  return false;
1828
1744
  }
@@ -1837,7 +1753,7 @@ class CompletionProvider {
1837
1753
  const completionItem = vscode_languageserver_1.CompletionItem.create(valueWithQuotes);
1838
1754
  completionItem.kind = vscode_languageserver_1.CompletionItemKind.Constant;
1839
1755
  completionItem.sortText = this._makeSortText(SortCategory.LiteralValue, valueWithQuotes);
1840
- let rangeStartCol = this._position.character;
1756
+ let rangeStartCol = this.position.character;
1841
1757
  if (quoteInfo.stringValue !== undefined) {
1842
1758
  rangeStartCol -= quoteInfo.stringValue.length + 1;
1843
1759
  }
@@ -1846,80 +1762,23 @@ class CompletionProvider {
1846
1762
  }
1847
1763
  // If the text after the insertion point is the closing quote,
1848
1764
  // replace it.
1849
- let rangeEndCol = this._position.character;
1765
+ let rangeEndCol = this.position.character;
1850
1766
  if (postText !== undefined) {
1851
1767
  if (postText.startsWith(quoteInfo.quoteCharacter)) {
1852
1768
  rangeEndCol++;
1853
1769
  }
1854
1770
  }
1855
1771
  const range = {
1856
- start: { line: this._position.line, character: rangeStartCol },
1857
- end: { line: this._position.line, character: rangeEndCol },
1772
+ start: { line: this.position.line, character: rangeStartCol },
1773
+ end: { line: this.position.line, character: rangeEndCol },
1858
1774
  };
1859
1775
  completionItem.textEdit = vscode_languageserver_1.TextEdit.replace(range, valueWithQuotes);
1860
1776
  completionItem.detail = detail;
1861
1777
  completionMap.set(completionItem);
1862
1778
  }
1863
1779
  }
1864
- _addAutoImportCompletions(priorWord, similarityLimit, lazyEdit, completionResults) {
1865
- var _a, _b, _c;
1866
- if (!this._configOptions.autoImportCompletions || !this._options.autoImport) {
1867
- // If auto import on the server is turned off or this particular invocation
1868
- // is turned off (ex, notebook), don't do any thing.
1869
- return;
1870
- }
1871
- const moduleSymbolMap = this._autoImportMaps.getModuleSymbolsMap();
1872
- const autoImporter = new autoImporter_1.AutoImporter(this._execEnv, this._importResolver, this._parseResults, this._position, completionResults.completionMap, moduleSymbolMap, {
1873
- libraryMap: this._autoImportMaps.libraryMap,
1874
- lazyEdit,
1875
- importFormat: this._options.importFormat,
1876
- });
1877
- const results = [];
1878
- const info = (_a = this._autoImportMaps.nameMap) === null || _a === void 0 ? void 0 : _a.get(priorWord);
1879
- if (info && priorWord.length > 1 && !completionResults.completionMap.has(priorWord)) {
1880
- (0, collectionUtils_1.appendArray)(results, autoImporter.getAutoImportCandidatesForAbbr(priorWord, info, this._cancellationToken));
1881
- }
1882
- results.push(...autoImporter.getAutoImportCandidates(priorWord, similarityLimit,
1883
- /* abbrFromUsers */ undefined, this._cancellationToken));
1884
- const perfInfo = autoImporter.getPerfInfo();
1885
- const additionDuration = new timing_1.Duration();
1886
- for (const result of results) {
1887
- if (result.symbol) {
1888
- this._addSymbol(result.name, result.symbol, priorWord, completionResults.completionMap, {
1889
- extraCommitChars: true,
1890
- autoImportSource: result.source,
1891
- autoImportAlias: result.alias,
1892
- edits: {
1893
- textEdit: this._createReplaceEdits(priorWord, /* node */ undefined, result.insertionText),
1894
- additionalTextEdits: result.edits,
1895
- },
1896
- });
1897
- }
1898
- else {
1899
- 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, {
1900
- extraCommitChars: true,
1901
- autoImportText: this._getAutoImportText(result.name, result.source, result.alias),
1902
- edits: {
1903
- textEdit: this._createReplaceEdits(priorWord, /* node */ undefined, result.insertionText),
1904
- additionalTextEdits: result.edits,
1905
- },
1906
- });
1907
- }
1908
- }
1909
- completionResults.autoImportInfo = {
1910
- indexUsed: perfInfo.indexUsed,
1911
- totalTimeInMS: perfInfo.totalInMs,
1912
- moduleTimeInMS: perfInfo.moduleTimeInMS,
1913
- indexTimeInMS: perfInfo.indexTimeInMS,
1914
- importAliasTimeInMS: perfInfo.importAliasTimeInMS,
1915
- itemCount: results.length,
1916
- symbolCount: perfInfo.symbolCount,
1917
- indexCount: perfInfo.indexCount,
1918
- importAliasCount: perfInfo.importAliasCount,
1919
- additionTimeInMS: additionDuration.getDurationInMilliseconds(),
1920
- };
1921
- }
1922
1780
  _getImportFromCompletions(importFromNode, priorWord) {
1781
+ var _a;
1923
1782
  // Don't attempt to provide completions for "from X import *".
1924
1783
  if (importFromNode.isWildcardImport) {
1925
1784
  return undefined;
@@ -1932,16 +1791,21 @@ class CompletionProvider {
1932
1791
  }
1933
1792
  const completionMap = new CompletionMap();
1934
1793
  const resolvedPath = importInfo.resolvedPaths.length > 0 ? importInfo.resolvedPaths[importInfo.resolvedPaths.length - 1] : '';
1935
- const lookupResults = this._importLookup(resolvedPath);
1936
- if (lookupResults) {
1937
- this._addSymbolsForSymbolTable(lookupResults.symbolTable, (symbol, name) => {
1938
- // Don't suggest built in symbols or ones that have already been imported.
1939
- return (symbol.getDeclarations().some((d) => !(0, declaration_1.isIntrinsicDeclaration)(d)) &&
1940
- !importFromNode.imports.find((imp) => imp.name.value === name));
1941
- }, priorWord, importFromNode,
1942
- /* isInImport */ true,
1943
- /* boundObject */ undefined, completionMap);
1794
+ const parseResults = this.program.getParseResults(resolvedPath);
1795
+ if (!parseResults) {
1796
+ return completionMap;
1944
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);
1945
1809
  // Add the implicit imports.
1946
1810
  importInfo.implicitImports.forEach((implImport) => {
1947
1811
  if (!importFromNode.imports.find((imp) => imp.name.value === implImport.name)) {
@@ -1950,7 +1814,7 @@ class CompletionProvider {
1950
1814
  });
1951
1815
  }
1952
1816
  });
1953
- return { completionMap };
1817
+ return completionMap;
1954
1818
  }
1955
1819
  _findMatchingKeywords(keywordList, partialMatch) {
1956
1820
  return keywordList.filter((keyword) => {
@@ -1984,8 +1848,8 @@ class CompletionProvider {
1984
1848
  completionItem.kind = vscode_languageserver_1.CompletionItemKind.Variable;
1985
1849
  const completionItemData = {
1986
1850
  workspacePath: this._workspacePath,
1987
- filePath: this._filePath,
1988
- position: this._position,
1851
+ filePath: this.filePath,
1852
+ position: this.position,
1989
1853
  };
1990
1854
  completionItem.data = (0, lspUtils_1.toLSPAny)(completionItemData);
1991
1855
  completionItem.sortText = this._makeSortText(SortCategory.NamedParameter, argName);
@@ -2024,7 +1888,7 @@ class CompletionProvider {
2024
1888
  }
2025
1889
  // If this is a class scope, add symbols from parent classes.
2026
1890
  if (curNode.nodeType === 10 /* Class */) {
2027
- const classType = this._evaluator.getTypeOfClass(curNode);
1891
+ const classType = this.evaluator.getTypeOfClass(curNode);
2028
1892
  if (classType && (0, types_1.isInstantiableClass)(classType.classType)) {
2029
1893
  classType.classType.details.mro.forEach((baseClass, index) => {
2030
1894
  if ((0, types_1.isInstantiableClass)(baseClass)) {
@@ -2056,14 +1920,14 @@ class CompletionProvider {
2056
1920
  // exported from this scope, don't include it in the
2057
1921
  // suggestion list unless we are in the same file.
2058
1922
  const hidden = !(0, symbolUtils_1.isVisibleExternally)(symbol) &&
2059
- !symbol.getDeclarations().some((d) => (0, declarationUtils_1.isDefinedInFile)(d, this._filePath));
1923
+ !symbol.getDeclarations().some((d) => (0, declarationUtils_1.isDefinedInFile)(d, this.filePath));
2060
1924
  if (!hidden && includeSymbolCallback(symbol, name)) {
2061
1925
  // Don't add a symbol more than once. It may have already been
2062
1926
  // added from an inner scope's symbol table.
2063
1927
  if (!completionMap.has(name)) {
2064
1928
  // Skip func parens for classes when not a direct assignment or an argument (passed as a value)
2065
1929
  const skipForClass = !this._shouldShowAutoParensForClass(symbol, node);
2066
- this._addSymbol(name, symbol, priorWord, completionMap, {
1930
+ this.addSymbol(name, symbol, priorWord, completionMap, {
2067
1931
  boundObjectOrClass,
2068
1932
  funcParensDisabled: isInImport || insideTypeAnnotation || skipForClass,
2069
1933
  extraCommitChars: !isInImport && !!priorWord,
@@ -2083,107 +1947,23 @@ class CompletionProvider {
2083
1947
  return true;
2084
1948
  }
2085
1949
  // Otherwise only show when the class is being assigned to a variable.
2086
- const nodeIndex = ParseTreeUtils.getTokenIndexAtLeft(this._parseResults.tokenizerOutput.tokens, node.start);
2087
- const prevToken = ParseTreeUtils.getTokenAtIndex(this._parseResults.tokenizerOutput.tokens, nodeIndex);
1950
+ const nodeIndex = ParseTreeUtils.getTokenIndexAtLeft(this.parseResults.tokenizerOutput.tokens, node.start);
1951
+ const prevToken = ParseTreeUtils.getTokenAtIndex(this.parseResults.tokenizerOutput.tokens, nodeIndex);
2088
1952
  return (prevToken &&
2089
1953
  prevToken.type === 9 /* Operator */ &&
2090
1954
  prevToken.operatorType === 2 /* Assign */);
2091
1955
  }
2092
- _addSymbol(name, symbol, priorWord, completionMap, detail) {
2093
- var _a, _b, _c, _d;
2094
- let primaryDecl = (0, symbolUtils_1.getLastTypedDeclaredForSymbol)(symbol);
2095
- if (!primaryDecl) {
2096
- const declarations = symbol.getDeclarations();
2097
- if (declarations.length > 0) {
2098
- primaryDecl = declarations[declarations.length - 1];
2099
- }
2100
- }
2101
- primaryDecl = primaryDecl
2102
- ? (_a = this._evaluator.resolveAliasDeclaration(primaryDecl, /* resolveLocalNames */ true)) !== null && _a !== void 0 ? _a : primaryDecl
2103
- : undefined;
2104
- const autoImportText = detail.autoImportSource
2105
- ? this._getAutoImportText(name, detail.autoImportSource, detail.autoImportAlias)
2106
- : undefined;
2107
- // Are we resolving a completion item? If so, see if this symbol
2108
- // is the one that we're trying to match.
2109
- if (this._itemToResolve) {
2110
- const completionItemData = (0, lspUtils_1.fromLSPAny)(this._itemToResolve.data);
2111
- if (completionItemData.symbolLabel !== name) {
2112
- // It's not what we are looking for.
2113
- return;
2114
- }
2115
- if (completionItemData.autoImportText) {
2116
- if (completionItemData.autoImportText === (autoImportText === null || autoImportText === void 0 ? void 0 : autoImportText.importText) &&
2117
- ((_b = detail.edits) === null || _b === void 0 ? void 0 : _b.additionalTextEdits)) {
2118
- this._itemToResolve.additionalTextEdits = (0, workspaceEditUtils_1.convertToTextEdits)(detail.edits.additionalTextEdits);
2119
- }
2120
- return;
2121
- }
2122
- // This call can be expensive to perform on every completion item
2123
- // that we return, so we do it lazily in the "resolve" callback.
2124
- const type = this._evaluator.getEffectiveTypeOfSymbol(symbol);
2125
- if (!type) {
2126
- // Can't resolve. so bail out.
2127
- return;
2128
- }
2129
- const typeDetail = (0, completionProviderUtils_1.getTypeDetail)(this._evaluator, primaryDecl, type, name, detail, this._configOptions.functionSignatureDisplay);
2130
- const documentation = (0, tooltipUtils_1.getDocumentationPartsForTypeAndDecl)(this._sourceMapper, type, primaryDecl, this._evaluator, {
2131
- name,
2132
- symbol,
2133
- boundObjectOrClass: detail.boundObjectOrClass,
2134
- });
2135
- if (this._options.format === vscode_languageserver_1.MarkupKind.Markdown || this._options.format === vscode_languageserver_1.MarkupKind.PlainText) {
2136
- this._itemToResolve.documentation = (0, completionProviderUtils_1.getCompletionItemDocumentation)(typeDetail, documentation, this._options.format);
2137
- }
2138
- else {
2139
- (0, debug_1.fail)(`Unsupported markup type: ${this._options.format}`);
2140
- }
2141
- // Bail out. We don't need to add items to completion.
2142
- return;
2143
- }
2144
- if (primaryDecl) {
2145
- let itemKind = this._convertDeclarationTypeToItemKind(primaryDecl);
2146
- // Handle enum members specially. Enum members normally look like
2147
- // variables, but the are declared using assignment expressions
2148
- // within an enum class.
2149
- if (primaryDecl.type === 1 /* Variable */ &&
2150
- detail.boundObjectOrClass &&
2151
- (0, types_1.isInstantiableClass)(detail.boundObjectOrClass) &&
2152
- types_1.ClassType.isEnumClass(detail.boundObjectOrClass) &&
2153
- ((_c = primaryDecl.node.parent) === null || _c === void 0 ? void 0 : _c.nodeType) === 3 /* Assignment */) {
2154
- itemKind = vscode_languageserver_1.CompletionItemKind.EnumMember;
2155
- }
2156
- this._addNameToCompletions((_d = detail.autoImportAlias) !== null && _d !== void 0 ? _d : name, itemKind, priorWord, completionMap, {
2157
- autoImportText,
2158
- extraCommitChars: detail.extraCommitChars,
2159
- funcParensDisabled: detail.funcParensDisabled,
2160
- edits: detail.edits,
2161
- });
2162
- }
2163
- else {
2164
- // Does the symbol have no declaration but instead has a synthesized type?
2165
- const synthesizedType = symbol.getSynthesizedType();
2166
- if (synthesizedType) {
2167
- const itemKind = this._convertTypeToItemKind(synthesizedType);
2168
- this._addNameToCompletions(name, itemKind, priorWord, completionMap, {
2169
- extraCommitChars: detail.extraCommitChars,
2170
- funcParensDisabled: detail.funcParensDisabled,
2171
- edits: detail.edits,
2172
- });
2173
- }
2174
- }
2175
- }
2176
1956
  _getAutoImportText(importName, importFrom, importAlias) {
2177
1957
  const autoImportText = (0, tooltipUtils_1.getAutoImportText)(importName, importFrom, importAlias);
2178
1958
  let importText = '';
2179
- if (this._options.format === vscode_languageserver_1.MarkupKind.Markdown) {
1959
+ if (this.options.format === vscode_languageserver_1.MarkupKind.Markdown) {
2180
1960
  importText = `\`\`\`\n${autoImportText}\n\`\`\``;
2181
1961
  }
2182
- else if (this._options.format === vscode_languageserver_1.MarkupKind.PlainText) {
1962
+ else if (this.options.format === vscode_languageserver_1.MarkupKind.PlainText) {
2183
1963
  importText = autoImportText;
2184
1964
  }
2185
1965
  else {
2186
- (0, debug_1.fail)(`Unsupported markup type: ${this._options.format}`);
1966
+ (0, debug_1.fail)(`Unsupported markup type: ${this.options.format}`);
2187
1967
  }
2188
1968
  return {
2189
1969
  source: importFrom !== null && importFrom !== void 0 ? importFrom : '',
@@ -2203,14 +1983,14 @@ class CompletionProvider {
2203
1983
  const completionItem = vscode_languageserver_1.CompletionItem.create(name);
2204
1984
  completionItem.kind = itemKind;
2205
1985
  if (detail === null || detail === void 0 ? void 0 : detail.extraCommitChars) {
2206
- this._addExtraCommitChar(completionItem, ...this._getExtraCommitCharsForKind(itemKind));
1986
+ this.addExtraCommitChar(completionItem);
2207
1987
  }
2208
1988
  const completionItemData = {
2209
1989
  workspacePath: this._workspacePath,
2210
- filePath: this._filePath,
2211
- position: this._position,
1990
+ filePath: this.filePath,
1991
+ position: this.position,
2212
1992
  };
2213
- if ((detail === null || detail === void 0 ? void 0 : detail.funcParensDisabled) || !this._options.snippet) {
1993
+ if ((detail === null || detail === void 0 ? void 0 : detail.funcParensDisabled) || !this.options.snippet) {
2214
1994
  completionItemData.funcParensDisabled = true;
2215
1995
  }
2216
1996
  if (detail === null || detail === void 0 ? void 0 : detail.modulePath) {
@@ -2248,7 +2028,7 @@ class CompletionProvider {
2248
2028
  completionItem.sortText = this._makeSortText(SortCategory.NormalSymbol, name);
2249
2029
  }
2250
2030
  completionItemData.symbolLabel = name;
2251
- if (this._options.format === vscode_languageserver_1.MarkupKind.Markdown) {
2031
+ if (this.options.format === vscode_languageserver_1.MarkupKind.Markdown) {
2252
2032
  let markdownString = '';
2253
2033
  if (detail === null || detail === void 0 ? void 0 : detail.autoImportText) {
2254
2034
  markdownString += detail.autoImportText.importText;
@@ -2272,7 +2052,7 @@ class CompletionProvider {
2272
2052
  };
2273
2053
  }
2274
2054
  }
2275
- else if (this._options.format === vscode_languageserver_1.MarkupKind.PlainText) {
2055
+ else if (this.options.format === vscode_languageserver_1.MarkupKind.PlainText) {
2276
2056
  let plainTextString = '';
2277
2057
  if (detail === null || detail === void 0 ? void 0 : detail.autoImportText) {
2278
2058
  plainTextString += detail.autoImportText.importText;
@@ -2296,7 +2076,7 @@ class CompletionProvider {
2296
2076
  }
2297
2077
  }
2298
2078
  else {
2299
- (0, debug_1.fail)(`Unsupported markup type: ${this._options.format}`);
2079
+ (0, debug_1.fail)(`Unsupported markup type: ${this.options.format}`);
2300
2080
  }
2301
2081
  if ((_b = detail === null || detail === void 0 ? void 0 : detail.edits) === null || _b === void 0 ? void 0 : _b.format) {
2302
2082
  completionItem.insertTextFormat = detail.edits.format;
@@ -2358,7 +2138,7 @@ class CompletionProvider {
2358
2138
  return result;
2359
2139
  }
2360
2140
  _convertDeclarationTypeToItemKind(declaration) {
2361
- const resolvedDeclaration = this._evaluator.resolveAliasDeclaration(declaration, /* resolveLocalNames */ true);
2141
+ const resolvedDeclaration = this.evaluator.resolveAliasDeclaration(declaration, /* resolveLocalNames */ true);
2362
2142
  if (!resolvedDeclaration) {
2363
2143
  return vscode_languageserver_1.CompletionItemKind.Variable;
2364
2144
  }
@@ -2379,7 +2159,7 @@ class CompletionProvider {
2379
2159
  return vscode_languageserver_1.CompletionItemKind.Variable;
2380
2160
  case 5 /* Function */: {
2381
2161
  if (this._isPossiblePropertyDeclaration(resolvedDeclaration)) {
2382
- const functionType = this._evaluator.getTypeOfFunction(resolvedDeclaration.node);
2162
+ const functionType = this.evaluator.getTypeOfFunction(resolvedDeclaration.node);
2383
2163
  if (functionType &&
2384
2164
  (0, typeUtils_1.isMaybeDescriptorInstance)(functionType.decoratedType, /* requireSetter */ false)) {
2385
2165
  return vscode_languageserver_1.CompletionItemKind.Property;
@@ -2419,7 +2199,7 @@ class CompletionProvider {
2419
2199
  nameParts: node.nameParts.map((part) => part.value),
2420
2200
  importedSymbols: [],
2421
2201
  };
2422
- const completions = this._importResolver.getCompletionSuggestions(this._filePath, this._execEnv, moduleDescriptor);
2202
+ const completions = this.importResolver.getCompletionSuggestions(this.filePath, this.execEnv, moduleDescriptor);
2423
2203
  const completionMap = new CompletionMap();
2424
2204
  // If we're in the middle of a "from X import Y" statement, offer
2425
2205
  // the "import" keyword as a completion.
@@ -2439,27 +2219,7 @@ class CompletionProvider {
2439
2219
  modulePath,
2440
2220
  });
2441
2221
  });
2442
- return { completionMap };
2443
- }
2444
- _getExtraCommitCharsForKind(kind) {
2445
- switch (kind) {
2446
- case vscode_languageserver_1.CompletionItemKind.Class:
2447
- return ['.', '('];
2448
- case vscode_languageserver_1.CompletionItemKind.Function:
2449
- case vscode_languageserver_1.CompletionItemKind.Method:
2450
- return ['('];
2451
- case vscode_languageserver_1.CompletionItemKind.Module:
2452
- case vscode_languageserver_1.CompletionItemKind.Enum:
2453
- return ['.'];
2454
- default:
2455
- return [];
2456
- }
2457
- }
2458
- _addExtraCommitChar(item, ...commitChars) {
2459
- if (!this._options.extraCommitChars || commitChars.length === 0) {
2460
- return;
2461
- }
2462
- item.commitCharacters = commitChars;
2222
+ return completionMap;
2463
2223
  }
2464
2224
  _isPossiblePropertyDeclaration(decl) {
2465
2225
  // Do cheap check using only nodes that will cover 99.9% cases