@zzzen/pyright-internal 1.2.0-dev.20230409 → 1.2.0-dev.20230423

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 (151) hide show
  1. package/dist/analyzer/binder.js +1 -3
  2. package/dist/analyzer/binder.js.map +1 -1
  3. package/dist/analyzer/codeFlowEngine.js +22 -0
  4. package/dist/analyzer/codeFlowEngine.js.map +1 -1
  5. package/dist/analyzer/commentUtils.d.ts +1 -1
  6. package/dist/analyzer/commentUtils.js +18 -3
  7. package/dist/analyzer/commentUtils.js.map +1 -1
  8. package/dist/analyzer/constructorTransform.js +112 -49
  9. package/dist/analyzer/constructorTransform.js.map +1 -1
  10. package/dist/analyzer/declarationUtils.js +2 -1
  11. package/dist/analyzer/declarationUtils.js.map +1 -1
  12. package/dist/analyzer/docStringConversion.js +2 -3
  13. package/dist/analyzer/docStringConversion.js.map +1 -1
  14. package/dist/analyzer/enums.d.ts +1 -1
  15. package/dist/analyzer/enums.js +114 -55
  16. package/dist/analyzer/enums.js.map +1 -1
  17. package/dist/analyzer/parseTreeUtils.js +9 -4
  18. package/dist/analyzer/parseTreeUtils.js.map +1 -1
  19. package/dist/analyzer/patternMatching.d.ts +6 -2
  20. package/dist/analyzer/patternMatching.js +109 -2
  21. package/dist/analyzer/patternMatching.js.map +1 -1
  22. package/dist/analyzer/program.d.ts +9 -7
  23. package/dist/analyzer/program.js +106 -46
  24. package/dist/analyzer/program.js.map +1 -1
  25. package/dist/analyzer/service.d.ts +2 -2
  26. package/dist/analyzer/service.js +6 -6
  27. package/dist/analyzer/service.js.map +1 -1
  28. package/dist/analyzer/sourceFile.d.ts +1 -3
  29. package/dist/analyzer/sourceFile.js +1 -9
  30. package/dist/analyzer/sourceFile.js.map +1 -1
  31. package/dist/analyzer/sourceMapper.js +1 -1
  32. package/dist/analyzer/sourceMapper.js.map +1 -1
  33. package/dist/analyzer/typeEvaluator.js +147 -38
  34. package/dist/analyzer/typeEvaluator.js.map +1 -1
  35. package/dist/analyzer/typeEvaluatorTypes.d.ts +4 -3
  36. package/dist/analyzer/typeEvaluatorTypes.js +0 -2
  37. package/dist/analyzer/typeEvaluatorTypes.js.map +1 -1
  38. package/dist/analyzer/typeGuards.d.ts +2 -0
  39. package/dist/analyzer/typeGuards.js +172 -175
  40. package/dist/analyzer/typeGuards.js.map +1 -1
  41. package/dist/analyzer/typePrinter.d.ts +1 -1
  42. package/dist/analyzer/typePrinter.js +21 -18
  43. package/dist/analyzer/typePrinter.js.map +1 -1
  44. package/dist/analyzer/typeUtils.js +13 -13
  45. package/dist/analyzer/typeUtils.js.map +1 -1
  46. package/dist/analyzer/types.d.ts +2 -1
  47. package/dist/analyzer/types.js +20 -4
  48. package/dist/analyzer/types.js.map +1 -1
  49. package/dist/common/configOptions.d.ts +1 -1
  50. package/dist/common/configOptions.js +3 -3
  51. package/dist/common/configOptions.js.map +1 -1
  52. package/dist/common/extensibility.d.ts +7 -4
  53. package/dist/common/extensibility.js.map +1 -1
  54. package/dist/common/fullAccessHost.d.ts +2 -1
  55. package/dist/common/fullAccessHost.js +11 -1
  56. package/dist/common/fullAccessHost.js.map +1 -1
  57. package/dist/common/host.d.ts +3 -2
  58. package/dist/common/host.js +1 -1
  59. package/dist/common/host.js.map +1 -1
  60. package/dist/languageServerBase.js +3 -2
  61. package/dist/languageServerBase.js.map +1 -1
  62. package/dist/languageService/autoImporter.d.ts +1 -1
  63. package/dist/languageService/autoImporter.js +2 -2
  64. package/dist/languageService/autoImporter.js.map +1 -1
  65. package/dist/languageService/callHierarchyProvider.js +17 -4
  66. package/dist/languageService/callHierarchyProvider.js.map +1 -1
  67. package/dist/languageService/completionProvider.js +259 -93
  68. package/dist/languageService/completionProvider.js.map +1 -1
  69. package/dist/languageService/completionProviderUtils.js +11 -3
  70. package/dist/languageService/completionProviderUtils.js.map +1 -1
  71. package/dist/languageService/documentSymbolCollector.js +1 -1
  72. package/dist/languageService/documentSymbolCollector.js.map +1 -1
  73. package/dist/languageService/hoverProvider.d.ts +28 -28
  74. package/dist/languageService/hoverProvider.js +151 -118
  75. package/dist/languageService/hoverProvider.js.map +1 -1
  76. package/dist/languageService/importAdder.d.ts +13 -2
  77. package/dist/languageService/importAdder.js +73 -26
  78. package/dist/languageService/importAdder.js.map +1 -1
  79. package/dist/languageService/indentationUtils.js +9 -4
  80. package/dist/languageService/indentationUtils.js.map +1 -1
  81. package/dist/languageService/insertionPointUtils.js +2 -2
  82. package/dist/languageService/insertionPointUtils.js.map +1 -1
  83. package/dist/localization/localize.d.ts +2 -0
  84. package/dist/localization/localize.js +2 -0
  85. package/dist/localization/localize.js.map +1 -1
  86. package/dist/localization/package.nls.en-us.json +2 -0
  87. package/dist/tests/checker.test.js +1 -1
  88. package/dist/tests/completions.test.js +412 -0
  89. package/dist/tests/completions.test.js.map +1 -1
  90. package/dist/tests/docStringConversion.test.js +11 -1
  91. package/dist/tests/docStringConversion.test.js.map +1 -1
  92. package/dist/tests/fourslash/completions.inherited.function.docFromStub.fourslash.js +1 -1
  93. package/dist/tests/fourslash/completions.inherited.function.docFromStub.fourslash.js.map +1 -1
  94. package/dist/tests/fourslash/completions.override2.fourslash.js +16 -1
  95. package/dist/tests/fourslash/completions.override2.fourslash.js.map +1 -1
  96. package/dist/tests/fourslash/completions.variableDocStrings.fourslash.js +1 -1
  97. package/dist/tests/fourslash/completions.variableDocStrings.fourslash.js.map +1 -1
  98. package/dist/tests/fourslash/fourslash.d.ts +11 -1
  99. package/dist/tests/fourslash/hover.docstring.overloads.fourslash.js +2 -2
  100. package/dist/tests/fourslash/hover.docstring.overloads.fourslash.js.map +1 -1
  101. package/dist/tests/fourslash/hover.variable.docString.fourslash.js +1 -1
  102. package/dist/tests/fourslash/hover.variable.docString.fourslash.js.map +1 -1
  103. package/dist/tests/fourslash/showcallhierarchy.incomingCalls.aliasedFunction.fourslash.js +5 -6
  104. package/dist/tests/fourslash/showcallhierarchy.incomingCalls.aliasedFunction.fourslash.js.map +1 -1
  105. package/dist/tests/fourslash/showcallhierarchy.incomingCalls.aliasedVariable.fourslash.js +1 -4
  106. package/dist/tests/fourslash/showcallhierarchy.incomingCalls.aliasedVariable.fourslash.js.map +1 -1
  107. package/dist/tests/fourslash/showcallhierarchy.incomingCalls.function.fourslash.js +10 -9
  108. package/dist/tests/fourslash/showcallhierarchy.incomingCalls.function.fourslash.js.map +1 -1
  109. package/dist/tests/fourslash/showcallhierarchy.outgoingCalls.aliasedFunction1.fourslash.d.ts +1 -0
  110. package/dist/tests/fourslash/showcallhierarchy.outgoingCalls.aliasedFunction1.fourslash.js +54 -0
  111. package/dist/tests/fourslash/showcallhierarchy.outgoingCalls.aliasedFunction1.fourslash.js.map +1 -0
  112. package/dist/tests/fourslash/showcallhierarchy.outgoingCalls.aliasedFunction2.fourslash.d.ts +1 -0
  113. package/dist/tests/fourslash/showcallhierarchy.outgoingCalls.aliasedFunction2.fourslash.js +46 -0
  114. package/dist/tests/fourslash/showcallhierarchy.outgoingCalls.aliasedFunction2.fourslash.js.map +1 -0
  115. package/dist/tests/fourslash/showcallhierarchy.outgoingCalls.function.fourslash.d.ts +1 -0
  116. package/dist/tests/fourslash/showcallhierarchy.outgoingCalls.function.fourslash.js +39 -0
  117. package/dist/tests/fourslash/showcallhierarchy.outgoingCalls.function.fourslash.js.map +1 -0
  118. package/dist/tests/harness/fourslash/fourSlashParser.js +1 -1
  119. package/dist/tests/harness/fourslash/fourSlashParser.js.map +1 -1
  120. package/dist/tests/harness/fourslash/testState.d.ts +6 -1
  121. package/dist/tests/harness/fourslash/testState.js +38 -6
  122. package/dist/tests/harness/fourslash/testState.js.map +1 -1
  123. package/dist/tests/harness/testHost.js +1 -1
  124. package/dist/tests/harness/testHost.js.map +1 -1
  125. package/dist/tests/harness/vfs/factory.js +2 -2
  126. package/dist/tests/harness/vfs/factory.js.map +1 -1
  127. package/dist/tests/harness/vfs/filesystem.js +26 -25
  128. package/dist/tests/harness/vfs/filesystem.js.map +1 -1
  129. package/dist/tests/hoverProvider.test.js +6 -0
  130. package/dist/tests/hoverProvider.test.js.map +1 -1
  131. package/dist/tests/importAdder.test.js +69 -1
  132. package/dist/tests/importAdder.test.js.map +1 -1
  133. package/dist/tests/indentationUtils.ptvs.test.js +2 -2
  134. package/dist/tests/indentationUtils.ptvs.test.js.map +1 -1
  135. package/dist/tests/indentationUtils.test.js +18 -0
  136. package/dist/tests/indentationUtils.test.js.map +1 -1
  137. package/dist/tests/moveSymbol.insertion.test.js +25 -4
  138. package/dist/tests/moveSymbol.insertion.test.js.map +1 -1
  139. package/dist/tests/typeEvaluator1.test.js +8 -0
  140. package/dist/tests/typeEvaluator1.test.js.map +1 -1
  141. package/dist/tests/typeEvaluator2.test.js +4 -0
  142. package/dist/tests/typeEvaluator2.test.js.map +1 -1
  143. package/dist/tests/typeEvaluator3.test.js +10 -0
  144. package/dist/tests/typeEvaluator3.test.js.map +1 -1
  145. package/dist/tests/typeEvaluator4.test.js +5 -1
  146. package/dist/tests/typeEvaluator4.test.js.map +1 -1
  147. package/dist/tests/typePrinter.test.js +5 -0
  148. package/dist/tests/typePrinter.test.js.map +1 -1
  149. package/dist/workspaceFactory.js +1 -1
  150. package/dist/workspaceFactory.js.map +1 -1
  151. package/package.json +1 -1
