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

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 (210) hide show
  1. package/dist/analyzer/analyzerFileInfo.d.ts +1 -0
  2. package/dist/analyzer/analyzerFileInfo.js +4 -3
  3. package/dist/analyzer/analyzerFileInfo.js.map +1 -1
  4. package/dist/analyzer/backgroundAnalysisProgram.d.ts +17 -15
  5. package/dist/analyzer/backgroundAnalysisProgram.js +43 -53
  6. package/dist/analyzer/backgroundAnalysisProgram.js.map +1 -1
  7. package/dist/analyzer/binder.d.ts +0 -2
  8. package/dist/analyzer/binder.js +2 -20
  9. package/dist/analyzer/binder.js.map +1 -1
  10. package/dist/analyzer/checker.d.ts +1 -1
  11. package/dist/analyzer/checker.js +97 -29
  12. package/dist/analyzer/checker.js.map +1 -1
  13. package/dist/analyzer/constraintSolver.js +14 -15
  14. package/dist/analyzer/constraintSolver.js.map +1 -1
  15. package/dist/analyzer/constructorTransform.js +5 -1
  16. package/dist/analyzer/constructorTransform.js.map +1 -1
  17. package/dist/analyzer/constructors.js +248 -189
  18. package/dist/analyzer/constructors.js.map +1 -1
  19. package/dist/analyzer/dataClasses.js +5 -2
  20. package/dist/analyzer/dataClasses.js.map +1 -1
  21. package/dist/analyzer/declarationUtils.js +1 -0
  22. package/dist/analyzer/declarationUtils.js.map +1 -1
  23. package/dist/analyzer/docStringConversion.js +1 -1
  24. package/dist/analyzer/docStringConversion.js.map +1 -1
  25. package/dist/analyzer/enums.js +8 -0
  26. package/dist/analyzer/enums.js.map +1 -1
  27. package/dist/analyzer/importResolver.d.ts +4 -4
  28. package/dist/analyzer/importResolver.js +93 -69
  29. package/dist/analyzer/importResolver.js.map +1 -1
  30. package/dist/analyzer/importResult.d.ts +2 -2
  31. package/dist/analyzer/importStatementUtils.js +2 -2
  32. package/dist/analyzer/importStatementUtils.js.map +1 -1
  33. package/dist/analyzer/namedTuples.js +2 -5
  34. package/dist/analyzer/namedTuples.js.map +1 -1
  35. package/dist/analyzer/packageTypeVerifier.js +1 -1
  36. package/dist/analyzer/packageTypeVerifier.js.map +1 -1
  37. package/dist/analyzer/parseTreeUtils.js +2 -34
  38. package/dist/analyzer/parseTreeUtils.js.map +1 -1
  39. package/dist/analyzer/parseTreeWalker.js +2 -2
  40. package/dist/analyzer/parseTreeWalker.js.map +1 -1
  41. package/dist/analyzer/patternMatching.js +1 -0
  42. package/dist/analyzer/patternMatching.js.map +1 -1
  43. package/dist/analyzer/program.d.ts +18 -34
  44. package/dist/analyzer/program.js +57 -259
  45. package/dist/analyzer/program.js.map +1 -1
  46. package/dist/analyzer/protocols.js +4 -2
  47. package/dist/analyzer/protocols.js.map +1 -1
  48. package/dist/analyzer/service.d.ts +8 -16
  49. package/dist/analyzer/service.js +33 -47
  50. package/dist/analyzer/service.js.map +1 -1
  51. package/dist/analyzer/sourceFile.d.ts +1 -15
  52. package/dist/analyzer/sourceFile.js +14 -96
  53. package/dist/analyzer/sourceFile.js.map +1 -1
  54. package/dist/analyzer/sourceMapper.js +1 -1
  55. package/dist/analyzer/sourceMapper.js.map +1 -1
  56. package/dist/analyzer/symbol.d.ts +3 -1
  57. package/dist/analyzer/symbol.js +5 -0
  58. package/dist/analyzer/symbol.js.map +1 -1
  59. package/dist/analyzer/typeDocStringUtils.js +1 -1
  60. package/dist/analyzer/typeDocStringUtils.js.map +1 -1
  61. package/dist/analyzer/typeEvaluator.d.ts +2 -2
  62. package/dist/analyzer/typeEvaluator.js +495 -196
  63. package/dist/analyzer/typeEvaluator.js.map +1 -1
  64. package/dist/analyzer/typeEvaluatorTypes.d.ts +7 -2
  65. package/dist/analyzer/typeEvaluatorTypes.js.map +1 -1
  66. package/dist/analyzer/typeGuards.js +1 -0
  67. package/dist/analyzer/typeGuards.js.map +1 -1
  68. package/dist/analyzer/typePrinter.d.ts +3 -3
  69. package/dist/analyzer/typePrinter.js +255 -101
  70. package/dist/analyzer/typePrinter.js.map +1 -1
  71. package/dist/analyzer/typeUtils.d.ts +12 -7
  72. package/dist/analyzer/typeUtils.js +174 -49
  73. package/dist/analyzer/typeUtils.js.map +1 -1
  74. package/dist/analyzer/typeVarContext.d.ts +1 -2
  75. package/dist/analyzer/typeVarContext.js +16 -34
  76. package/dist/analyzer/typeVarContext.js.map +1 -1
  77. package/dist/analyzer/typedDicts.js +138 -41
  78. package/dist/analyzer/typedDicts.js.map +1 -1
  79. package/dist/analyzer/types.d.ts +10 -3
  80. package/dist/analyzer/types.js +32 -16
  81. package/dist/analyzer/types.js.map +1 -1
  82. package/dist/backgroundAnalysisBase.d.ts +25 -19
  83. package/dist/backgroundAnalysisBase.js +161 -115
  84. package/dist/backgroundAnalysisBase.js.map +1 -1
  85. package/dist/backgroundThreadBase.d.ts +1 -1
  86. package/dist/backgroundThreadBase.js +1 -1
  87. package/dist/backgroundThreadBase.js.map +1 -1
  88. package/dist/commands/dumpFileDebugInfoCommand.js +3 -4
  89. package/dist/commands/dumpFileDebugInfoCommand.js.map +1 -1
  90. package/dist/common/configOptions.js +1 -1
  91. package/dist/common/configOptions.js.map +1 -1
  92. package/dist/common/extensibility.d.ts +26 -5
  93. package/dist/common/extensibility.js.map +1 -1
  94. package/dist/common/logTracker.d.ts +2 -0
  95. package/dist/common/logTracker.js +8 -1
  96. package/dist/common/logTracker.js.map +1 -1
  97. package/dist/common/lspUtils.d.ts +4 -1
  98. package/dist/common/lspUtils.js +38 -1
  99. package/dist/common/lspUtils.js.map +1 -1
  100. package/dist/common/pythonVersion.d.ts +2 -1
  101. package/dist/common/pythonVersion.js +1 -0
  102. package/dist/common/pythonVersion.js.map +1 -1
  103. package/dist/common/textRange.js +1 -1
  104. package/dist/common/textRange.js.map +1 -1
  105. package/dist/common/workspaceEditUtils.d.ts +3 -3
  106. package/dist/common/workspaceEditUtils.js +15 -17
  107. package/dist/common/workspaceEditUtils.js.map +1 -1
  108. package/dist/languageServerBase.d.ts +2 -5
  109. package/dist/languageServerBase.js +35 -62
  110. package/dist/languageServerBase.js.map +1 -1
  111. package/dist/languageService/autoImporter.d.ts +51 -52
  112. package/dist/languageService/autoImporter.js +126 -211
  113. package/dist/languageService/autoImporter.js.map +1 -1
  114. package/dist/languageService/callHierarchyProvider.js +8 -33
  115. package/dist/languageService/callHierarchyProvider.js.map +1 -1
  116. package/dist/languageService/completionProvider.d.ts +42 -81
  117. package/dist/languageService/completionProvider.js +608 -841
  118. package/dist/languageService/completionProvider.js.map +1 -1
  119. package/dist/languageService/documentSymbolCollector.d.ts +2 -2
  120. package/dist/languageService/documentSymbolCollector.js +40 -30
  121. package/dist/languageService/documentSymbolCollector.js.map +1 -1
  122. package/dist/languageService/documentSymbolProvider.d.ts +13 -35
  123. package/dist/languageService/documentSymbolProvider.js +52 -264
  124. package/dist/languageService/documentSymbolProvider.js.map +1 -1
  125. package/dist/languageService/hoverProvider.d.ts +1 -3
  126. package/dist/languageService/hoverProvider.js +11 -97
  127. package/dist/languageService/hoverProvider.js.map +1 -1
  128. package/dist/languageService/referencesProvider.d.ts +3 -3
  129. package/dist/languageService/referencesProvider.js +6 -8
  130. package/dist/languageService/referencesProvider.js.map +1 -1
  131. package/dist/languageService/renameProvider.d.ts +0 -1
  132. package/dist/languageService/renameProvider.js +2 -6
  133. package/dist/languageService/renameProvider.js.map +1 -1
  134. package/dist/languageService/signatureHelpProvider.js +1 -1
  135. package/dist/languageService/signatureHelpProvider.js.map +1 -1
  136. package/dist/languageService/symbolIndexer.d.ts +23 -0
  137. package/dist/languageService/symbolIndexer.js +105 -0
  138. package/dist/languageService/symbolIndexer.js.map +1 -0
  139. package/dist/languageService/tooltipUtils.d.ts +8 -1
  140. package/dist/languageService/tooltipUtils.js +102 -1
  141. package/dist/languageService/tooltipUtils.js.map +1 -1
  142. package/dist/languageService/workspaceSymbolProvider.d.ts +17 -0
  143. package/dist/languageService/workspaceSymbolProvider.js +133 -0
  144. package/dist/languageService/workspaceSymbolProvider.js.map +1 -0
  145. package/dist/localization/localize.d.ts +38 -4
  146. package/dist/localization/localize.js +21 -4
  147. package/dist/localization/localize.js.map +1 -1
  148. package/dist/localization/package.nls.en-us.json +23 -6
  149. package/dist/parser/parseNodes.d.ts +8 -8
  150. package/dist/parser/parseNodes.js +20 -10
  151. package/dist/parser/parseNodes.js.map +1 -1
  152. package/dist/parser/parser.d.ts +3 -3
  153. package/dist/parser/parser.js +136 -159
  154. package/dist/parser/parser.js.map +1 -1
  155. package/dist/parser/stringTokenUtils.d.ts +3 -13
  156. package/dist/parser/stringTokenUtils.js +8 -181
  157. package/dist/parser/stringTokenUtils.js.map +1 -1
  158. package/dist/parser/tokenizer.d.ts +3 -0
  159. package/dist/parser/tokenizer.js +211 -24
  160. package/dist/parser/tokenizer.js.map +1 -1
  161. package/dist/parser/tokenizerTypes.d.ts +31 -1
  162. package/dist/parser/tokenizerTypes.js +51 -1
  163. package/dist/parser/tokenizerTypes.js.map +1 -1
  164. package/dist/pyright.js +26 -4
  165. package/dist/pyright.js.map +1 -1
  166. package/dist/readonlyAugmentedFileSystem.js +1 -1
  167. package/dist/readonlyAugmentedFileSystem.js.map +1 -1
  168. package/dist/tests/chainedSourceFiles.test.js +15 -20
  169. package/dist/tests/chainedSourceFiles.test.js.map +1 -1
  170. package/dist/tests/checker.test.js +14 -0
  171. package/dist/tests/checker.test.js.map +1 -1
  172. package/dist/tests/completions.test.js +11 -236
  173. package/dist/tests/completions.test.js.map +1 -1
  174. package/dist/tests/docStringConversion.test.js +36 -2
  175. package/dist/tests/docStringConversion.test.js.map +1 -1
  176. package/dist/tests/fourslash/completions.override2.fourslash.js +1 -16
  177. package/dist/tests/fourslash/completions.override2.fourslash.js.map +1 -1
  178. package/dist/tests/harness/fourslash/testLanguageService.js +1 -1
  179. package/dist/tests/harness/fourslash/testLanguageService.js.map +1 -1
  180. package/dist/tests/harness/fourslash/testState.d.ts +14 -8
  181. package/dist/tests/harness/fourslash/testState.js +27 -37
  182. package/dist/tests/harness/fourslash/testState.js.map +1 -1
  183. package/dist/tests/importResolver.test.js +84 -4
  184. package/dist/tests/importResolver.test.js.map +1 -1
  185. package/dist/tests/textRange.test.js +45 -0
  186. package/dist/tests/textRange.test.js.map +1 -0
  187. package/dist/tests/tokenizer.test.js +272 -58
  188. package/dist/tests/tokenizer.test.js.map +1 -1
  189. package/dist/tests/typeEvaluator2.test.js +16 -0
  190. package/dist/tests/typeEvaluator2.test.js.map +1 -1
  191. package/dist/tests/typeEvaluator3.test.js +14 -0
  192. package/dist/tests/typeEvaluator3.test.js.map +1 -1
  193. package/dist/tests/typeEvaluator4.test.js +7 -2
  194. package/dist/tests/typeEvaluator4.test.js.map +1 -1
  195. package/dist/tests/typeEvaluator5.test.js +29 -9
  196. package/dist/tests/typeEvaluator5.test.js.map +1 -1
  197. package/dist/tests/workspaceEditUtils.test.js +15 -10
  198. package/dist/tests/workspaceEditUtils.test.js.map +1 -1
  199. package/dist/workspaceFactory.js +3 -5
  200. package/dist/workspaceFactory.js.map +1 -1
  201. package/package.json +1 -1
  202. package/dist/languageService/importAdder.d.ts +0 -40
  203. package/dist/languageService/importAdder.js +0 -388
  204. package/dist/languageService/importAdder.js.map +0 -1
  205. package/dist/tests/fourslash/completions.commitChars.fourslash.d.ts +0 -1
  206. package/dist/tests/fourslash/completions.commitChars.fourslash.js +0 -81
  207. package/dist/tests/fourslash/completions.commitChars.fourslash.js.map +0 -1
  208. package/dist/tests/importAdder.test.js +0 -1325
  209. package/dist/tests/importAdder.test.js.map +0 -1
  210. /package/dist/tests/{importAdder.test.d.ts → textRange.test.d.ts} +0 -0