@@ -37,6 +37,7 @@ 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");
40
41
  const scopeUtils_1 = require("../analyzer/scopeUtils");
41
42
  const sourceMapper_1 = require("../analyzer/sourceMapper");
42
43
  const SymbolNameUtils = __importStar(require("../analyzer/symbolNameUtils"));
@@ -51,6 +52,7 @@ const collectionUtils_1 = require("../common/collectionUtils");
51
52
  const debug = __importStar(require("../common/debug"));
52
53
  const debug_1 = require("../common/debug");
53
54
  const lspUtils_1 = require("../common/lspUtils");
55
+ const pathUtils_1 = require("../common/pathUtils");
54
56
  const positionUtils_1 = require("../common/positionUtils");
55
57
  const pythonVersion_1 = require("../common/pythonVersion");
56
58
  const StringUtils = __importStar(require("../common/stringUtils"));
@@ -62,6 +64,7 @@ const parseNodes_1 = require("../parser/parseNodes");
62
64
  const autoImporter_1 = require("./autoImporter");
63
65
  const completionProviderUtils_1 = require("./completionProviderUtils");
64
66
  const documentSymbolCollector_1 = require("./documentSymbolCollector");
67
+ const importAdder_1 = require("./importAdder");
65
68
  const tooltipUtils_1 = require("./tooltipUtils");