@@ -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"));
@@ -52,19 +51,15 @@ const collectionUtils_1 = require("../common/collectionUtils");
52
51
  const debug = __importStar(require("../common/debug"));
53
52
  const debug_1 = require("../common/debug");
54
53
  const lspUtils_1 = require("../common/lspUtils");
55
- const pathUtils_1 = require("../common/pathUtils");
56
54
  const positionUtils_1 = require("../common/positionUtils");
57
55
  const pythonVersion_1 = require("../common/pythonVersion");
58
56
  const StringUtils = __importStar(require("../common/stringUtils"));
59
57
  const textRange_1 = require("../common/textRange");
60
- 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,38 +153,455 @@ 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;
170
- // Indicate whether invocation is inside of string literal.
171
- 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);
176
- }
177
- getCompletionsForPosition() {
159
+ this.filePath = filePath;
160
+ this.position = position;
161
+ this.options = options;
162
+ this.cancellationToken = cancellationToken;
163
+ // Indicates whether invocation position is inside of string literal
164
+ // token or an f-string expression.
165
+ this._stringLiteralContainer = undefined;
166
+ this.execEnv = this.configOptions.findExecEnvironment(this.filePath);
167
+ this.parseResults = this.program.getParseResults(this.filePath);
168
+ this.sourceMapper = this.program.getSourceMapper(this.filePath, this.cancellationToken, /* mapCompiled */ true);
169
+ }
170
+ getCompletions() {
171
+ if (!this.program.getSourceFileInfo(this.filePath)) {
172
+ return null;
173
+ }
174
+ const completionMap = this._getCompletions();
175
+ return vscode_languageserver_1.CompletionList.create(completionMap === null || completionMap === void 0 ? void 0 : completionMap.toArray());
176
+ }
177
+ // When the user selects a completion, this callback is invoked,
178
+ // allowing us to record what was selected. This allows us to
179
+ // build our MRU cache so we can better predict entries.
180
+ resolveCompletionItem(completionItem) {
181
+ (0, cancellationUtils_1.throwIfCancellationRequested)(this.cancellationToken);
182
+ const completionItemData = (0, lspUtils_1.fromLSPAny)(completionItem.data);
183
+ const label = completionItem.label;
184
+ let autoImportText = '';
185
+ if (completionItemData.autoImportText) {
186
+ autoImportText = completionItemData.autoImportText;
187
+ }
188
+ const curIndex = CompletionProvider._mostRecentCompletions.findIndex((item) => item.label === label && item.autoImportText === autoImportText);
189
+ if (curIndex > 0) {
190
+ // If there's an existing entry with the same name that's not at the
191
+ // beginning of the array, remove it.
192
+ CompletionProvider._mostRecentCompletions = CompletionProvider._mostRecentCompletions.splice(curIndex, 1);
193
+ }
194
+ if (curIndex !== 0) {
195
+ // Add to the start of the array.
196
+ CompletionProvider._mostRecentCompletions.unshift({ label, autoImportText });
197
+ }
198
+ if (CompletionProvider._mostRecentCompletions.length > maxRecentCompletions) {
199
+ // Prevent the MRU list from growing indefinitely.
200
+ CompletionProvider._mostRecentCompletions.pop();
201
+ }
202
+ if (!completionItemData.symbolLabel) {
203
+ return;
204
+ }
205
+ if (completionItemData.modulePath) {
206
+ const documentation = (0, typeDocStringUtils_1.getModuleDocStringFromPaths)([completionItemData.modulePath], this.sourceMapper);
207
+ if (!documentation) {
208
+ return;
209
+ }
210
+ if (this.options.format === vscode_languageserver_1.MarkupKind.Markdown) {
211
+ const markdownString = (0, docStringConversion_1.convertDocStringToMarkdown)(documentation);
212
+ completionItem.documentation = {
213
+ kind: vscode_languageserver_1.MarkupKind.Markdown,
214
+ value: markdownString,
215
+ };
216
+ }
217
+ else if (this.options.format === vscode_languageserver_1.MarkupKind.PlainText) {
218
+ const plainTextString = (0, docStringConversion_1.convertDocStringToPlainText)(documentation);
219
+ completionItem.documentation = {
220
+ kind: vscode_languageserver_1.MarkupKind.PlainText,
221
+ value: plainTextString,
222
+ };
223
+ }
224
+ return;
225
+ }
226
+ this._itemToResolve = completionItem;
227
+ if (!completionItemData.autoImportText) {
228
+ // Rerun the completion lookup. It will fill in additional information
229
+ // about the item to be resolved. We'll ignore the rest of the returned
230
+ // list. This is a bit wasteful, but all of that information should be
231
+ // cached, so it's not as bad as it might seem.
232
+ this.getCompletions();
233
+ }
234
+ else if (!completionItem.additionalTextEdits) {
235
+ const completionMap = new CompletionMap();
236
+ this.addAutoImportCompletions(completionItemData.symbolLabel,
237
+ /* similarityLimit */ 1,
238
+ /* lazyEdit */ false, completionMap);
239
+ }
240
+ }
241
+ get evaluator() {
242
+ return this.program.evaluator;
243
+ }
244
+ get importResolver() {
245
+ return this.program.importResolver;
246
+ }
247
+ get configOptions() {
248
+ return this.program.configOptions;
249
+ }
250
+ isSimpleDefault(node) {
251
+ switch (node.nodeType) {
252
+ case 40 /* Number */:
253
+ case 11 /* Constant */:
254
+ case 35 /* MemberAccess */:
255
+ return true;
256
+ case 49 /* String */:
257
+ return (node.token.flags & 64 /* Format */) === 0;
258
+ case 48 /* StringList */:
259
+ return node.strings.every(this.isSimpleDefault);
260
+ case 55 /* UnaryOperation */:
261
+ return this.isSimpleDefault(node.expression);
262
+ case 7 /* BinaryOperation */:
263
+ return this.isSimpleDefault(node.leftExpression) && this.isSimpleDefault(node.rightExpression);
264
+ default:
265
+ return false;
266
+ }
267
+ }
268
+ getMethodOverrideCompletions(priorWord, partialName, decorators) {
269
+ var _a, _b;
270
+ const enclosingClass = ParseTreeUtils.getEnclosingClass(partialName, /* stopAtFunction */ true);
271
+ if (!enclosingClass) {
272
+ return undefined;
273
+ }
274
+ const classResults = this.evaluator.getTypeOfClass(enclosingClass);
275
+ if (!classResults) {
276
+ return undefined;
277
+ }
278
+ const symbolTable = new Map();
279
+ for (let i = 1; i < classResults.classType.details.mro.length; i++) {
280
+ const mroClass = classResults.classType.details.mro[i];
281
+ if ((0, types_1.isInstantiableClass)(mroClass)) {
282
+ (0, typeUtils_1.getMembersForClass)(mroClass, symbolTable, /* includeInstanceVars */ false);
283
+ }
284
+ }
285
+ const staticmethod = (_a = decorators === null || decorators === void 0 ? void 0 : decorators.some((d) => this.checkDecorator(d, 'staticmethod'))) !== null && _a !== void 0 ? _a : false;
286
+ const classmethod = (_b = decorators === null || decorators === void 0 ? void 0 : decorators.some((d) => this.checkDecorator(d, 'classmethod'))) !== null && _b !== void 0 ? _b : false;
287
+ const completionMap = new CompletionMap();
288
+ symbolTable.forEach((symbol, name) => {
289
+ var _a;
290
+ let decl = (0, symbolUtils_1.getLastTypedDeclaredForSymbol)(symbol);
291
+ if (decl && decl.type === 5 /* Function */) {
292
+ if (StringUtils.isPatternInSymbol(partialName.value, name)) {
293
+ const declaredType = (_a = this.evaluator.getTypeForDeclaration(decl)) === null || _a === void 0 ? void 0 : _a.type;
294
+ if (!declaredType) {
295
+ return;
296
+ }
297
+ let isProperty = (0, types_1.isClassInstance)(declaredType) && types_1.ClassType.isPropertyClass(declaredType);
298
+ if (SymbolNameUtils.isDunderName(name)) {
299
+ // Don't offer suggestions for built-in properties like "__class__", etc.
300
+ isProperty = false;
301
+ }
302
+ if (!(0, types_1.isFunction)(declaredType) && !isProperty) {
303
+ return;
304
+ }
305
+ if (isProperty) {
306
+ // For properties, we should override the "getter", which is typically
307
+ // the first declaration.
308
+ const typedDecls = symbol.getTypedDeclarations();
309
+ if (typedDecls.length > 0 && typedDecls[0].type === 5 /* Function */) {
310
+ decl = typedDecls[0];
311
+ }
312
+ }
313
+ const isDeclaredStaticMethod = (0, types_1.isFunction)(declaredType) && types_1.FunctionType.isStaticMethod(declaredType);
314
+ // Special-case the "__init__subclass__" method because it's an implicit
315
+ // classmethod that the type evaluator flags as a real classmethod.
316
+ const isDeclaredClassMethod = (0, types_1.isFunction)(declaredType) &&
317
+ types_1.FunctionType.isClassMethod(declaredType) &&
318
+ name !== '__init_subclass__';
319
+ if (staticmethod !== isDeclaredStaticMethod || classmethod !== isDeclaredClassMethod) {
320
+ return;
321
+ }
322
+ const methodSignature = this._printMethodSignature(classResults.classType, decl);
323
+ let text;
324
+ if ((0, sourceMapper_1.isStubFile)(this.filePath)) {
325
+ text = `${methodSignature}: ...`;
326
+ }
327
+ else {
328
+ const methodBody = this.printOverriddenMethodBody(classResults.classType, isDeclaredStaticMethod, isProperty, decl);
329
+ text = `${methodSignature}:\n${methodBody}`;
330
+ }
331
+ const textEdit = this.createReplaceEdits(priorWord, partialName, text);
332
+ this.addSymbol(name, symbol, partialName.value, completionMap, {
333
+ // method signature already contains ()
334
+ funcParensDisabled: true,
335
+ edits: {
336
+ format: this.options.snippet ? vscode_languageserver_1.InsertTextFormat.Snippet : undefined,
337
+ textEdit,
338
+ },
339
+ });
340
+ }
341
+ }
342
+ });
343
+ return completionMap;
344
+ }
345
+ printOverriddenMethodBody(classType, isStaticMethod, isProperty, decl) {
346
+ let sb = this.parseResults.tokenizerOutput.predominantTabSequence;
347
+ if (classType.details.baseClasses.length === 1 &&
348
+ (0, types_1.isClass)(classType.details.baseClasses[0]) &&
349
+ classType.details.baseClasses[0].details.fullName === 'builtins.object') {
350
+ sb += this.options.snippet ? '${0:pass}' : 'pass';
351
+ return sb;
352
+ }
353
+ if (decl.node.parameters.length === 0) {
354
+ sb += this.options.snippet ? '${0:pass}' : 'pass';
355
+ return sb;
356
+ }
357
+ const parameters = getParameters(isStaticMethod ? decl.node.parameters : decl.node.parameters.slice(1));
358
+ if (decl.node.name.value !== '__init__') {
359
+ sb += 'return ';
360
+ }
361
+ if (decl.node.isAsync) {
362
+ sb += 'await ';
363
+ }
364
+ if (isProperty) {
365
+ return sb + `super().${decl.node.name.value}`;
366
+ }
367
+ return sb + `super().${decl.node.name.value}(${parameters.map(convertToString).join(', ')})`;
368
+ function getParameters(parameters) {
369
+ const results = [];
370
+ let sawKeywordOnlySeparator = false;
371
+ for (const parameter of parameters) {
372
+ if (parameter.name) {
373
+ results.push([
374
+ parameter,
375
+ parameter.category === 0 /* Simple */ && !!parameter.name && sawKeywordOnlySeparator,
376
+ ]);
377
+ }
378
+ // All simple parameters after a `*` or `*args` parameter
379
+ // are considered keyword only.
380
+ if (parameter.category === 1 /* VarArgList */) {
381
+ sawKeywordOnlySeparator = true;
382
+ }
383
+ }
384
+ return results;
385
+ }
386
+ function convertToString(parameter) {
387
+ var _a;
388
+ const name = (_a = parameter[0].name) === null || _a === void 0 ? void 0 : _a.value;
389
+ if (parameter[0].category === 1 /* VarArgList */) {
390
+ return `*${name}`;
391
+ }
392
+ if (parameter[0].category === 2 /* VarArgDictionary */) {
393
+ return `**${name}`;
394
+ }
395
+ return parameter[1] ? `${name}=${name}` : name;
396
+ }
397
+ }
398
+ createReplaceEdits(priorWord, node, text) {
399
+ const replaceOrInsertEndChar = (node === null || node === void 0 ? void 0 : node.nodeType) === 38 /* Name */
400
+ ? this.position.character - priorWord.length + node.value.length
401
+ : this.position.character;
402
+ const range = {
403
+ start: { line: this.position.line, character: this.position.character - priorWord.length },
404
+ end: { line: this.position.line, character: replaceOrInsertEndChar },
405
+ };
406
+ return vscode_languageserver_1.TextEdit.replace(range, text);
407
+ }
408
+ addSymbol(name, symbol, priorWord, completionMap, detail) {
409
+ var _a, _b, _c, _d;
410
+ let primaryDecl = (0, symbolUtils_1.getLastTypedDeclaredForSymbol)(symbol);
411
+ if (!primaryDecl) {
412
+ const declarations = symbol.getDeclarations();
413
+ if (declarations.length > 0) {
414
+ primaryDecl = declarations[declarations.length - 1];
415
+ }
416
+ }
417
+ primaryDecl = primaryDecl
418
+ ? (_a = this.evaluator.resolveAliasDeclaration(primaryDecl, /* resolveLocalNames */ true)) !== null && _a !== void 0 ? _a : primaryDecl
419
+ : undefined;
420
+ const autoImportText = detail.autoImportSource
421
+ ? this._getAutoImportText(name, detail.autoImportSource, detail.autoImportAlias)
422
+ : undefined;
423
+ // Are we resolving a completion item? If so, see if this symbol
424
+ // is the one that we're trying to match.
425
+ if (this._itemToResolve) {
426
+ const completionItemData = (0, lspUtils_1.fromLSPAny)(this._itemToResolve.data);
427
+ if (completionItemData.symbolLabel !== name) {
428
+ // It's not what we are looking for.
429
+ return;
430
+ }
431
+ if (completionItemData.autoImportText) {
432
+ if (completionItemData.autoImportText === (autoImportText === null || autoImportText === void 0 ? void 0 : autoImportText.importText) &&
433
+ ((_b = detail.edits) === null || _b === void 0 ? void 0 : _b.additionalTextEdits)) {
434
+ this._itemToResolve.additionalTextEdits = (0, workspaceEditUtils_1.convertToTextEdits)(detail.edits.additionalTextEdits);
435
+ }
436
+ return;
437
+ }
438
+ // This call can be expensive to perform on every completion item
439
+ // that we return, so we do it lazily in the "resolve" callback.
440
+ const type = this.evaluator.getEffectiveTypeOfSymbol(symbol);
441
+ if (!type) {
442
+ // Can't resolve. so bail out.
443
+ return;
444
+ }
445
+ const typeDetail = (0, completionProviderUtils_1.getTypeDetail)(this.evaluator, primaryDecl, type, name, detail, this.configOptions.functionSignatureDisplay);
446
+ const documentation = (0, tooltipUtils_1.getDocumentationPartsForTypeAndDecl)(this.sourceMapper, type, primaryDecl, this.evaluator, {
447
+ name,
448
+ symbol,
449
+ boundObjectOrClass: detail.boundObjectOrClass,
450
+ });
451
+ if (this.options.format === vscode_languageserver_1.MarkupKind.Markdown || this.options.format === vscode_languageserver_1.MarkupKind.PlainText) {
452
+ this._itemToResolve.documentation = (0, completionProviderUtils_1.getCompletionItemDocumentation)(typeDetail, documentation, this.options.format);
453
+ }
454
+ else {
455
+ (0, debug_1.fail)(`Unsupported markup type: ${this.options.format}`);
456
+ }
457
+ // Bail out. We don't need to add items to completion.
458
+ return;
459
+ }
460
+ if (primaryDecl) {
461
+ let itemKind = this._convertDeclarationTypeToItemKind(primaryDecl);
462
+ // Handle enum members specially. Enum members normally look like
463
+ // variables, but the are declared using assignment expressions
464
+ // within an enum class.
465
+ if (primaryDecl.type === 1 /* Variable */ &&
466
+ detail.boundObjectOrClass &&
467
+ (0, types_1.isInstantiableClass)(detail.boundObjectOrClass) &&
468
+ types_1.ClassType.isEnumClass(detail.boundObjectOrClass) &&
469
+ ((_c = primaryDecl.node.parent) === null || _c === void 0 ? void 0 : _c.nodeType) === 3 /* Assignment */) {
470
+ itemKind = vscode_languageserver_1.CompletionItemKind.EnumMember;
471
+ }
472
+ this._addNameToCompletions((_d = detail.autoImportAlias) !== null && _d !== void 0 ? _d : name, itemKind, priorWord, completionMap, {
473
+ autoImportText,
474
+ extraCommitChars: detail.extraCommitChars,
475
+ funcParensDisabled: detail.funcParensDisabled,
476
+ edits: detail.edits,
477
+ });
478
+ }
479
+ else {
480
+ // Does the symbol have no declaration but instead has a synthesized type?
481
+ const synthesizedType = symbol.getSynthesizedType();
482
+ if (synthesizedType) {
483
+ const itemKind = this._convertTypeToItemKind(synthesizedType);
484
+ this._addNameToCompletions(name, itemKind, priorWord, completionMap, {
485
+ extraCommitChars: detail.extraCommitChars,
486
+ funcParensDisabled: detail.funcParensDisabled,
487
+ edits: detail.edits,
488
+ });
489
+ }
490
+ }
491
+ }
492
+ getMemberAccessCompletions(leftExprNode, priorWord) {
493
+ const symbolTable = new Map();
494
+ const completionMap = new CompletionMap();
495
+ let leftType = this.evaluator.getType(leftExprNode);
496
+ if (!leftType) {
497
+ return completionMap;
498
+ }
499
+ leftType = this.evaluator.makeTopLevelTypeVarsConcrete(leftType);
500
+ // If this is an unknown type with a "possible type" associated with
501
+ // it, use the possible type.
502
+ if ((0, types_1.isUnknown)(leftType) && leftType.possibleType) {
503
+ leftType = this.evaluator.makeTopLevelTypeVarsConcrete(leftType.possibleType);
504
+ }
505
+ (0, typeUtils_1.doForEachSubtype)(leftType, (subtype) => {
506
+ subtype = this.evaluator.makeTopLevelTypeVarsConcrete(subtype);
507
+ if ((0, types_1.isClass)(subtype)) {
508
+ (0, typeUtils_1.getMembersForClass)(subtype, symbolTable, /* includeInstanceVars */ types_1.TypeBase.isInstance(subtype));
509
+ }
510
+ else if ((0, types_1.isModule)(subtype)) {
511
+ (0, typeUtils_1.getMembersForModule)(subtype, symbolTable);
512
+ }
513
+ else if ((0, types_1.isFunction)(subtype) || (0, types_1.isOverloadedFunction)(subtype)) {
514
+ const functionClass = this.evaluator.getBuiltInType(leftExprNode, 'function');
515
+ if (functionClass && (0, types_1.isInstantiableClass)(functionClass)) {
516
+ (0, typeUtils_1.getMembersForClass)(functionClass, symbolTable, /* includeInstanceVars */ true);
517
+ }
518
+ }
519
+ else if ((0, types_1.isNoneInstance)(subtype)) {
520
+ const objectClass = this.evaluator.getBuiltInType(leftExprNode, 'object');
521
+ if (objectClass && (0, types_1.isInstantiableClass)(objectClass)) {
522
+ (0, typeUtils_1.getMembersForClass)(objectClass, symbolTable, types_1.TypeBase.isInstance(subtype));
523
+ }
524
+ }
525
+ this._addSymbolsForSymbolTable(symbolTable, () => true, priorWord, leftExprNode,
526
+ /* isInImport */ false, (0, types_1.isClass)(subtype) ? subtype : undefined, completionMap);
527
+ });
528
+ return completionMap;
529
+ }
530
+ addAutoImportCompletions(priorWord, similarityLimit, lazyEdit, completionMap) {
531
+ if (!this.configOptions.autoImportCompletions) {
532
+ // If auto import on the server is turned off or this particular invocation
533
+ // is turned off (ex, notebook), don't do any thing.
534
+ return;
535
+ }
536
+ const currentFile = this.program.getSourceFileInfo(this.filePath);
537
+ const moduleSymbolMap = (0, autoImporter_1.buildModuleSymbolsMap)(this.program.getSourceFileInfoList().filter((s) => s !== currentFile));
538
+ const autoImporter = new autoImporter_1.AutoImporter(this.execEnv, this.importResolver, this.parseResults, this.position, completionMap, moduleSymbolMap, {
539
+ lazyEdit,
540
+ });
541
+ const results = [];
542
+ (0, collectionUtils_1.appendArray)(results, autoImporter.getAutoImportCandidates(priorWord, similarityLimit,
543
+ /* abbrFromUsers */ undefined, this.cancellationToken));
544
+ this.addImportResults(results, priorWord, completionMap);
545
+ }
546
+ addImportResults(results, priorWord, completionMap) {
178
547
  var _a, _b;
179
- const offset = (0, positionUtils_1.convertPositionToOffset)(this._position, this._parseResults.tokenizerOutput.lines);
548
+ for (const result of results) {
549
+ if (result.symbol) {
550
+ this.addSymbol(result.name, result.symbol, priorWord, completionMap, {
551
+ extraCommitChars: true,
552
+ autoImportSource: result.source,
553
+ autoImportAlias: result.alias,
554
+ edits: {
555
+ textEdit: this.createReplaceEdits(priorWord, /* node */ undefined, result.insertionText),
556
+ additionalTextEdits: result.edits,
557
+ },
558
+ });
559
+ }
560
+ else {
561
+ 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, {
562
+ extraCommitChars: true,
563
+ autoImportText: this._getAutoImportText(result.name, result.source, result.alias),
564
+ edits: {
565
+ textEdit: this.createReplaceEdits(priorWord, /* node */ undefined, result.insertionText),
566
+ additionalTextEdits: result.edits,
567
+ },
568
+ });
569
+ }
570
+ }
571
+ }
572
+ checkDecorator(node, value) {
573
+ return node.expression.nodeType === 38 /* Name */ && node.expression.value === value;
574
+ }
575
+ addExtraCommitChar(item) {
576
+ // extra commit char is not supported.
577
+ }
578
+ get _fileContents() {
579
+ var _a, _b;
580
+ return (_b = (_a = this.parseResults) === null || _a === void 0 ? void 0 : _a.text) !== null && _b !== void 0 ? _b : '';
581
+ }
582
+ _getCompletions() {
583
+ var _a, _b;
584
+ const offset = (0, positionUtils_1.convertPositionToOffset)(this.position, this.parseResults.tokenizerOutput.lines);
180
585
  if (offset === undefined) {
181
586
  return undefined;
182
587
  }
183
- const token = ParseTreeUtils.getTokenOverlapping(this._parseResults.tokenizerOutput.tokens, offset);
588
+ let node = ParseTreeUtils.findNodeByOffset(this.parseResults.parseTree, offset);
589
+ // See if we're inside a string literal or an f-string statement.
590
+ const token = ParseTreeUtils.getTokenOverlapping(this.parseResults.tokenizerOutput.tokens, offset);
184
591
  if ((token === null || token === void 0 ? void 0 : token.type) === 5 /* String */) {
185
592
  const stringToken = token;
186
- this._insideStringLiteral = textRange_2.TextRange.contains(stringToken, offset)
593
+ this._stringLiteralContainer = textRange_1.TextRange.contains(stringToken, offset)
187
594
  ? stringToken
188
595
  : stringToken.flags & 65536 /* Unterminated */
189
596
  ? stringToken
190
597
  : undefined;
191
598
  }
192
- let node = ParseTreeUtils.findNodeByOffset(this._parseResults.parseTree, offset);
599
+ else if (node) {
600
+ const fStringContainer = ParseTreeUtils.getParentNodeOfType(node, 27 /* FormatString */);
601
+ if (fStringContainer) {
602
+ this._stringLiteralContainer = fStringContainer.token;
603
+ }
604
+ }
193
605
  // See if we can get to a "better" node by backing up a few columns.
194
606
  // A "better" node is defined as one that's deeper than the current
195
607
  // node.
@@ -208,7 +620,7 @@ class CompletionProvider {
208
620
  if (curChar === ',') {
209
621
  sawComma = true;
210
622
  }
211
- const curNode = ParseTreeUtils.findNodeByOffset(this._parseResults.parseTree, curOffset);
623
+ const curNode = ParseTreeUtils.findNodeByOffset(this.parseResults.parseTree, curOffset);
212
624
  if (curNode && curNode !== initialNode) {
213
625
  if (ParseTreeUtils.getNodeDepth(curNode) > initialDepth) {
214
626
  node = curNode;
@@ -226,10 +638,10 @@ class CompletionProvider {
226
638
  return undefined;
227
639
  }
228
640
  // Get the text on that line prior to the insertion point.
229
- const lineTextRange = this._parseResults.tokenizerOutput.lines.getItemAt(this._position.line);
641
+ const lineTextRange = this.parseResults.tokenizerOutput.lines.getItemAt(this.position.line);
230
642
  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);
643
+ const priorText = textOnLine.substr(0, this.position.character);
644
+ const postText = textOnLine.substr(this.position.character);
233
645
  const priorWordIndex = priorText.search(/\w+$/);
234
646
  const priorWord = priorWordIndex >= 0 ? priorText.substr(priorWordIndex) : '';
235
647
  // Don't offer completions if we're within a comment.
@@ -249,7 +661,7 @@ class CompletionProvider {
249
661
  // that of its ancestors.
250
662
  let curNode = errorNode || node;
251
663
  while (true) {
252
- (0, cancellationUtils_1.throwIfCancellationRequested)(this._cancellationToken);
664
+ (0, cancellationUtils_1.throwIfCancellationRequested)(this.cancellationToken);
253
665
  if (curNode.nodeType === 49 /* String */) {
254
666
  return this._getLiteralCompletions(curNode, offset, priorWord, priorText, postText);
255
667
  }
@@ -263,13 +675,13 @@ class CompletionProvider {
263
675
  return this._getExpressionErrorCompletions(curNode, offset, priorWord, priorText, postText);
264
676
  }
265
677
  if (curNode.nodeType === 35 /* MemberAccess */) {
266
- return this._getMemberAccessCompletions(curNode.leftExpression, priorWord);
678
+ return this.getMemberAccessCompletions(curNode.leftExpression, priorWord);
267
679
  }
268
680
  if (curNode.nodeType === 15 /* Dictionary */) {
269
681
  const completionMap = new CompletionMap();
270
682
  if (this._tryAddTypedDictKeysFromDictionary(curNode,
271
683
  /* stringNode */ undefined, priorWord, priorText, postText, completionMap)) {
272
- return { completionMap };
684
+ return completionMap;
273
685
  }
274
686
  }
275
687
  const dictionaryEntry = ParseTreeUtils.getFirstAncestorOrSelfOfKind(curNode, 17 /* DictionaryKeyEntry */);
@@ -280,7 +692,7 @@ class CompletionProvider {
280
692
  const completionMap = new CompletionMap();
281
693
  if (this._tryAddTypedDictKeysFromDictionary(dictionaryNode,
282
694
  /* stringNode */ undefined, priorWord, priorText, postText, completionMap)) {
283
- return { completionMap };
695
+ return completionMap;
284
696
  }
285
697
  }
286
698
  }
@@ -294,7 +706,7 @@ class CompletionProvider {
294
706
  return result;
295
707
  }
296
708
  }
297
- if (curNode.nodeType === 31 /* List */ && this._options.triggerCharacter === '[') {
709
+ if (curNode.nodeType === 31 /* List */ && this.options.triggerCharacter === '[') {
298
710
  // If this is an empty list, don't start putting completions up yet.
299
711
  return undefined;
300
712
  }
@@ -309,7 +721,7 @@ class CompletionProvider {
309
721
  curNode.parent.nodeType === 25 /* Except */ &&
310
722
  !curNode.parent.name &&
311
723
  curNode.parent.typeExpression &&
312
- textRange_2.TextRange.getEnd(curNode.parent.typeExpression) < offset &&
724
+ textRange_1.TextRange.getEnd(curNode.parent.typeExpression) < offset &&
313
725
  offset <= curNode.parent.exceptSuite.start) {
314
726
  // except Exception as [<empty>]
315
727
  return undefined;
@@ -341,84 +753,6 @@ class CompletionProvider {
341
753
  }
342
754
  return undefined;
343
755
  }
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
756
  // This method will return false if it wants1
423
757
  // caller to walk up the tree. it will return
424
758
  // CompletionResults or undefined if it wants caller
@@ -437,7 +771,7 @@ class CompletionProvider {
437
771
  if (curNode.parent.parent &&
438
772
  curNode.parent.parent.nodeType === 21 /* ImportAs */ &&
439
773
  !curNode.parent.parent.alias &&
440
- textRange_2.TextRange.getEnd(curNode.parent.parent) < offset) {
774
+ textRange_1.TextRange.getEnd(curNode.parent.parent) < offset) {
441
775
  return undefined;
442
776
  }
443
777
  // Are we within a "from X import Y as Z" statement and
@@ -452,7 +786,7 @@ class CompletionProvider {
452
786
  const parentNode = curNode.parent.parent;
453
787
  if (parentNode && parentNode.nodeType === 22 /* ImportFrom */) {
454
788
  // Are we within a "from X import Y as [<empty>]"?
455
- if (!curNode.parent.alias && textRange_2.TextRange.getEnd(curNode.parent) < offset) {
789
+ if (!curNode.parent.alias && textRange_1.TextRange.getEnd(curNode.parent) < offset) {
456
790
  return undefined;
457
791
  }
458
792
  if (curNode.parent.name === curNode) {
@@ -463,7 +797,7 @@ class CompletionProvider {
463
797
  return false;
464
798
  }
465
799
  if (curNode.parent.nodeType === 35 /* MemberAccess */ && curNode === curNode.parent.memberName) {
466
- return this._getMemberAccessCompletions(curNode.parent.leftExpression, priorWord);
800
+ return this.getMemberAccessCompletions(curNode.parent.leftExpression, priorWord);
467
801
  }
468
802
  if (curNode.parent.nodeType === 25 /* Except */ && curNode === curNode.parent.name) {
469
803
  return undefined;
@@ -481,11 +815,11 @@ class CompletionProvider {
481
815
  return undefined;
482
816
  }
483
817
  if (curNode.parent.nodeType === 26 /* For */ &&
484
- textRange_2.TextRange.contains(curNode.parent.targetExpression, curNode.start)) {
818
+ textRange_1.TextRange.contains(curNode.parent.targetExpression, curNode.start)) {
485
819
  return undefined;
486
820
  }
487
821
  if (curNode.parent.nodeType === 33 /* ListComprehensionFor */ &&
488
- textRange_2.TextRange.contains(curNode.parent.targetExpression, curNode.start)) {
822
+ textRange_1.TextRange.contains(curNode.parent.targetExpression, curNode.start)) {
489
823
  return undefined;
490
824
  }
491
825
  // For assignments that implicitly declare variables, remove itself (var decl) from completion.
@@ -497,15 +831,15 @@ class CompletionProvider {
497
831
  if (leftNode !== curNode || priorWord.length === 0) {
498
832
  return false;
499
833
  }
500
- const decls = this._evaluator.getDeclarationsForNameNode(curNode);
834
+ const decls = this.evaluator.getDeclarationsForNameNode(curNode);
501
835
  if ((decls === null || decls === void 0 ? void 0 : decls.length) !== 1 || !(0, declaration_1.isVariableDeclaration)(decls[0]) || decls[0].node !== curNode) {
502
836
  return false;
503
837
  }
504
- const completionList = this._getExpressionCompletions(curNode, priorWord, priorText, postText);
505
- if (completionList) {
506
- completionList.completionMap.delete(curNode.value);
838
+ const completionMap = this._getExpressionCompletions(curNode, priorWord, priorText, postText);
839
+ if (completionMap) {
840
+ completionMap.delete(curNode.value);
507
841
  }
508
- return completionList;
842
+ return completionMap;
509
843
  }
510
844
  // Defining class variables.
511
845
  // ex) class A:
@@ -522,12 +856,12 @@ class CompletionProvider {
522
856
  }
523
857
  _isWithinComment(offset) {
524
858
  var _a, _b;
525
- const token = getTokenAfter(offset, this._parseResults.tokenizerOutput.tokens);
859
+ const token = getTokenAfter(offset, this.parseResults.tokenizerOutput.tokens);
526
860
  if (!token) {
527
861
  // If we're in the middle of a token, we're not in a comment.
528
862
  return false;
529
863
  }
530
- return (_b = (_a = token.comments) === null || _a === void 0 ? void 0 : _a.some((c) => textRange_2.TextRange.overlaps(c, offset))) !== null && _b !== void 0 ? _b : false;
864
+ return (_b = (_a = token.comments) === null || _a === void 0 ? void 0 : _a.some((c) => textRange_1.TextRange.overlaps(c, offset))) !== null && _b !== void 0 ? _b : false;
531
865
  function getTokenAfter(offset, tokens) {
532
866
  const tokenIndex = tokens.getItemAtPosition(offset);
533
867
  if (tokenIndex < 0) {
@@ -572,8 +906,8 @@ class CompletionProvider {
572
906
  case 7 /* MissingMemberAccessName */:
573
907
  case 2 /* MissingExpression */: {
574
908
  // Don't show completion after random dots.
575
- const tokenizerOutput = this._parseResults.tokenizerOutput;
576
- const offset = (0, positionUtils_1.convertPositionToOffset)(this._position, tokenizerOutput.lines);
909
+ const tokenizerOutput = this.parseResults.tokenizerOutput;
910
+ const offset = (0, positionUtils_1.convertPositionToOffset)(this.position, tokenizerOutput.lines);
577
911
  const index = ParseTreeUtils.getTokenIndexAtLeft(tokenizerOutput.tokens, offset);
578
912
  const token = ParseTreeUtils.getTokenAtIndex(tokenizerOutput.tokens, index);
579
913
  const prevToken = ParseTreeUtils.getTokenAtIndex(tokenizerOutput.tokens, index - 1);
@@ -591,14 +925,14 @@ class CompletionProvider {
591
925
  // since parser won't see "is" as partially written member name instead it will see it as
592
926
  // expression statement with missing expression after "is" keyword.
593
927
  // In such case, use "MyType." to get completion.
594
- if ((token === null || token === void 0 ? void 0 : token.type) !== 8 /* Keyword */ || textRange_2.TextRange.getEnd(token) !== offset) {
928
+ if ((token === null || token === void 0 ? void 0 : token.type) !== 8 /* Keyword */ || textRange_1.TextRange.getEnd(token) !== offset) {
595
929
  return this._getExpressionCompletions(node, priorWord, priorText, postText);
596
930
  }
597
931
  if ((prevToken === null || prevToken === void 0 ? void 0 : prevToken.type) !== 20 /* Dot */) {
598
932
  return this._getExpressionCompletions(node, priorWord, priorText, postText);
599
933
  }
600
- const previousOffset = textRange_2.TextRange.getEnd(prevToken);
601
- const previousNode = ParseTreeUtils.findNodeByOffset(this._parseResults.parseTree, previousOffset);
934
+ const previousOffset = textRange_1.TextRange.getEnd(prevToken);
935
+ const previousNode = ParseTreeUtils.findNodeByOffset(this.parseResults.parseTree, previousOffset);
602
936
  if ((previousNode === null || previousNode === void 0 ? void 0 : previousNode.nodeType) !== 0 /* Error */ ||
603
937
  previousNode.category !== 7 /* MissingMemberAccessName */) {
604
938
  return this._getExpressionCompletions(node, priorWord, priorText, postText);
@@ -635,7 +969,7 @@ class CompletionProvider {
635
969
  }
636
970
  // Determine if the partial name is a method that's overriding
637
971
  // a method in a base class.
638
- return this._getMethodOverrideCompletions(priorWord, node.child, node.decorators);
972
+ return this.getMethodOverrideCompletions(priorWord, node.child, node.decorators);
639
973
  }
640
974
  break;
641
975
  }
@@ -646,13 +980,10 @@ class CompletionProvider {
646
980
  if (!node.child || !(0, parseNodes_1.isExpressionNode)(node.child)) {
647
981
  return undefined;
648
982
  }
649
- return this._getMemberAccessCompletions(node.child, priorWord);
983
+ return this.getMemberAccessCompletions(node.child, priorWord);
650
984
  }
651
985
  _isOverload(node) {
652
- return this._checkDecorator(node, 'overload');
653
- }
654
- _checkDecorator(node, value) {
655
- return node.expression.nodeType === 38 /* Name */ && node.expression.value === value;
986
+ return this.checkDecorator(node, 'overload');
656
987
  }
657
988
  _createSingleKeywordCompletion(keyword) {
658
989
  const completionItem = vscode_languageserver_1.CompletionItem.create(keyword);
@@ -660,7 +991,7 @@ class CompletionProvider {
660
991
  completionItem.sortText = this._makeSortText(SortCategory.LikelyKeyword, keyword);
661
992
  const completionMap = new CompletionMap();
662
993
  completionMap.set(completionItem);
663
- return { completionMap };
994
+ return completionMap;
664
995
  }
665
996
  _addClassVariableTypeAnnotationCompletions(priorWord, parseNode, completionMap) {
666
997
  var _a, _b, _c, _d;
@@ -679,7 +1010,7 @@ class CompletionProvider {
679
1010
  if (!enclosingClass) {
680
1011
  return;
681
1012
  }
682
- const classResults = this._evaluator.getTypeOfClass(enclosingClass);
1013
+ const classResults = this.evaluator.getTypeOfClass(enclosingClass);
683
1014
  if (!classResults) {
684
1015
  return undefined;
685
1016
  }
@@ -687,8 +1018,8 @@ class CompletionProvider {
687
1018
  const classMember = (0, typeUtils_1.lookUpClassMember)(classResults.classType, classVariableName, 8 /* SkipInstanceVariables */ | 1 /* SkipOriginalClass */);
688
1019
  // First, see whether we can use semantic info to get variable type.
689
1020
  if (classMember) {
690
- const memberType = this._evaluator.getTypeOfMember(classMember);
691
- const text = this._evaluator.printType(memberType, {
1021
+ const memberType = this.evaluator.getTypeOfMember(classMember);
1022
+ const text = this.evaluator.printType(memberType, {
692
1023
  enforcePythonSyntax: true,
693
1024
  expandTypeAlias: false,
694
1025
  });
@@ -724,7 +1055,7 @@ class CompletionProvider {
724
1055
  if (declWithTypeAnnotations.length === 0) {
725
1056
  return;
726
1057
  }
727
- const printFlags = (0, sourceMapper_1.isStubFile)(this._filePath)
1058
+ const printFlags = (0, sourceMapper_1.isStubFile)(this.filePath)
728
1059
  ? 1 /* ForwardDeclarations */ |
729
1060
  2 /* DoNotLimitStringLength */
730
1061
  : 2 /* DoNotLimitStringLength */;
@@ -738,7 +1069,7 @@ class CompletionProvider {
738
1069
  if (!enclosingClass) {
739
1070
  return undefined;
740
1071
  }
741
- const classResults = this._evaluator.getTypeOfClass(enclosingClass);
1072
+ const classResults = this.evaluator.getTypeOfClass(enclosingClass);
742
1073
  if (!classResults) {
743
1074
  return undefined;
744
1075
  }
@@ -764,13 +1095,13 @@ class CompletionProvider {
764
1095
  decls.some((d) => d.node && ParseTreeUtils.getEnclosingClass(d.node, false) === enclosingClass)) {
765
1096
  return;
766
1097
  }
767
- this._addSymbol(name, symbol, partialName.value, completionMap, {});
1098
+ this.addSymbol(name, symbol, partialName.value, completionMap, {});
768
1099
  });
769
- return completionMap.size > 0 ? { completionMap } : undefined;
1100
+ return completionMap.size > 0 ? completionMap : undefined;
770
1101
  }
771
1102
  _getMethodOverloadsCompletions(priorWord, partialName) {
772
1103
  var _a;
773
- const symbolTable = getSymbolTable(this._evaluator, partialName);
1104
+ const symbolTable = getSymbolTable(this.evaluator, partialName);
774
1105
  if (!symbolTable) {
775
1106
  return undefined;
776
1107
  }
@@ -792,14 +1123,14 @@ class CompletionProvider {
792
1123
  return;
793
1124
  }
794
1125
  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, {
1126
+ const textEdit = this.createReplaceEdits(priorWord, partialName, decl.node.name.value);
1127
+ this.addSymbol(name, symbol, partialName.value, completionMap, {
797
1128
  funcParensDisabled,
798
1129
  edits: { textEdit },
799
1130
  });
800
1131
  }
801
1132
  });
802
- return { completionMap };
1133
+ return completionMap;
803
1134
  function getSymbolTable(evaluator, partialName) {
804
1135
  const enclosingClass = ParseTreeUtils.getEnclosingClass(partialName, false);
805
1136
  if (enclosingClass) {
@@ -808,155 +1139,39 @@ class CompletionProvider {
808
1139
  return undefined;
809
1140
  }
810
1141
  const symbolTable = new Map();
811
- for (const mroClass of classResults.classType.details.mro) {
812
- 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;
1142
+ for (const mroClass of classResults.classType.details.mro) {
1143
+ if ((0, types_1.isInstantiableClass)(mroClass)) {
1144
+ (0, typeUtils_1.getMembersForClass)(mroClass, symbolTable, /* includeInstanceVars */ false);
1145
+ }
881
1146
  }
882
- funcType = member;
883
- }
884
- if (!funcType || !funcType.details.declaration) {
885
- return;
1147
+ return symbolTable;
886
1148
  }
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}: ...`;
1149
+ // For function overload, we only care about top level functions
1150
+ const moduleNode = ParseTreeUtils.getEnclosingModule(partialName);
1151
+ if (moduleNode) {
1152
+ const moduleScope = AnalyzerNodeInfo.getScope(moduleNode);
1153
+ return moduleScope === null || moduleScope === void 0 ? void 0 : moduleScope.symbolTable;
892
1154
  }
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));
1155
+ return undefined;
919
1156
  }
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
1157
  }
932
- _printMethodSignature(importAdder, classType, funcType, typingFilePath) {
933
- const declaration = funcType.details.declaration;
1158
+ _printMethodSignature(classType, decl) {
1159
+ const node = decl.node;
934
1160
  let ellipsisForDefault;
935
- if ((0, sourceMapper_1.isStubFile)(this._filePath)) {
1161
+ if ((0, sourceMapper_1.isStubFile)(this.filePath)) {
936
1162
  // In stubs, always use "...".
937
1163
  ellipsisForDefault = true;
938
1164
  }
939
- else if (classType.details.moduleName === declaration.moduleName) {
1165
+ else if (classType.details.moduleName === decl.moduleName) {
940
1166
  // In the same file, always print the full default.
941
1167
  ellipsisForDefault = false;
942
1168
  }
943
- const printOptionsUsingSyntax = (0, sourceMapper_1.isStubFile)(this._filePath)
1169
+ const printFlags = (0, sourceMapper_1.isStubFile)(this.filePath)
944
1170
  ? 1 /* ForwardDeclarations */ |
945
1171
  2 /* DoNotLimitStringLength */
946
1172
  : 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) => {
1173
+ const paramList = node.parameters
1174
+ .map((param, index) => {
960
1175
  let paramString = '';
961
1176
  if (param.category === 1 /* VarArgList */) {
962
1177
  paramString += '*';
@@ -965,325 +1180,35 @@ class CompletionProvider {
965
1180
  paramString += '**';
966
1181
  }
967
1182
  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}`;
1183
+ paramString += param.name.value;
1199
1184
  }
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
- }
1185
+ // Currently, we don't automatically add import if the type used in the annotation is not imported
1186
+ // in current file.
1187
+ const paramTypeAnnotation = ParseTreeUtils.getTypeAnnotationForParameter(node, index);
1188
+ if (paramTypeAnnotation) {
1189
+ paramString += ': ' + ParseTreeUtils.printExpression(paramTypeAnnotation, printFlags);
1258
1190
  }
1259
- else {
1260
- break;
1191
+ if (param.defaultValue) {
1192
+ paramString += paramTypeAnnotation ? ' = ' : '=';
1193
+ const useEllipsis = ellipsisForDefault !== null && ellipsisForDefault !== void 0 ? ellipsisForDefault : !this.isSimpleDefault(param.defaultValue);
1194
+ paramString += useEllipsis ? '...' : ParseTreeUtils.printExpression(param.defaultValue, printFlags);
1261
1195
  }
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
- }
1196
+ if (!paramString && !param.name && param.category === 0 /* Simple */) {
1197
+ return '/';
1268
1198
  }
1199
+ return paramString;
1200
+ })
1201
+ .join(', ');
1202
+ let methodSignature = node.name.value + '(' + paramList + ')';
1203
+ if (node.returnTypeAnnotation) {
1204
+ methodSignature += ' -> ' + ParseTreeUtils.printExpression(node.returnTypeAnnotation, printFlags);
1269
1205
  }
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;
1206
+ else if (node.functionAnnotationComment) {
1207
+ methodSignature +=
1208
+ ' -> ' +
1209
+ ParseTreeUtils.printExpression(node.functionAnnotationComment.returnTypeAnnotation, printFlags);
1285
1210
  }
1286
- return memberAccessInfo;
1211
+ return methodSignature;
1287
1212
  }
1288
1213
  _getStatementCompletions(parseNode, priorWord, priorText, postText) {
1289
1214
  // For now, use the same logic for expressions and statements.
@@ -1304,10 +1229,9 @@ class CompletionProvider {
1304
1229
  return undefined;
1305
1230
  }
1306
1231
  const completionMap = new CompletionMap();
1307
- const completionResults = { completionMap };
1308
1232
  // Return empty completionList for Ellipsis
1309
1233
  if (priorText.slice(-2) === '..') {
1310
- return completionResults;
1234
+ return completionMap;
1311
1235
  }
1312
1236
  // Defining type annotation for class variables.
1313
1237
  // ex) class A:
@@ -1319,7 +1243,7 @@ class CompletionProvider {
1319
1243
  // Add symbols that are in scope.
1320
1244
  this._addSymbols(parseNode, priorWord, completionMap);
1321
1245
  // Add keywords.
1322
- this._findMatchingKeywords(Keywords.forVersion(this._execEnv.pythonVersion), priorWord).map((keyword) => {
1246
+ this._findMatchingKeywords(Keywords.forVersion(this.execEnv.pythonVersion), priorWord).map((keyword) => {
1323
1247
  if (completionMap.has(keyword)) {
1324
1248
  return;
1325
1249
  }
@@ -1331,11 +1255,11 @@ class CompletionProvider {
1331
1255
  // Add auto-import suggestions from other modules.
1332
1256
  // Ignore this check for privates, since they are not imported.
1333
1257
  if (!priorWord.startsWith('_') && !this._itemToResolve) {
1334
- this._addAutoImportCompletions(priorWord, similarityLimit, this._options.lazyEdit, completionResults);
1258
+ this.addAutoImportCompletions(priorWord, similarityLimit, this.options.lazyEdit, completionMap);
1335
1259
  }
1336
1260
  // Add literal values if appropriate.
1337
1261
  this._tryAddLiterals(parseNode, priorWord, priorText, postText, completionMap);
1338
- return completionResults;
1262
+ return completionMap;
1339
1263
  }
1340
1264
  _isIndexArgument(node) {
1341
1265
  const currentNode = node.parent;
@@ -1349,16 +1273,16 @@ class CompletionProvider {
1349
1273
  }
1350
1274
  _addCallArgumentCompletions(parseNode, priorWord, priorText, postText, atArgument, completionMap) {
1351
1275
  // 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);
1276
+ const offset = (0, positionUtils_1.convertPositionToOffset)(this.position, this.parseResults.tokenizerOutput.lines);
1277
+ const callInfo = (0, parseTreeUtils_1.getCallNodeAndActiveParameterIndex)(parseNode, offset, this.parseResults.tokenizerOutput.tokens);
1354
1278
  if (!callInfo) {
1355
1279
  return;
1356
1280
  }
1357
- const signatureInfo = this._evaluator.getCallSignatureInfo(callInfo.callNode, callInfo.activeIndex, callInfo.activeOrFake);
1281
+ const signatureInfo = this.evaluator.getCallSignatureInfo(callInfo.callNode, callInfo.activeIndex, callInfo.activeOrFake);
1358
1282
  if (signatureInfo) {
1359
1283
  // 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) {
1284
+ const callNameEnd = (0, positionUtils_1.convertOffsetToPosition)(signatureInfo.callNode.leftExpression.start + signatureInfo.callNode.leftExpression.length, this.parseResults.tokenizerOutput.lines);
1285
+ if ((0, textRange_1.comparePositions)(this.position, callNameEnd) > 0) {
1362
1286
  if (!atArgument) {
1363
1287
  this._addNamedParameters(signatureInfo, priorWord, completionMap);
1364
1288
  }
@@ -1449,7 +1373,7 @@ class CompletionProvider {
1449
1373
  if (member === null || member === void 0 ? void 0 : member.symbol.hasDeclarations()) {
1450
1374
  const declaration = member.symbol.getDeclarations()[0];
1451
1375
  if ((0, declaration_1.isFunctionDeclaration)(declaration) && declaration.isMethod) {
1452
- const getItemType = (_b = this._evaluator.getTypeForDeclaration(declaration)) === null || _b === void 0 ? void 0 : _b.type;
1376
+ const getItemType = (_b = this.evaluator.getTypeForDeclaration(declaration)) === null || _b === void 0 ? void 0 : _b.type;
1453
1377
  if (getItemType && (0, types_1.isFunction)(getItemType) && getItemType.details.parameters.length === 2) {
1454
1378
  return getItemType.details.parameters[1].type;
1455
1379
  }
@@ -1459,7 +1383,7 @@ class CompletionProvider {
1459
1383
  }
1460
1384
  _getIndexerKeys(indexNode, invocationNode) {
1461
1385
  var _a, _b, _c, _d, _e, _f, _g, _h, _j;
1462
- const baseType = this._evaluator.getType(indexNode.baseExpression);
1386
+ const baseType = this.evaluator.getType(indexNode.baseExpression);
1463
1387
  if (!baseType || !(0, types_1.isClassInstance)(baseType)) {
1464
1388
  return [];
1465
1389
  }
@@ -1475,7 +1399,7 @@ class CompletionProvider {
1475
1399
  !types_1.ClassType.isEnumClass(v)) {
1476
1400
  return;
1477
1401
  }
1478
- keys.push((0, typePrinter_1.printLiteralValue)(v, this._parseResults.tokenizerOutput.predominantSingleQuoteCharacter));
1402
+ keys.push((0, typePrinter_1.printLiteralValue)(v, this.parseResults.tokenizerOutput.predominantSingleQuoteCharacter));
1479
1403
  });
1480
1404
  if (keys.length > 0) {
1481
1405
  return keys;
@@ -1486,13 +1410,13 @@ class CompletionProvider {
1486
1410
  return [];
1487
1411
  }
1488
1412
  // Must be local variable/parameter
1489
- const declarations = (_a = this._evaluator.getDeclarationsForNameNode(indexNode.baseExpression)) !== null && _a !== void 0 ? _a : [];
1413
+ const declarations = (_a = this.evaluator.getDeclarationsForNameNode(indexNode.baseExpression)) !== null && _a !== void 0 ? _a : [];
1490
1414
  const declaration = declarations.length > 0 ? declarations[0] : undefined;
1491
1415
  if (!declaration ||
1492
1416
  (declaration.type !== 1 /* Variable */ && declaration.type !== 2 /* Parameter */)) {
1493
1417
  return [];
1494
1418
  }
1495
- if (declaration.path !== this._filePath) {
1419
+ if (declaration.path !== this.filePath) {
1496
1420
  return [];
1497
1421
  }
1498
1422
  let startingNode = indexNode.baseExpression;
@@ -1504,7 +1428,7 @@ class CompletionProvider {
1504
1428
  startingNode = scopeRoot;
1505
1429
  }
1506
1430
  }
1507
- const results = documentSymbolCollector_1.DocumentSymbolCollector.collectFromNode(this._program, indexNode.baseExpression, this._cancellationToken, startingNode);
1431
+ const results = documentSymbolCollector_1.DocumentSymbolCollector.collectFromNode(this.program, indexNode.baseExpression, this.cancellationToken, startingNode);
1508
1432
  const keys = new Set();
1509
1433
  for (const result of results) {
1510
1434
  const node = ((_d = result.node.parent) === null || _d === void 0 ? void 0 : _d.nodeType) === 54 /* TypeAnnotation */ ? result.node.parent : result.node;
@@ -1513,7 +1437,7 @@ class CompletionProvider {
1513
1437
  if (node.parent.rightExpression.nodeType === 15 /* Dictionary */) {
1514
1438
  const dictionary = node.parent.rightExpression;
1515
1439
  for (const entry of dictionary.entries.filter((e) => e.nodeType === 17 /* DictionaryKeyEntry */)) {
1516
- const key = this._parseResults.text
1440
+ const key = this.parseResults.text
1517
1441
  .substr(entry.keyExpression.start, entry.keyExpression.length)
1518
1442
  .trim();
1519
1443
  if (key.length > 0)
@@ -1522,13 +1446,13 @@ class CompletionProvider {
1522
1446
  }
1523
1447
  if (node.parent.rightExpression.nodeType === 9 /* Call */) {
1524
1448
  const call = node.parent.rightExpression;
1525
- const type = this._evaluator.getType(call.leftExpression);
1449
+ const type = this.evaluator.getType(call.leftExpression);
1526
1450
  if (!type || !(0, types_1.isInstantiableClass)(type) || !types_1.ClassType.isBuiltIn(type, 'dict')) {
1527
1451
  continue;
1528
1452
  }
1529
1453
  for (const arg of call.arguments) {
1530
1454
  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;
1455
+ const quote = this.parseResults.tokenizerOutput.predominantSingleQuoteCharacter;
1532
1456
  if (key.length > 0) {
1533
1457
  keys.add(`${quote}${key}${quote}`);
1534
1458
  }
@@ -1538,19 +1462,19 @@ class CompletionProvider {
1538
1462
  if (((_j = node.parent) === null || _j === void 0 ? void 0 : _j.nodeType) === 24 /* Index */ &&
1539
1463
  node.parent.items.length === 1 &&
1540
1464
  node.parent.items[0].valueExpression.nodeType !== 0 /* Error */ &&
1541
- !textRange_2.TextRange.containsRange(node.parent, invocationNode)) {
1465
+ !textRange_1.TextRange.containsRange(node.parent, invocationNode)) {
1542
1466
  const indexArgument = node.parent.items[0];
1543
- const key = this._parseResults.text
1467
+ const key = this.parseResults.text
1544
1468
  .substr(indexArgument.valueExpression.start, indexArgument.valueExpression.length)
1545
1469
  .trim();
1546
1470
  if (key.length > 0)
1547
1471
  keys.add(key);
1548
1472
  }
1549
1473
  }
1550
- return [...keys];
1474
+ return Array.from(keys);
1551
1475
  }
1552
1476
  _getLiteralCompletions(parseNode, offset, priorWord, priorText, postText) {
1553
- if (this._options.triggerCharacter === '"' || this._options.triggerCharacter === "'") {
1477
+ if (this.options.triggerCharacter === '"' || this.options.triggerCharacter === "'") {
1554
1478
  if (parseNode.start !== offset - 1) {
1555
1479
  // If completion is triggered by typing " or ', it must be the one that starts a string
1556
1480
  // literal. In another word, it can't be something inside of another string or comment
@@ -1561,7 +1485,7 @@ class CompletionProvider {
1561
1485
  if (!this._tryAddLiterals(parseNode, priorWord, priorText, postText, completionMap)) {
1562
1486
  return undefined;
1563
1487
  }
1564
- return { completionMap };
1488
+ return completionMap;
1565
1489
  }
1566
1490
  _tryAddLiterals(parseNode, priorWord, priorText, postText, completionMap) {
1567
1491
  var _a, _b, _c, _d, _e, _f;
@@ -1579,7 +1503,7 @@ class CompletionProvider {
1579
1503
  ? parentAndChild.child
1580
1504
  : undefined;
1581
1505
  if (nodeForExpectedType) {
1582
- const expectedTypeResult = this._evaluator.getExpectedType(nodeForExpectedType);
1506
+ const expectedTypeResult = this.evaluator.getExpectedType(nodeForExpectedType);
1583
1507
  if (expectedTypeResult && (0, typeUtils_1.isLiteralTypeOrUnion)(expectedTypeResult.type)) {
1584
1508
  this._addLiteralValuesForTargetType(expectedTypeResult.type, priorWord, priorText, postText, completionMap);
1585
1509
  return true;
@@ -1648,7 +1572,7 @@ class CompletionProvider {
1648
1572
  const comparison = parentAndChild.parent;
1649
1573
  const supportedOperators = [2 /* Assign */, 12 /* Equals */, 28 /* NotEquals */];
1650
1574
  if (comparison.nodeType === 7 /* BinaryOperation */ && supportedOperators.includes(comparison.operator)) {
1651
- const type = this._evaluator.getType(comparison.leftExpression);
1575
+ const type = this.evaluator.getType(comparison.leftExpression);
1652
1576
  if (type && (0, typeUtils_1.isLiteralTypeOrUnion)(type)) {
1653
1577
  this._addLiteralValuesForTargetType(type, priorWord, priorText, postText, completionMap);
1654
1578
  return true;
@@ -1658,7 +1582,7 @@ class CompletionProvider {
1658
1582
  const assignmentExpression = parentAndChild.parent;
1659
1583
  if (assignmentExpression.nodeType === 4 /* AssignmentExpression */ &&
1660
1584
  assignmentExpression.rightExpression === parentAndChild.child) {
1661
- const type = this._evaluator.getType(assignmentExpression.name);
1585
+ const type = this.evaluator.getType(assignmentExpression.name);
1662
1586
  if (type && (0, typeUtils_1.isLiteralTypeOrUnion)(type)) {
1663
1587
  this._addLiteralValuesForTargetType(type, priorWord, priorText, postText, completionMap);
1664
1588
  return true;
@@ -1673,7 +1597,7 @@ class CompletionProvider {
1673
1597
  caseNode.pattern.category === 11 /* MissingPattern */ &&
1674
1598
  caseNode.suite === parentAndChild.child &&
1675
1599
  ((_c = caseNode.parent) === null || _c === void 0 ? void 0 : _c.nodeType) === 63 /* Match */) {
1676
- const type = this._evaluator.getType(caseNode.parent.subjectExpression);
1600
+ const type = this.evaluator.getType(caseNode.parent.subjectExpression);
1677
1601
  if (type && (0, typeUtils_1.isLiteralTypeOrUnion)(type)) {
1678
1602
  this._addLiteralValuesForTargetType(type, priorWord, priorText, postText, completionMap);
1679
1603
  return true;
@@ -1688,15 +1612,15 @@ class CompletionProvider {
1688
1612
  ((_d = patternLiteral.parent) === null || _d === void 0 ? void 0 : _d.nodeType) === 66 /* PatternAs */ &&
1689
1613
  ((_e = patternLiteral.parent.parent) === null || _e === void 0 ? void 0 : _e.nodeType) === 64 /* Case */ &&
1690
1614
  ((_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);
1615
+ const type = this.evaluator.getType(patternLiteral.parent.parent.parent.subjectExpression);
1692
1616
  if (type && (0, typeUtils_1.isLiteralTypeOrUnion)(type)) {
1693
1617
  this._addLiteralValuesForTargetType(type, priorWord, priorText, postText, completionMap);
1694
1618
  return true;
1695
1619
  }
1696
1620
  }
1697
1621
  if (parseNode.nodeType === 49 /* String */) {
1698
- const offset = (0, positionUtils_1.convertPositionToOffset)(this._position, this._parseResults.tokenizerOutput.lines);
1699
- const atArgument = parseNode.parent.start < offset && offset < textRange_2.TextRange.getEnd(parseNode);
1622
+ const offset = (0, positionUtils_1.convertPositionToOffset)(this.position, this.parseResults.tokenizerOutput.lines);
1623
+ const atArgument = parseNode.parent.start < offset && offset < textRange_1.TextRange.getEnd(parseNode);
1700
1624
  this._addCallArgumentCompletions(parseNode, priorWord, priorText, postText, atArgument, completionMap);
1701
1625
  return true;
1702
1626
  }
@@ -1732,7 +1656,7 @@ class CompletionProvider {
1732
1656
  const quoteInfo = this._getQuoteInfo(priorWord, priorText);
1733
1657
  const excludes = new Set(existingKeys);
1734
1658
  typedDicts.forEach((typedDict) => {
1735
- (0, typedDicts_1.getTypedDictMembersForClass)(this._evaluator, typedDict, /* allowNarrowed */ true).forEach((_, key) => {
1659
+ (0, typedDicts_1.getTypedDictMembersForClass)(this.evaluator, typedDict, /* allowNarrowed */ true).forEach((_, key) => {
1736
1660
  // Unions of TypedDicts may define the same key.
1737
1661
  if (excludes.has(key) || completionMap.has(key)) {
1738
1662
  return;
@@ -1745,7 +1669,7 @@ class CompletionProvider {
1745
1669
  }
1746
1670
  _tryAddTypedDictKeysFromDictionary(dictionaryNode, stringNode, priorWord, priorText, postText, completionMap) {
1747
1671
  var _a;
1748
- const expectedTypeResult = this._evaluator.getExpectedType(dictionaryNode);
1672
+ const expectedTypeResult = this.evaluator.getExpectedType(dictionaryNode);
1749
1673
  if (!expectedTypeResult) {
1750
1674
  return false;
1751
1675
  }
@@ -1759,7 +1683,7 @@ class CompletionProvider {
1759
1683
  }
1760
1684
  _tryNarrowTypedDicts(types, keys) {
1761
1685
  const newTypes = types.flatMap((type) => {
1762
- const entries = (0, typedDicts_1.getTypedDictMembersForClass)(this._evaluator, type, /* allowNarrowed */ true);
1686
+ const entries = (0, typedDicts_1.getTypedDictMembersForClass)(this.evaluator, type, /* allowNarrowed */ true);
1763
1687
  for (let index = 0; index < keys.length; index++) {
1764
1688
  if (!entries.has(keys[index])) {
1765
1689
  return [];
@@ -1773,16 +1697,16 @@ class CompletionProvider {
1773
1697
  }
1774
1698
  return newTypes;
1775
1699
  }
1776
- // Find out quotation and string prefix to use for string literals
1700
+ // Find quotation and string prefix to use for string literals
1777
1701
  // completion under current context.
1778
1702
  _getQuoteInfo(priorWord, priorText) {
1779
1703
  let filterText = priorWord;
1780
1704
  let stringValue = undefined;
1781
- let quoteCharacter = this._parseResults.tokenizerOutput.predominantSingleQuoteCharacter;
1705
+ let quoteCharacter = this.parseResults.tokenizerOutput.predominantSingleQuoteCharacter;
1782
1706
  // If completion is not inside of the existing string literal
1783
1707
  // ex) typedDict[ |<= here
1784
1708
  // use default quotation char without any string prefix.
1785
- if (!this._insideStringLiteral) {
1709
+ if (!this._stringLiteralContainer) {
1786
1710
  return { priorWord, priorText, filterText, stringValue, quoteCharacter };
1787
1711
  }
1788
1712
  const singleQuote = "'";
@@ -1802,16 +1726,15 @@ class CompletionProvider {
1802
1726
  quoteCharacter = doubleQuote;
1803
1727
  }
1804
1728
  }
1805
- // If the string literal that completion is invoked in is f-string,
1806
- // quotation must be the other one than one that is used for f-string.
1807
- // ex) f"....{typedDict[|<= here ]}"
1808
- // then quotation must be "'"
1809
- //
1810
- // for f-string, this code path will be only taken when completion is inside
1811
- // of f-string segment.
1812
- // ex) f"..{|<= here }"
1813
- if (this._insideStringLiteral.flags & 64 /* Format */) {
1814
- quoteCharacter = this._insideStringLiteral.flags & 1 /* SingleQuote */ ? doubleQuote : singleQuote;
1729
+ // If the invocation position is within an f-string, use a double or
1730
+ // single quote that doesn't match the f-string. Prior to Python 3.12,
1731
+ // using the same quotation mark nested within an f-string was not
1732
+ // permitted. For example, f"..{typedDict[|<= here ]}", we need to use
1733
+ // single quotes. Note that this doesn't account for deeper nested
1734
+ // f-strings.
1735
+ if (this._stringLiteralContainer.flags & 64 /* Format */) {
1736
+ quoteCharacter =
1737
+ this._stringLiteralContainer.flags & 1 /* SingleQuote */ ? doubleQuote : singleQuote;
1815
1738
  }
1816
1739
  if (stringValue) {
1817
1740
  filterText = stringValue;
@@ -1822,7 +1745,7 @@ class CompletionProvider {
1822
1745
  if (!indexNode) {
1823
1746
  return false;
1824
1747
  }
1825
- const baseType = this._evaluator.getType(indexNode.baseExpression);
1748
+ const baseType = this.evaluator.getType(indexNode.baseExpression);
1826
1749
  if (!baseType) {
1827
1750
  return false;
1828
1751
  }
@@ -1837,7 +1760,7 @@ class CompletionProvider {
1837
1760
  const completionItem = vscode_languageserver_1.CompletionItem.create(valueWithQuotes);
1838
1761
  completionItem.kind = vscode_languageserver_1.CompletionItemKind.Constant;
1839
1762
  completionItem.sortText = this._makeSortText(SortCategory.LiteralValue, valueWithQuotes);
1840
- let rangeStartCol = this._position.character;
1763
+ let rangeStartCol = this.position.character;
1841
1764
  if (quoteInfo.stringValue !== undefined) {
1842
1765
  rangeStartCol -= quoteInfo.stringValue.length + 1;
1843
1766
  }
@@ -1846,80 +1769,23 @@ class CompletionProvider {
1846
1769
  }
1847
1770
  // If the text after the insertion point is the closing quote,
1848
1771
  // replace it.
1849
- let rangeEndCol = this._position.character;
1772
+ let rangeEndCol = this.position.character;
1850
1773
  if (postText !== undefined) {
1851
1774
  if (postText.startsWith(quoteInfo.quoteCharacter)) {
1852
1775
  rangeEndCol++;
1853
1776
  }
1854
1777
  }
1855
1778
  const range = {
1856
- start: { line: this._position.line, character: rangeStartCol },
1857
- end: { line: this._position.line, character: rangeEndCol },
1779
+ start: { line: this.position.line, character: rangeStartCol },
1780
+ end: { line: this.position.line, character: rangeEndCol },
1858
1781
  };
1859
1782
  completionItem.textEdit = vscode_languageserver_1.TextEdit.replace(range, valueWithQuotes);
1860
1783
  completionItem.detail = detail;
1861
1784
  completionMap.set(completionItem);
1862
1785
  }
1863
1786
  }
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
1787
  _getImportFromCompletions(importFromNode, priorWord) {
1788
+ var _a;
1923
1789
  // Don't attempt to provide completions for "from X import *".
1924
1790
  if (importFromNode.isWildcardImport) {
1925
1791
  return undefined;
@@ -1932,16 +1798,21 @@ class CompletionProvider {
1932
1798
  }
1933
1799
  const completionMap = new CompletionMap();
1934
1800
  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);
1801
+ const parseResults = this.program.getParseResults(resolvedPath);
1802
+ if (!parseResults) {
1803
+ return completionMap;
1944
1804
  }
1805
+ const symbolTable = (_a = AnalyzerNodeInfo.getScope(parseResults.parseTree)) === null || _a === void 0 ? void 0 : _a.symbolTable;
1806
+ if (!symbolTable) {
1807
+ return completionMap;
1808
+ }
1809
+ this._addSymbolsForSymbolTable(symbolTable, (symbol, name) => {
1810
+ // Don't suggest built in symbols or ones that have already been imported.
1811
+ return (symbol.getDeclarations().some((d) => !(0, declaration_1.isIntrinsicDeclaration)(d)) &&
1812
+ !importFromNode.imports.find((imp) => imp.name.value === name));
1813
+ }, priorWord, importFromNode,
1814
+ /* isInImport */ true,
1815
+ /* boundObject */ undefined, completionMap);
1945
1816
  // Add the implicit imports.
1946
1817
  importInfo.implicitImports.forEach((implImport) => {
1947
1818
  if (!importFromNode.imports.find((imp) => imp.name.value === implImport.name)) {
@@ -1950,7 +1821,7 @@ class CompletionProvider {
1950
1821
  });
1951
1822
  }
1952
1823
  });
1953
- return { completionMap };
1824
+ return completionMap;
1954
1825
  }
1955
1826
  _findMatchingKeywords(keywordList, partialMatch) {
1956
1827
  return keywordList.filter((keyword) => {
@@ -1984,8 +1855,8 @@ class CompletionProvider {
1984
1855
  completionItem.kind = vscode_languageserver_1.CompletionItemKind.Variable;
1985
1856
  const completionItemData = {
1986
1857
  workspacePath: this._workspacePath,
1987
- filePath: this._filePath,
1988
- position: this._position,
1858
+ filePath: this.filePath,
1859
+ position: this.position,
1989
1860
  };
1990
1861
  completionItem.data = (0, lspUtils_1.toLSPAny)(completionItemData);
1991
1862
  completionItem.sortText = this._makeSortText(SortCategory.NamedParameter, argName);
@@ -2024,7 +1895,7 @@ class CompletionProvider {
2024
1895
  }
2025
1896
  // If this is a class scope, add symbols from parent classes.
2026
1897
  if (curNode.nodeType === 10 /* Class */) {
2027
- const classType = this._evaluator.getTypeOfClass(curNode);
1898
+ const classType = this.evaluator.getTypeOfClass(curNode);
2028
1899
  if (classType && (0, types_1.isInstantiableClass)(classType.classType)) {
2029
1900
  classType.classType.details.mro.forEach((baseClass, index) => {
2030
1901
  if ((0, types_1.isInstantiableClass)(baseClass)) {
@@ -2056,14 +1927,14 @@ class CompletionProvider {
2056
1927
  // exported from this scope, don't include it in the
2057
1928
  // suggestion list unless we are in the same file.
2058
1929
  const hidden = !(0, symbolUtils_1.isVisibleExternally)(symbol) &&
2059
- !symbol.getDeclarations().some((d) => (0, declarationUtils_1.isDefinedInFile)(d, this._filePath));
1930
+ !symbol.getDeclarations().some((d) => (0, declarationUtils_1.isDefinedInFile)(d, this.filePath));
2060
1931
  if (!hidden && includeSymbolCallback(symbol, name)) {
2061
1932
  // Don't add a symbol more than once. It may have already been
2062
1933
  // added from an inner scope's symbol table.
2063
1934
  if (!completionMap.has(name)) {
2064
1935
  // Skip func parens for classes when not a direct assignment or an argument (passed as a value)
2065
1936
  const skipForClass = !this._shouldShowAutoParensForClass(symbol, node);
2066
- this._addSymbol(name, symbol, priorWord, completionMap, {
1937
+ this.addSymbol(name, symbol, priorWord, completionMap, {
2067
1938
  boundObjectOrClass,
2068
1939
  funcParensDisabled: isInImport || insideTypeAnnotation || skipForClass,
2069
1940
  extraCommitChars: !isInImport && !!priorWord,
@@ -2083,107 +1954,23 @@ class CompletionProvider {
2083
1954
  return true;
2084
1955
  }
2085
1956
  // 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);
1957
+ const nodeIndex = ParseTreeUtils.getTokenIndexAtLeft(this.parseResults.tokenizerOutput.tokens, node.start);
1958
+ const prevToken = ParseTreeUtils.getTokenAtIndex(this.parseResults.tokenizerOutput.tokens, nodeIndex);
2088
1959
  return (prevToken &&
2089
1960
  prevToken.type === 9 /* Operator */ &&
2090
1961
  prevToken.operatorType === 2 /* Assign */);
2091
1962
  }
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
1963
  _getAutoImportText(importName, importFrom, importAlias) {
2177
1964
  const autoImportText = (0, tooltipUtils_1.getAutoImportText)(importName, importFrom, importAlias);
2178
1965
  let importText = '';
2179
- if (this._options.format === vscode_languageserver_1.MarkupKind.Markdown) {
1966
+ if (this.options.format === vscode_languageserver_1.MarkupKind.Markdown) {
2180
1967
  importText = `\`\`\`\n${autoImportText}\n\`\`\``;
2181
1968
  }
2182
- else if (this._options.format === vscode_languageserver_1.MarkupKind.PlainText) {
1969
+ else if (this.options.format === vscode_languageserver_1.MarkupKind.PlainText) {
2183
1970
  importText = autoImportText;
2184
1971
  }
2185
1972
  else {
2186
- (0, debug_1.fail)(`Unsupported markup type: ${this._options.format}`);
1973
+ (0, debug_1.fail)(`Unsupported markup type: ${this.options.format}`);
2187
1974
  }
2188
1975
  return {
2189
1976
  source: importFrom !== null && importFrom !== void 0 ? importFrom : '',
@@ -2203,14 +1990,14 @@ class CompletionProvider {
2203
1990
  const completionItem = vscode_languageserver_1.CompletionItem.create(name);
2204
1991
  completionItem.kind = itemKind;
2205
1992
  if (detail === null || detail === void 0 ? void 0 : detail.extraCommitChars) {
2206
- this._addExtraCommitChar(completionItem, ...this._getExtraCommitCharsForKind(itemKind));
1993
+ this.addExtraCommitChar(completionItem);
2207
1994
  }
2208
1995
  const completionItemData = {
2209
1996
  workspacePath: this._workspacePath,
2210
- filePath: this._filePath,
2211
- position: this._position,
1997
+ filePath: this.filePath,
1998
+ position: this.position,
2212
1999
  };
2213
- if ((detail === null || detail === void 0 ? void 0 : detail.funcParensDisabled) || !this._options.snippet) {
2000
+ if ((detail === null || detail === void 0 ? void 0 : detail.funcParensDisabled) || !this.options.snippet) {
2214
2001
  completionItemData.funcParensDisabled = true;
2215
2002
  }
2216
2003
  if (detail === null || detail === void 0 ? void 0 : detail.modulePath) {
@@ -2248,7 +2035,7 @@ class CompletionProvider {
2248
2035
  completionItem.sortText = this._makeSortText(SortCategory.NormalSymbol, name);
2249
2036
  }
2250
2037
  completionItemData.symbolLabel = name;
2251
- if (this._options.format === vscode_languageserver_1.MarkupKind.Markdown) {
2038
+ if (this.options.format === vscode_languageserver_1.MarkupKind.Markdown) {
2252
2039
  let markdownString = '';
2253
2040
  if (detail === null || detail === void 0 ? void 0 : detail.autoImportText) {
2254
2041
  markdownString += detail.autoImportText.importText;
@@ -2272,7 +2059,7 @@ class CompletionProvider {
2272
2059
  };
2273
2060
  }
2274
2061
  }
2275
- else if (this._options.format === vscode_languageserver_1.MarkupKind.PlainText) {
2062
+ else if (this.options.format === vscode_languageserver_1.MarkupKind.PlainText) {
2276
2063
  let plainTextString = '';
2277
2064
  if (detail === null || detail === void 0 ? void 0 : detail.autoImportText) {
2278
2065
  plainTextString += detail.autoImportText.importText;
@@ -2296,7 +2083,7 @@ class CompletionProvider {
2296
2083
  }
2297
2084
  }
2298
2085
  else {
2299
- (0, debug_1.fail)(`Unsupported markup type: ${this._options.format}`);
2086
+ (0, debug_1.fail)(`Unsupported markup type: ${this.options.format}`);
2300
2087
  }
2301
2088
  if ((_b = detail === null || detail === void 0 ? void 0 : detail.edits) === null || _b === void 0 ? void 0 : _b.format) {
2302
2089
  completionItem.insertTextFormat = detail.edits.format;
@@ -2358,7 +2145,7 @@ class CompletionProvider {
2358
2145
  return result;
2359
2146
  }
2360
2147
  _convertDeclarationTypeToItemKind(declaration) {
2361
- const resolvedDeclaration = this._evaluator.resolveAliasDeclaration(declaration, /* resolveLocalNames */ true);
2148
+ const resolvedDeclaration = this.evaluator.resolveAliasDeclaration(declaration, /* resolveLocalNames */ true);
2362
2149
  if (!resolvedDeclaration) {
2363
2150
  return vscode_languageserver_1.CompletionItemKind.Variable;
2364
2151
  }
@@ -2379,7 +2166,7 @@ class CompletionProvider {
2379
2166
  return vscode_languageserver_1.CompletionItemKind.Variable;
2380
2167
  case 5 /* Function */: {
2381
2168
  if (this._isPossiblePropertyDeclaration(resolvedDeclaration)) {
2382
- const functionType = this._evaluator.getTypeOfFunction(resolvedDeclaration.node);
2169
+ const functionType = this.evaluator.getTypeOfFunction(resolvedDeclaration.node);
2383
2170
  if (functionType &&
2384
2171
  (0, typeUtils_1.isMaybeDescriptorInstance)(functionType.decoratedType, /* requireSetter */ false)) {
2385
2172
  return vscode_languageserver_1.CompletionItemKind.Property;
@@ -2417,9 +2204,9 @@ class CompletionProvider {
2417
2204
  leadingDots: node.leadingDots,
2418
2205
  hasTrailingDot: node.hasTrailingDot || false,
2419
2206
  nameParts: node.nameParts.map((part) => part.value),
2420
- importedSymbols: [],
2207
+ importedSymbols: new Set(),
2421
2208
  };
2422
- const completions = this._importResolver.getCompletionSuggestions(this._filePath, this._execEnv, moduleDescriptor);
2209
+ const completions = this.importResolver.getCompletionSuggestions(this.filePath, this.execEnv, moduleDescriptor);
2423
2210
  const completionMap = new CompletionMap();
2424
2211
  // If we're in the middle of a "from X import Y" statement, offer
2425
2212
  // the "import" keyword as a completion.
@@ -2439,27 +2226,7 @@ class CompletionProvider {
2439
2226
  modulePath,
2440
2227
  });
2441
2228
  });
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;
2229
+ return completionMap;
2463
2230
  }
2464
2231
  _isPossiblePropertyDeclaration(decl) {
2465
2232
  // Do cheap check using only nodes that will cover 99.9% cases