66
69
  var Keywords;
67
70
  (function (Keywords) {
@@ -820,71 +823,89 @@ class CompletionProvider {
820
823
  if (!classResults) {
821
824
  return undefined;
822
825
  }
823
- const symbolTable = new Map();
824
- for (let i = 1; i < classResults.classType.details.mro.length; i++) {
825
- const mroClass = classResults.classType.details.mro[i];
826
- if ((0, types_1.isInstantiableClass)(mroClass)) {
827
- (0, typeUtils_1.getMembersForClass)(mroClass, symbolTable, /* includeInstanceVars */ false);
828
- }
829
- }
830
826
  const staticmethod = (_a = decorators === null || decorators === void 0 ? void 0 : decorators.some((d) => this._checkDecorator(d, 'staticmethod'))) !== null && _a !== void 0 ? _a : false;
831
827
  const classmethod = (_b = decorators === null || decorators === void 0 ? void 0 : decorators.some((d) => this._checkDecorator(d, 'classmethod'))) !== null && _b !== void 0 ? _b : false;
832
- const completionMap = new CompletionMap();
833
- symbolTable.forEach((symbol, name) => {
834
- var _a;
835
- let decl = (0, symbolUtils_1.getLastTypedDeclaredForSymbol)(symbol);
836
- if (decl && decl.type === 5 /* Function */) {
837
- if (StringUtils.isPatternInSymbol(partialName.value, name)) {
838
- const declaredType = (_a = this._evaluator.getTypeForDeclaration(decl)) === null || _a === void 0 ? void 0 : _a.type;
839
- if (!declaredType) {
840
- return;
841
- }
842
- let isProperty = (0, types_1.isClassInstance)(declaredType) && types_1.ClassType.isPropertyClass(declaredType);
843
- if (SymbolNameUtils.isDunderName(name)) {
844
- // Don't offer suggestions for built-in properties like "__class__", etc.
845
- isProperty = false;
846
- }
847
- if (!(0, types_1.isFunction)(declaredType) && !isProperty) {
848
- return;
849
- }
850
- if (isProperty) {
851
- // For properties, we should override the "getter", which is typically
852
- // the first declaration.
853
- const typedDecls = symbol.getTypedDeclarations();
854
- if (typedDecls.length > 0 && typedDecls[0].type === 5 /* Function */) {
855
- decl = typedDecls[0];
856
- }
857
- }
858
- const isDeclaredStaticMethod = (0, types_1.isFunction)(declaredType) && types_1.FunctionType.isStaticMethod(declaredType);
859
- // Special-case the "__init__subclass__" method because it's an implicit
860
- // classmethod that the type evaluator flags as a real classmethod.
861
- const isDeclaredClassMethod = (0, types_1.isFunction)(declaredType) &&
862
- types_1.FunctionType.isClassMethod(declaredType) &&
863
- name !== '__init_subclass__';
864
- if (staticmethod !== isDeclaredStaticMethod || classmethod !== isDeclaredClassMethod) {
865
- return;
866
- }
867
- const methodSignature = this._printMethodSignature(classResults.classType, decl);
868
- let text;
869
- if ((0, sourceMapper_1.isStubFile)(this._filePath)) {
870
- text = `${methodSignature}: ...`;
871
- }
872
- else {
873
- const methodBody = this._printOverriddenMethodBody(classResults.classType, isDeclaredStaticMethod, isProperty, decl);
874
- text = `${methodSignature}:\n${methodBody}`;
875
- }
876
- const textEdit = this._createReplaceEdits(priorWord, partialName, text);
877
- this._addSymbol(name, symbol, partialName.value, completionMap, {
878
- // method signature already contains ()
879
- funcParensDisabled: true,
880
- edits: {
881
- format: this._options.snippet ? vscode_languageserver_1.InsertTextFormat.Snippet : undefined,
882
- textEdit,
883
- },
884
- });
828
+ const fallbackPath = (0, pythonPathUtils_1.getTypeShedFallbackPath)(this._importResolver.fileSystem);
829
+ const typingFilePath = fallbackPath ? (0, pathUtils_1.combinePaths)(fallbackPath, 'stdlib/typing.pyi') : undefined;
830
+ const appendMember = (map, member, name) => {
831
+ if (!(0, types_1.isInstantiableClass)(member.classType) ||
832
+ member.classType.details === classResults.classType.details ||
833
+ !StringUtils.isPatternInSymbol(partialName.value, name)) {
834
+ // Quick bail out if member is something we don't want to override.
835
+ return;
836
+ }
837
+ const symbol = member.symbol;
838
+ const decl = (0, symbolUtils_1.getLastTypedDeclaredForSymbol)(symbol);
839
+ if (!decl || decl.type !== 5 /* Function */) {
840
+ return;
841
+ }
842
+ const declaredType = this._evaluator.getTypeOfMember(member);
843
+ if (!declaredType) {
844
+ return;
845
+ }
846
+ const isDeclaredStaticMethod = (0, types_1.isFunction)(declaredType) && types_1.FunctionType.isStaticMethod(declaredType);
847
+ // Special-case the "__init__subclass__" method because it's an implicit
848
+ // classmethod that the type evaluator flags as a real classmethod.
849
+ const isDeclaredClassMethod = (0, types_1.isFunction)(declaredType) && types_1.FunctionType.isClassMethod(declaredType) && name !== '__init_subclass__';
850
+ if (staticmethod !== isDeclaredStaticMethod || classmethod !== isDeclaredClassMethod) {
851
+ return;
852
+ }
853
+ let isProperty = (0, types_1.isClassInstance)(declaredType) && types_1.ClassType.isPropertyClass(declaredType);
854
+ if (SymbolNameUtils.isDunderName(name)) {
855
+ // Don't offer suggestions for built-in properties like "__class__", etc.
856
+ isProperty = false;
857
+ }
858
+ let funcType = undefined;
859
+ if ((0, types_1.isFunction)(declaredType)) {
860
+ funcType = declaredType;
861
+ }
862
+ else if (isProperty) {
863
+ const getter = (0, typeUtils_1.lookUpClassMember)(declaredType, 'fget');
864
+ if (!getter) {
865
+ return;
866
+ }
867
+ const member = this._evaluator.getTypeOfMember(getter);
868
+ if (!(0, types_1.isFunction)(member)) {
869
+ return;
885
870
  }
871
+ funcType = member;
886
872
  }
887
- });
873
+ if (!funcType || !funcType.details.declaration) {
874
+ return;
875
+ }
876
+ const importAdder = new importAdder_1.ImportAdder(this._configOptions, this._importResolver, this._evaluator);
877
+ const result = this._printMethodSignature(importAdder, classResults.classType, funcType, typingFilePath);
878
+ let text;
879
+ if ((0, sourceMapper_1.isStubFile)(this._filePath)) {
880
+ text = `${result.methodSignature}: ...`;
881
+ }
882
+ else {
883
+ const methodBody = this._printOverriddenMethodBody(classResults.classType, isDeclaredStaticMethod, isProperty, decl);
884
+ text = `${result.methodSignature}:\n${methodBody}`;
885
+ }
886
+ const textEdit = this._createReplaceEdits(priorWord, partialName, text);
887
+ // This will add new import statements, but for now, it won't add new
888
+ // `TypeVar` statement such as TypeVar, TypeVarTuple, ParamSpec even if
889
+ // the overridden method uses them.
890
+ const additionalTextEdits = importAdder.applyImports(result.importData, this._filePath, this._parseResults, this._parseResults.parseTree.length, "absolute" /* Absolute */, this._cancellationToken);
891
+ this._addSymbol(name, symbol, partialName.value, map, {
892
+ // method signature already contains ()
893
+ funcParensDisabled: true,
894
+ edits: {
895
+ format: this._options.snippet ? vscode_languageserver_1.InsertTextFormat.Snippet : undefined,
896
+ textEdit,
897
+ additionalTextEdits,
898
+ },
899
+ });
900
+ };
901
+ const completionMap = new CompletionMap();
902
+ const classMemberMap = (0, typeUtils_1.getClassFieldsRecursive)(classResults.classType);
903
+ classMemberMap.forEach((member, name) => appendMember(completionMap, member, name));
904
+ if (classResults.classType.details.effectiveMetaclass &&
905
+ !(0, types_1.isUnknown)(classResults.classType.details.effectiveMetaclass)) {
906
+ const metaClassMemberMap = (0, typeUtils_1.getClassFieldsRecursive)(classResults.classType.details.effectiveMetaclass);
907
+ metaClassMemberMap.forEach((member, name) => appendMember(completionMap, member, name));
908
+ }
888
909
  return { completionMap };
889
910
  }
890
911
  _createReplaceEdits(priorWord, node, text) {
@@ -897,23 +918,34 @@ class CompletionProvider {
897
918
  };
898
919
  return vscode_languageserver_1.TextEdit.replace(range, text);
899
920
  }
900
- _printMethodSignature(classType, decl) {
901
- const node = decl.node;
921
+ _printMethodSignature(importAdder, classType, funcType, typingFilePath) {
922
+ const declaration = funcType.details.declaration;
902
923
  let ellipsisForDefault;
903
924
  if ((0, sourceMapper_1.isStubFile)(this._filePath)) {
904
925
  // In stubs, always use "...".
905
926
  ellipsisForDefault = true;
906
927
  }
907
- else if (classType.details.moduleName === decl.moduleName) {
928
+ else if (classType.details.moduleName === declaration.moduleName) {
908
929
  // In the same file, always print the full default.
909
930
  ellipsisForDefault = false;
910
931
  }
911
- const printFlags = (0, sourceMapper_1.isStubFile)(this._filePath)
932
+ const printOptionsUsingSyntax = (0, sourceMapper_1.isStubFile)(this._filePath)
912
933
  ? 1 /* ForwardDeclarations */ |
913
934
  2 /* DoNotLimitStringLength */
914
935
  : 2 /* DoNotLimitStringLength */;
915
- const paramList = node.parameters
916
- .map((param, index) => {
936
+ const printOptionsUsingType = {
937
+ enforcePythonSyntax: true,
938
+ expandTypeAlias: false,
939
+ omitTypeArgumentsIfUnknown: true,
940
+ printUnknownWithAny: true,
941
+ };
942
+ const getTypeToPrint = (mainType, fallbackType) => {
943
+ return mainType && (!(0, types_1.isUnknown)(mainType) || (fallbackType === null || fallbackType === void 0 ? void 0 : fallbackType.category) === 10 /* TypeVar */)
944
+ ? mainType
945
+ : fallbackType;
946
+ };
947
+ const importData = createImportData(importAdder, funcType, declaration, typingFilePath, (t) => this._sourceMapper.findClassDeclarationsByType(this._filePath, t), this._cancellationToken);
948
+ const paramList = funcType.details.parameters.map((param, index) => {
917
949
  let paramString = '';
918
950
  if (param.category === 1 /* VarArgList */) {
919
951
  paramString += '*';
@@ -922,35 +954,169 @@ class CompletionProvider {
922
954
  paramString += '**';
923
955
  }
924
956
  if (param.name) {
925
- paramString += param.name.value;
957
+ paramString += param.name;
958
+ }
959
+ if (param.typeAnnotation) {
960
+ const originalType = funcType.details.parameters[index].type;
961
+ const typeToPrint = getTypeToPrint(types_1.FunctionType.getEffectiveParameterType(funcType, index), originalType);
962
+ // If we have actual type, then use type to generate string representation of the type, otherwise, use syntax (text).
963
+ const strType = isTypeUsableForPrint(typeToPrint, originalType)
964
+ ? this._evaluator.printType(typeToPrint, printOptionsUsingType)
965
+ : ParseTreeUtils.printExpression(param.typeAnnotation, printOptionsUsingSyntax);
966
+ paramString += ': ' + strType;
967
+ }
968
+ if (param.defaultValueExpression) {
969
+ paramString += param.typeAnnotation ? ' = ' : '=';
970
+ const useEllipsis = ellipsisForDefault !== null && ellipsisForDefault !== void 0 ? ellipsisForDefault : !isSimpleDefault(param.defaultValueExpression);
971
+ paramString += useEllipsis
972
+ ? '...'
973
+ : ParseTreeUtils.printExpression(param.defaultValueExpression, printOptionsUsingSyntax);
974
+ }
975
+ if (!paramString &&
976
+ !param.name &&
977
+ param.category === 0 /* Simple */ &&
978
+ index < funcType.details.parameters.length - 1) {
979
+ return '/';
926
980
  }
927
- // Currently, we don't automatically add import if the type used in the annotation is not imported
928
- // in current file.
929
- const paramTypeAnnotation = ParseTreeUtils.getTypeAnnotationForParameter(node, index);
930
- if (paramTypeAnnotation) {
931
- paramString += ': ' + ParseTreeUtils.printExpression(paramTypeAnnotation, printFlags);
981
+ return paramString;
982
+ });
983
+ // Remove empty parameters at the end.
984
+ for (let i = paramList.length - 1; i >= 0; i--) {
985
+ if (paramList[i] !== '') {
986
+ break;
932
987
  }
933
- if (param.defaultValue) {
934
- paramString += paramTypeAnnotation ? ' = ' : '=';
935
- const useEllipsis = ellipsisForDefault !== null && ellipsisForDefault !== void 0 ? ellipsisForDefault : !isSimpleDefault(param.defaultValue);
936
- paramString += useEllipsis ? '...' : ParseTreeUtils.printExpression(param.defaultValue, printFlags);
988
+ paramList.pop();
989
+ }
990
+ let methodSignature = funcType.details.name + '(' + paramList.join(', ') + ')';
991
+ const strReturnType = getReturnTypeStr(this._evaluator, funcType, printOptionsUsingSyntax);
992
+ if (strReturnType) {
993
+ methodSignature += ' -> ' + strReturnType;
994
+ }
995
+ return { methodSignature, importData };
996
+ function createImportData(importAdder, funcType, declaration, typingFilePath, declarationGetter, token) {
997
+ var _a, _b;
998
+ // Handle regular case. In this case, we can get import info from
999
+ // import used in the file where the function is declared.
1000
+ const ranges = [];
1001
+ (0, collectionUtils_1.addIfNotNull)(ranges, textRange_2.TextRange.combine(declaration.node.parameters));
1002
+ (0, collectionUtils_1.addIfNotNull)(ranges, declaration.node.returnTypeAnnotation);
1003
+ (0, collectionUtils_1.addIfNotNull)(ranges, declaration.node.functionAnnotationComment);
1004
+ const moduleNode = ParseTreeUtils.getModuleNode(declaration.node);
1005
+ const importData = importAdder.collectImportsForSymbolsUsed(moduleNode, ranges, token);
1006
+ // Handle special case where function has type arguments. In this case,
1007
+ // we can't use the file the function is declared in because it doesn't
1008
+ // have those type arguments. It just has the type vars.
1009
+ // We could walk the mro to discover imports for the type arguments, but
1010
+ // for now, instead, this creates import statement out of type arguments itself.
1011
+ const effectiveTypes = [];
1012
+ funcType.details.parameters.forEach((param, index) => {
1013
+ if (!param.typeAnnotation) {
1014
+ return;
1015
+ }
1016
+ const originalType = funcType.details.parameters[index].type;
1017
+ if (!(0, types_1.isTypeVar)(originalType)) {
1018
+ return;
1019
+ }
1020
+ const effectiveType = types_1.FunctionType.getEffectiveParameterType(funcType, index);
1021
+ effectiveTypes.push([effectiveType, param.typeAnnotation]);
1022
+ });
1023
+ const node = declaration.node;
1024
+ const originalType = funcType.details.declaredReturnType;
1025
+ if (originalType &&
1026
+ (0, types_1.isTypeVar)(originalType) &&
1027
+ (node.returnTypeAnnotation || ((_a = node.functionAnnotationComment) === null || _a === void 0 ? void 0 : _a.returnTypeAnnotation))) {
1028
+ effectiveTypes.push([
1029
+ types_1.FunctionType.getSpecializedReturnType(funcType),
1030
+ (_b = node.returnTypeAnnotation) !== null && _b !== void 0 ? _b : node.functionAnnotationComment.returnTypeAnnotation,
1031
+ ]);
1032
+ }
1033
+ const visited = new Set();
1034
+ const addImport = (t, n) => {
1035
+ var _a, _b;
1036
+ if (visited.has(t)) {
1037
+ return;
1038
+ }
1039
+ visited.add(t);
1040
+ // We need to special case `Any` since we can't get decl from `Any`.
1041
+ if ((0, types_1.isAny)(t)) {
1042
+ if (!typingFilePath) {
1043
+ return;
1044
+ }
1045
+ importAdder.addImportInfo({ filePath: typingFilePath, nameInfo: { name: 'Any' } }, importData);
1046
+ }
1047
+ if (!(0, types_1.isClass)(t)) {
1048
+ return;
1049
+ }
1050
+ // We need to special case `List`, `Dict` and `Tuple` since user might have
1051
+ // used typing.List or typing.Dict in the code, but we internally already
1052
+ // converted them to built-in `list` and `dict`.
1053
+ // We could avoid doing this if class type holds onto decl it was created from
1054
+ // if it is not synthesized like func type.
1055
+ if (typingFilePath && types_1.ClassType.isBuiltIn(t)) {
1056
+ const name = (_a = t.aliasName) !== null && _a !== void 0 ? _a : t.details.name;
1057
+ if (t.details.moduleName === 'typing' && name) {
1058
+ importAdder.addImportInfo({
1059
+ filePath: typingFilePath,
1060
+ nameInfo: { name },
1061
+ }, importData);
1062
+ }
1063
+ else if (t.details.moduleName === 'builtins' && t.aliasName) {
1064
+ importAdder.addImportInfo({
1065
+ filePath: typingFilePath,
1066
+ nameInfo: { name },
1067
+ }, importData);
1068
+ }
1069
+ }
1070
+ else {
1071
+ const decls = declarationGetter(t);
1072
+ if (decls.length === 0) {
1073
+ return;
1074
+ }
1075
+ importAdder.addDeclaration(decls[0], n, importData);
1076
+ }
1077
+ if (t.isTypeArgumentExplicit) {
1078
+ (_b = t.typeArguments) === null || _b === void 0 ? void 0 : _b.forEach((ta) => {
1079
+ addImport(ta, n);
1080
+ (0, typeUtils_1.doForEachSubtype)(ta, (subtype) => {
1081
+ addImport(subtype, n);
1082
+ });
1083
+ });
1084
+ }
1085
+ };
1086
+ effectiveTypes.forEach(([t, n]) => {
1087
+ addImport(t, n);
1088
+ (0, typeUtils_1.doForEachSubtype)(t, (subtype) => {
1089
+ addImport(subtype, n);
1090
+ });
1091
+ });
1092
+ return importData;
1093
+ }
1094
+ function getReturnTypeStr(evaluator, funcType, printFlags) {
1095
+ var _a;
1096
+ const originalType = funcType.details.declaredReturnType;
1097
+ const typeToPrint = getTypeToPrint(types_1.FunctionType.getSpecializedReturnType(funcType), originalType);
1098
+ const node = funcType.details.declaration.node;
1099
+ if (!node.returnTypeAnnotation && !((_a = node.functionAnnotationComment) === null || _a === void 0 ? void 0 : _a.returnTypeAnnotation)) {
1100
+ return undefined;
937
1101
  }
938
- if (!paramString && !param.name && param.category === 0 /* Simple */) {
939
- return '/';
1102
+ if (typeToPrint && isTypeUsableForPrint(typeToPrint, originalType)) {
1103
+ return evaluator.printType(typeToPrint, printOptionsUsingType);
940
1104
  }
941
- return paramString;
942
- })
943
- .join(', ');
944
- let methodSignature = node.name.value + '(' + paramList + ')';
945
- if (node.returnTypeAnnotation) {
946
- methodSignature += ' -> ' + ParseTreeUtils.printExpression(node.returnTypeAnnotation, printFlags);
947
- }
948
- else if (node.functionAnnotationComment) {
949
- methodSignature +=
950
- ' -> ' +
951
- ParseTreeUtils.printExpression(node.functionAnnotationComment.returnTypeAnnotation, printFlags);
952
- }
953
- return methodSignature;
1105
+ if (node.returnTypeAnnotation) {
1106
+ return ParseTreeUtils.printExpression(node.returnTypeAnnotation, printFlags);
1107
+ }
1108
+ if (node.functionAnnotationComment) {
1109
+ return ParseTreeUtils.printExpression(node.functionAnnotationComment.returnTypeAnnotation, printFlags);
1110
+ }
1111
+ return undefined;
1112
+ }
1113
+ function isTypeUsableForPrint(effectiveType, originalType) {
1114
+ if (!effectiveType) {
1115
+ return false;
1116
+ }
1117
+ // If original type was `TypeVar`, we want to use `Unknown` as `Any`
1118
+ return !(0, types_1.isUnknown)(effectiveType) || (originalType === null || originalType === void 0 ? void 0 : originalType.category) === 10 /* TypeVar */;
1119
+ }
954
1120
  function isSimpleDefault(node) {
955
1121
  switch (node.nodeType) {
956
1122
  case 40 /* Number */:
@@ -1873,7 +2039,7 @@ class CompletionProvider {
1873
2039
  }
1874
2040
  _addSymbolsForSymbolTable(symbolTable, includeSymbolCallback, priorWord, node, isInImport, boundObjectOrClass, completionMap) {
1875
2041
  const insideTypeAnnotation = ParseTreeUtils.isWithinAnnotationComment(node) ||
1876
- ParseTreeUtils.isWithinTypeAnnotation(node, /*requireQuotedAnnotation*/ false);
2042
+ ParseTreeUtils.isWithinTypeAnnotation(node, /* requireQuotedAnnotation */ false);
1877
2043
  symbolTable.forEach((symbol, name) => {
1878
2044
  // If there are no declarations or the symbol is not
1879
2045
  // exported from this scope, don't include it in the