@zzzen/pyright-internal 1.2.0-dev.20231231 → 1.2.0-dev.20240114

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 (214) hide show
  1. package/dist/analyzer/binder.js +12 -3
  2. package/dist/analyzer/binder.js.map +1 -1
  3. package/dist/analyzer/checker.d.ts +4 -0
  4. package/dist/analyzer/checker.js +191 -36
  5. package/dist/analyzer/checker.js.map +1 -1
  6. package/dist/analyzer/codeFlowEngine.js +6 -6
  7. package/dist/analyzer/codeFlowEngine.js.map +1 -1
  8. package/dist/analyzer/constraintSolver.js +11 -1
  9. package/dist/analyzer/constraintSolver.js.map +1 -1
  10. package/dist/analyzer/dataClasses.js +2 -2
  11. package/dist/analyzer/dataClasses.js.map +1 -1
  12. package/dist/analyzer/decorators.js +9 -9
  13. package/dist/analyzer/decorators.js.map +1 -1
  14. package/dist/analyzer/importResolver.d.ts +2 -2
  15. package/dist/analyzer/importResolver.js +93 -24
  16. package/dist/analyzer/importResolver.js.map +1 -1
  17. package/dist/analyzer/namedTuples.js +13 -5
  18. package/dist/analyzer/namedTuples.js.map +1 -1
  19. package/dist/analyzer/operations.js +4 -3
  20. package/dist/analyzer/operations.js.map +1 -1
  21. package/dist/analyzer/parseTreeUtils.js +37 -0
  22. package/dist/analyzer/parseTreeUtils.js.map +1 -1
  23. package/dist/analyzer/patternMatching.js +4 -4
  24. package/dist/analyzer/patternMatching.js.map +1 -1
  25. package/dist/analyzer/program.js +1 -1
  26. package/dist/analyzer/program.js.map +1 -1
  27. package/dist/analyzer/protocols.d.ts +2 -0
  28. package/dist/analyzer/protocols.js +90 -14
  29. package/dist/analyzer/protocols.js.map +1 -1
  30. package/dist/analyzer/scopeUtils.d.ts +1 -0
  31. package/dist/analyzer/scopeUtils.js +12 -1
  32. package/dist/analyzer/scopeUtils.js.map +1 -1
  33. package/dist/analyzer/service.d.ts +1 -1
  34. package/dist/analyzer/service.js +7 -6
  35. package/dist/analyzer/service.js.map +1 -1
  36. package/dist/analyzer/sourceFile.d.ts +2 -2
  37. package/dist/analyzer/sourceFile.js +5 -5
  38. package/dist/analyzer/sourceFile.js.map +1 -1
  39. package/dist/analyzer/sourceFileInfoUtils.js +1 -1
  40. package/dist/analyzer/sourceFileInfoUtils.js.map +1 -1
  41. package/dist/analyzer/typeEvaluator.js +399 -223
  42. package/dist/analyzer/typeEvaluator.js.map +1 -1
  43. package/dist/analyzer/typeEvaluatorTypes.d.ts +5 -3
  44. package/dist/analyzer/typeEvaluatorTypes.js +4 -4
  45. package/dist/analyzer/typeEvaluatorTypes.js.map +1 -1
  46. package/dist/analyzer/typeGuards.js +22 -13
  47. package/dist/analyzer/typeGuards.js.map +1 -1
  48. package/dist/analyzer/typePrinter.js +4 -2
  49. package/dist/analyzer/typePrinter.js.map +1 -1
  50. package/dist/analyzer/typeUtils.d.ts +2 -1
  51. package/dist/analyzer/typeUtils.js +19 -1
  52. package/dist/analyzer/typeUtils.js.map +1 -1
  53. package/dist/analyzer/types.d.ts +10 -6
  54. package/dist/analyzer/types.js +41 -26
  55. package/dist/analyzer/types.js.map +1 -1
  56. package/dist/backgroundAnalysisBase.d.ts +12 -11
  57. package/dist/backgroundAnalysisBase.js +62 -65
  58. package/dist/backgroundAnalysisBase.js.map +1 -1
  59. package/dist/backgroundThreadBase.d.ts +6 -4
  60. package/dist/backgroundThreadBase.js +64 -54
  61. package/dist/backgroundThreadBase.js.map +1 -1
  62. package/dist/commands/quickActionCommand.js +1 -1
  63. package/dist/commands/quickActionCommand.js.map +1 -1
  64. package/dist/common/cancellationUtils.d.ts +6 -3
  65. package/dist/common/cancellationUtils.js +29 -5
  66. package/dist/common/cancellationUtils.js.map +1 -1
  67. package/dist/common/commandUtils.d.ts +2 -0
  68. package/dist/common/commandUtils.js +24 -0
  69. package/dist/common/commandUtils.js.map +1 -0
  70. package/dist/common/extensibility.d.ts +7 -6
  71. package/dist/common/extensibility.js.map +1 -1
  72. package/dist/common/fileBasedCancellationUtils.js +19 -13
  73. package/dist/common/fileBasedCancellationUtils.js.map +1 -1
  74. package/dist/common/fullAccessHost.d.ts +1 -1
  75. package/dist/common/fullAccessHost.js +2 -2
  76. package/dist/common/fullAccessHost.js.map +1 -1
  77. package/dist/common/host.d.ts +2 -2
  78. package/dist/common/host.js.map +1 -1
  79. package/dist/common/realFileSystem.js +52 -20
  80. package/dist/common/realFileSystem.js.map +1 -1
  81. package/dist/common/serviceProvider.js +8 -1
  82. package/dist/common/serviceProvider.js.map +1 -1
  83. package/dist/common/uri/baseUri.d.ts +4 -1
  84. package/dist/common/uri/baseUri.js +7 -1
  85. package/dist/common/uri/baseUri.js.map +1 -1
  86. package/dist/common/uri/emptyUri.d.ts +3 -0
  87. package/dist/common/uri/emptyUri.js +9 -0
  88. package/dist/common/uri/emptyUri.js.map +1 -1
  89. package/dist/common/uri/fileUri.d.ts +2 -0
  90. package/dist/common/uri/fileUri.js +6 -0
  91. package/dist/common/uri/fileUri.js.map +1 -1
  92. package/dist/common/uri/memoization.js +1 -1
  93. package/dist/common/uri/memoization.js.map +1 -1
  94. package/dist/common/uri/uri.d.ts +4 -1
  95. package/dist/common/uri/uri.js +5 -2
  96. package/dist/common/uri/uri.js.map +1 -1
  97. package/dist/common/uri/uriUtils.d.ts +2 -0
  98. package/dist/common/uri/uriUtils.js +18 -1
  99. package/dist/common/uri/uriUtils.js.map +1 -1
  100. package/dist/common/uri/webUri.d.ts +2 -0
  101. package/dist/common/uri/webUri.js +7 -1
  102. package/dist/common/uri/webUri.js.map +1 -1
  103. package/dist/common/workspaceEditUtils.d.ts +6 -5
  104. package/dist/common/workspaceEditUtils.js +18 -17
  105. package/dist/common/workspaceEditUtils.js.map +1 -1
  106. package/dist/languageServerBase.d.ts +1 -0
  107. package/dist/languageServerBase.js +28 -25
  108. package/dist/languageServerBase.js.map +1 -1
  109. package/dist/languageService/analyzerServiceExecutor.d.ts +1 -2
  110. package/dist/languageService/analyzerServiceExecutor.js +6 -5
  111. package/dist/languageService/analyzerServiceExecutor.js.map +1 -1
  112. package/dist/languageService/autoImporter.js +3 -3
  113. package/dist/languageService/autoImporter.js.map +1 -1
  114. package/dist/languageService/callHierarchyProvider.js +9 -7
  115. package/dist/languageService/callHierarchyProvider.js.map +1 -1
  116. package/dist/languageService/codeActionProvider.js +3 -2
  117. package/dist/languageService/codeActionProvider.js.map +1 -1
  118. package/dist/languageService/completionProvider.d.ts +2 -4
  119. package/dist/languageService/completionProvider.js +14 -18
  120. package/dist/languageService/completionProvider.js.map +1 -1
  121. package/dist/languageService/documentSymbolProvider.js +5 -4
  122. package/dist/languageService/documentSymbolProvider.js.map +1 -1
  123. package/dist/languageService/navigationUtils.js +2 -1
  124. package/dist/languageService/navigationUtils.js.map +1 -1
  125. package/dist/languageService/renameProvider.js +2 -2
  126. package/dist/languageService/renameProvider.js.map +1 -1
  127. package/dist/languageService/workspaceSymbolProvider.js +2 -1
  128. package/dist/languageService/workspaceSymbolProvider.js.map +1 -1
  129. package/dist/localization/localize.d.ts +32 -4
  130. package/dist/localization/localize.js +15 -2
  131. package/dist/localization/localize.js.map +1 -1
  132. package/dist/localization/package.nls.cs.json +19 -4
  133. package/dist/localization/package.nls.de.json +19 -4
  134. package/dist/localization/package.nls.en-us.json +16 -3
  135. package/dist/localization/package.nls.es.json +19 -4
  136. package/dist/localization/package.nls.fr.json +18 -3
  137. package/dist/localization/package.nls.it.json +19 -4
  138. package/dist/localization/package.nls.ja.json +19 -4
  139. package/dist/localization/package.nls.ko.json +19 -4
  140. package/dist/localization/package.nls.pl.json +19 -4
  141. package/dist/localization/package.nls.pt-br.json +19 -4
  142. package/dist/localization/package.nls.qps-ploc.json +19 -4
  143. package/dist/localization/package.nls.ru.json +18 -3
  144. package/dist/localization/package.nls.tr.json +19 -4
  145. package/dist/localization/package.nls.zh-cn.json +19 -4
  146. package/dist/localization/package.nls.zh-tw.json +19 -4
  147. package/dist/parser/parser.d.ts +0 -3
  148. package/dist/parser/parser.js.map +1 -1
  149. package/dist/parser/tokenizer.d.ts +2 -4
  150. package/dist/parser/tokenizer.js +5 -6
  151. package/dist/parser/tokenizer.js.map +1 -1
  152. package/dist/parser/tokenizerTypes.d.ts +2 -2
  153. package/dist/parser/tokenizerTypes.js.map +1 -1
  154. package/dist/pyright.js +3 -3
  155. package/dist/pyright.js.map +1 -1
  156. package/dist/tests/chainedSourceFiles.test.js +8 -8
  157. package/dist/tests/chainedSourceFiles.test.js.map +1 -1
  158. package/dist/tests/completions.test.js +3 -3
  159. package/dist/tests/completions.test.js.map +1 -1
  160. package/dist/tests/config.test.js +10 -2
  161. package/dist/tests/config.test.js.map +1 -1
  162. package/dist/tests/filesystem.test.js +4 -4
  163. package/dist/tests/filesystem.test.js.map +1 -1
  164. package/dist/tests/fourSlashParser.test.js +22 -8
  165. package/dist/tests/fourSlashParser.test.js.map +1 -1
  166. package/dist/tests/fourslash/rename.multipleDecl.fourslash.d.ts +1 -1
  167. package/dist/tests/harness/fourslash/fourSlashParser.js +4 -0
  168. package/dist/tests/harness/fourslash/fourSlashParser.js.map +1 -1
  169. package/dist/tests/harness/fourslash/fourSlashTypes.d.ts +3 -0
  170. package/dist/tests/harness/fourslash/fourSlashTypes.js.map +1 -1
  171. package/dist/tests/harness/fourslash/testState.d.ts +13 -0
  172. package/dist/tests/harness/fourslash/testState.js +13 -8
  173. package/dist/tests/harness/fourslash/testState.js.map +1 -1
  174. package/dist/tests/harness/vfs/factory.d.ts +1 -1
  175. package/dist/tests/harness/vfs/factory.js +4 -4
  176. package/dist/tests/harness/vfs/factory.js.map +1 -1
  177. package/dist/tests/importStatementUtils.test.js +1 -1
  178. package/dist/tests/importStatementUtils.test.js.map +1 -1
  179. package/dist/tests/ipythonMode.test.js +11 -12
  180. package/dist/tests/ipythonMode.test.js.map +1 -1
  181. package/dist/tests/localizer.test.js +1 -1
  182. package/dist/tests/localizer.test.js.map +1 -1
  183. package/dist/tests/serialization.test.d.ts +2 -0
  184. package/dist/tests/serialization.test.js +88 -0
  185. package/dist/tests/serialization.test.js.map +1 -0
  186. package/dist/tests/service.test.js +1 -1
  187. package/dist/tests/service.test.js.map +1 -1
  188. package/dist/tests/signatureHelp.test.js +2 -3
  189. package/dist/tests/signatureHelp.test.js.map +1 -1
  190. package/dist/tests/sourceFile.test.js +3 -3
  191. package/dist/tests/sourceFile.test.js.map +1 -1
  192. package/dist/tests/sourceMapperUtils.test.js +2 -2
  193. package/dist/tests/sourceMapperUtils.test.js.map +1 -1
  194. package/dist/tests/testState.test.js +1 -1
  195. package/dist/tests/testState.test.js.map +1 -1
  196. package/dist/tests/testStateUtils.js +2 -2
  197. package/dist/tests/testStateUtils.js.map +1 -1
  198. package/dist/tests/textEditUtil.test.js +1 -2
  199. package/dist/tests/textEditUtil.test.js.map +1 -1
  200. package/dist/tests/typeEvaluator1.test.js +13 -1
  201. package/dist/tests/typeEvaluator1.test.js.map +1 -1
  202. package/dist/tests/typeEvaluator2.test.js +17 -5
  203. package/dist/tests/typeEvaluator2.test.js.map +1 -1
  204. package/dist/tests/typeEvaluator3.test.js +9 -3
  205. package/dist/tests/typeEvaluator3.test.js.map +1 -1
  206. package/dist/tests/typeEvaluator4.test.js +10 -6
  207. package/dist/tests/typeEvaluator4.test.js.map +1 -1
  208. package/dist/tests/uri.test.js +37 -7
  209. package/dist/tests/uri.test.js.map +1 -1
  210. package/dist/tests/workspaceEditUtils.test.js +8 -8
  211. package/dist/tests/workspaceEditUtils.test.js.map +1 -1
  212. package/dist/workspaceFactory.js +1 -1
  213. package/dist/workspaceFactory.js.map +1 -1
  214. package/package.json +2 -1
@@ -60,6 +60,7 @@ const parameterUtils_1 = require("./parameterUtils");
60
60
  const ParseTreeUtils = __importStar(require("./parseTreeUtils"));
61
61
  const parseTreeWalker_1 = require("./parseTreeWalker");
62
62
  const patternMatching_1 = require("./patternMatching");
63
+ const protocols_1 = require("./protocols");
63
64
  const regions_1 = require("./regions");
64
65
  const scopeUtils_1 = require("./scopeUtils");
65
66
  const sourceFile_1 = require("./sourceFile");
@@ -162,8 +163,8 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
162
163
  !types_1.ClassType.isBuiltIn(baseClassType, 'Generic')) {
163
164
  if (!types_1.ClassType.isProtocolClass(baseClassType)) {
164
165
  this._evaluator.addError(localize_1.Localizer.Diagnostic.protocolBaseClass().format({
165
- classType: this._evaluator.printType(classTypeResult.classType),
166
- baseType: this._evaluator.printType(baseClassType),
166
+ classType: classTypeResult.classType.details.name,
167
+ baseType: baseClassType.details.name,
167
168
  }), arg.valueExpression);
168
169
  }
169
170
  }
@@ -179,6 +180,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
179
180
  this._validateSlotsClassVarConflict(classTypeResult.classType);
180
181
  }
181
182
  this._validateBaseClassOverrides(classTypeResult.classType);
183
+ this._validateOverloadDecoratorConsistency(classTypeResult.classType);
182
184
  this._validateMultipleInheritanceBaseClasses(classTypeResult.classType, node.name);
183
185
  this._validateMultipleInheritanceCompatibility(classTypeResult.classType, node.name);
184
186
  this._validateConstructorConsistency(classTypeResult.classType, node.name);
@@ -1952,6 +1954,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
1952
1954
  else if ((0, types_1.isClassInstance)(exceptionType)) {
1953
1955
  const iterableType = (_b = (_a = this._evaluator.getTypeOfIterator({ type: exceptionType }, /* isAsync */ false, errorNode)) === null || _a === void 0 ? void 0 : _a.type) !== null && _b !== void 0 ? _b : types_1.UnknownType.create();
1954
1956
  resultingExceptionType = (0, typeUtils_1.mapSubtypes)(iterableType, (subtype) => {
1957
+ subtype = this._evaluator.makeTopLevelTypeVarsConcrete(subtype);
1955
1958
  if ((0, types_1.isAnyOrUnknown)(subtype) || (0, types_1.isNever)(subtype)) {
1956
1959
  return subtype;
1957
1960
  }
@@ -2546,6 +2549,26 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
2546
2549
  type: this._evaluator.printType(arg1Type),
2547
2550
  }) + diag.getString(), node.arguments[1]);
2548
2551
  }
2552
+ // If this call is an issubclass, check for the use of a "data protocol",
2553
+ // which PEP 544 says cannot be used in issubclass.
2554
+ if (!isInstanceCheck) {
2555
+ const diag = new diagnostic_1.DiagnosticAddendum();
2556
+ (0, typeUtils_1.doForEachSubtype)(arg1Type, (arg1Subtype) => {
2557
+ if ((0, types_1.isClassInstance)(arg1Subtype) &&
2558
+ types_1.ClassType.isTupleClass(arg1Subtype) &&
2559
+ arg1Subtype.tupleTypeArguments) {
2560
+ arg1Subtype.tupleTypeArguments.forEach((typeArg) => {
2561
+ this._validateNotDataProtocol(typeArg.type, diag);
2562
+ });
2563
+ }
2564
+ else {
2565
+ this._validateNotDataProtocol(arg1Subtype, diag);
2566
+ }
2567
+ });
2568
+ if (!diag.isEmpty()) {
2569
+ this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.dataProtocolInSubclassCheck(), node.arguments[1]);
2570
+ }
2571
+ }
2549
2572
  // If this call is within an assert statement, we won't check whether
2550
2573
  // it's unnecessary.
2551
2574
  let curNode = node;
@@ -2581,6 +2604,9 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
2581
2604
  arg1IncludesSubclasses = true;
2582
2605
  }
2583
2606
  }
2607
+ if (arg0Type) {
2608
+ this._validateUnsafeProtocolOverlap(node.arguments[0].valueExpression, (0, typeUtils_1.convertToInstance)(arg1Subtype), isInstanceCheck ? arg0Type : (0, typeUtils_1.convertToInstance)(arg0Type));
2609
+ }
2584
2610
  }
2585
2611
  else {
2586
2612
  // The isinstance and issubclass call supports a variation where the second
@@ -2593,6 +2619,9 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
2593
2619
  if (typeArg.type.includeSubclasses) {
2594
2620
  arg1IncludesSubclasses = true;
2595
2621
  }
2622
+ if (arg0Type) {
2623
+ this._validateUnsafeProtocolOverlap(node.arguments[0].valueExpression, (0, typeUtils_1.convertToInstance)(typeArg.type), isInstanceCheck ? arg0Type : (0, typeUtils_1.convertToInstance)(arg0Type));
2624
+ }
2596
2625
  }
2597
2626
  else {
2598
2627
  isValidType = false;
@@ -2706,6 +2735,29 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
2706
2735
  }), node);
2707
2736
  }
2708
2737
  }
2738
+ _validateUnsafeProtocolOverlap(errorNode, protocol, testType) {
2739
+ // If this is a protocol class, check for an "unsafe overlap"
2740
+ // with the arg0 type.
2741
+ if (types_1.ClassType.isProtocolClass(protocol)) {
2742
+ let isUnsafeOverlap = false;
2743
+ const diag = new diagnostic_1.DiagnosticAddendum();
2744
+ (0, typeUtils_1.doForEachSubtype)(testType, (testSubtype) => {
2745
+ if ((0, types_1.isClassInstance)(testSubtype)) {
2746
+ if ((0, protocols_1.isProtocolUnsafeOverlap)(this._evaluator, protocol, testSubtype)) {
2747
+ isUnsafeOverlap = true;
2748
+ diag.addMessage(localize_1.Localizer.DiagnosticAddendum.protocolUnsafeOverlap().format({
2749
+ name: testSubtype.details.name,
2750
+ }));
2751
+ }
2752
+ }
2753
+ });
2754
+ if (isUnsafeOverlap) {
2755
+ this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.protocolUnsafeOverlap().format({
2756
+ name: protocol.details.name,
2757
+ }) + diag.getString(), errorNode);
2758
+ }
2759
+ }
2760
+ }
2709
2761
  // Determines whether the specified type is allowed as the second argument
2710
2762
  // to an isinstance or issubclass check.
2711
2763
  _isTypeSupportedTypeForIsInstance(type, isInstanceCheck, diag) {
@@ -2713,6 +2765,11 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
2713
2765
  (0, typeUtils_1.doForEachSubtype)(type, (subtype) => {
2714
2766
  subtype = this._evaluator.makeTopLevelTypeVarsConcrete(subtype);
2715
2767
  subtype = (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(subtype);
2768
+ if (subtype.specialForm && types_1.ClassType.isBuiltIn(subtype.specialForm, 'TypeAliasType')) {
2769
+ diag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeAliasInstanceCheck());
2770
+ isSupported = false;
2771
+ return;
2772
+ }
2716
2773
  switch (subtype.category) {
2717
2774
  case 2 /* TypeCategory.Any */:
2718
2775
  case 1 /* TypeCategory.Unknown */:
@@ -2761,6 +2818,13 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
2761
2818
  });
2762
2819
  return isSupported;
2763
2820
  }
2821
+ _validateNotDataProtocol(type, diag) {
2822
+ if ((0, types_1.isInstantiableClass)(type) && types_1.ClassType.isProtocolClass(type) && !(0, protocols_1.isMethodOnlyProtocol)(type)) {
2823
+ diag.addMessage(localize_1.Localizer.DiagnosticAddendum.dataProtocolUnsupported().format({
2824
+ name: type.details.name,
2825
+ }));
2826
+ }
2827
+ }
2764
2828
  _isSymbolPrivate(nameValue, scopeType) {
2765
2829
  // All variables within the scope of a function or a list
2766
2830
  // comprehension are considered private.
@@ -3396,14 +3460,12 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
3396
3460
  }
3397
3461
  }
3398
3462
  else if (decls[0].type === 5 /* DeclarationType.Function */) {
3399
- if (decls.every((decl) => decl.type !== 5 /* DeclarationType.Function */ || ParseTreeUtils.isSuiteEmpty(decl.node.suite))) {
3400
- if (!decls[0].uri.hasExtension('.pyi')) {
3401
- if (!isSymbolImplemented(name)) {
3402
- diagAddendum.addMessage(localize_1.Localizer.DiagnosticAddendum.missingProtocolMember().format({
3403
- name,
3404
- classType: member.classType.details.name,
3405
- }));
3406
- }
3463
+ if (this._isUnimplementedProtocolMethod(member.symbol)) {
3464
+ if (!isSymbolImplemented(name)) {
3465
+ diagAddendum.addMessage(localize_1.Localizer.DiagnosticAddendum.missingProtocolMember().format({
3466
+ name,
3467
+ classType: member.classType.details.name,
3468
+ }));
3407
3469
  }
3408
3470
  }
3409
3471
  }
@@ -3485,6 +3547,42 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
3485
3547
  paramIndex++;
3486
3548
  });
3487
3549
  }
3550
+ // Determine whether a method defined in a protocol should be considered
3551
+ // "unimplemented". This is an under-specified part of the typing spec.
3552
+ _isUnimplementedProtocolMethod(symbol) {
3553
+ const symbolType = this._evaluator.getEffectiveTypeOfSymbol(symbol);
3554
+ // Behavior differs between stub files and source files.
3555
+ const decls = symbol.getDeclarations();
3556
+ const isDeclaredInStubFile = decls.length > 0 && (0, sourceMapper_1.isStubFile)(decls[0].uri);
3557
+ if ((0, types_1.isFunction)(symbolType)) {
3558
+ const decl = symbolType.details.declaration;
3559
+ if (decl) {
3560
+ return isDeclaredInStubFile
3561
+ ? types_1.FunctionType.isAbstractMethod(symbolType)
3562
+ : ParseTreeUtils.isSuiteEmpty(decl.node.suite);
3563
+ }
3564
+ }
3565
+ else if ((0, types_1.isOverloadedFunction)(symbolType)) {
3566
+ // If an implementation is present and has an empty body, assume
3567
+ // the function is unimplemented.
3568
+ const impl = types_1.OverloadedFunctionType.getImplementation(symbolType);
3569
+ if (impl) {
3570
+ const decl = impl.details.declaration;
3571
+ if (decl) {
3572
+ return ParseTreeUtils.isSuiteEmpty(decl.node.suite);
3573
+ }
3574
+ return false;
3575
+ }
3576
+ if (isDeclaredInStubFile) {
3577
+ // If no implementation was present, see if any of the overloads
3578
+ // are marked as abstract.
3579
+ const overloads = types_1.OverloadedFunctionType.getOverloads(symbolType);
3580
+ return overloads.some((overload) => types_1.FunctionType.isAbstractMethod(overload));
3581
+ }
3582
+ return true;
3583
+ }
3584
+ return false;
3585
+ }
3488
3586
  // If a class is marked final, it must implement all abstract methods,
3489
3587
  // otherwise it is of no use.
3490
3588
  _validateFinalClassNotAbstract(classType, errorNode) {
@@ -4094,6 +4192,51 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
4094
4192
  }), overrideDecl.uri, overrideDecl.range);
4095
4193
  }
4096
4194
  }
4195
+ // Validates that any overloaded methods are consistent in how they
4196
+ // are decorated. For example, if the first overload is not marked @final
4197
+ // but subsequent ones are, an error should be reported.
4198
+ _validateOverloadDecoratorConsistency(classType) {
4199
+ classType.details.fields.forEach((symbol, name) => {
4200
+ const primaryDecl = (0, symbolUtils_1.getLastTypedDeclaredForSymbol)(symbol);
4201
+ if (!primaryDecl || primaryDecl.type !== 5 /* DeclarationType.Function */) {
4202
+ return;
4203
+ }
4204
+ const typeOfSymbol = this._evaluator.getEffectiveTypeOfSymbol(symbol);
4205
+ if (!(0, types_1.isOverloadedFunction)(typeOfSymbol)) {
4206
+ return;
4207
+ }
4208
+ const overloads = types_1.OverloadedFunctionType.getOverloads(typeOfSymbol);
4209
+ // If there's an implementation, it will determine whether the
4210
+ // function is @final.
4211
+ const implementation = types_1.OverloadedFunctionType.getImplementation(typeOfSymbol);
4212
+ if (implementation) {
4213
+ // If one or more of the overloads is marked @final but the
4214
+ // implementation is not, report an error.
4215
+ if (!types_1.FunctionType.isFinal(implementation)) {
4216
+ overloads.forEach((overload) => {
4217
+ var _a, _b;
4218
+ if (types_1.FunctionType.isFinal(overload) && ((_a = overload.details.declaration) === null || _a === void 0 ? void 0 : _a.node)) {
4219
+ this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.overloadFinalInconsistencyImpl().format({
4220
+ name: overload.details.name,
4221
+ }), (_b = (0, declarationUtils_1.getNameNodeForDeclaration)(overload.details.declaration)) !== null && _b !== void 0 ? _b : overload.details.declaration.node);
4222
+ }
4223
+ });
4224
+ }
4225
+ return;
4226
+ }
4227
+ if (!types_1.FunctionType.isFinal(overloads[0])) {
4228
+ overloads.slice(1).forEach((overload, index) => {
4229
+ var _a, _b;
4230
+ if (types_1.FunctionType.isFinal(overload) && ((_a = overload.details.declaration) === null || _a === void 0 ? void 0 : _a.node)) {
4231
+ this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.overloadFinalInconsistencyNoImpl().format({
4232
+ name: overload.details.name,
4233
+ index: index + 2,
4234
+ }), (_b = (0, declarationUtils_1.getNameNodeForDeclaration)(overload.details.declaration)) !== null && _b !== void 0 ? _b : overload.details.declaration.node);
4235
+ }
4236
+ });
4237
+ }
4238
+ });
4239
+ }
4097
4240
  // Validates that any overridden methods or variables contain the same
4098
4241
  // types as the original method. Also marks the class as abstract if one
4099
4242
  // or more abstract methods are not overridden.
@@ -4213,7 +4356,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
4213
4356
  this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.overriddenMethodNotFound().format({ name: funcNode.name.value }), funcNode.name);
4214
4357
  }
4215
4358
  _validateBaseClassOverride(baseClassAndSymbol, overrideSymbol, overrideType, childClassType, memberName) {
4216
- var _a, _b;
4359
+ var _a, _b, _c, _d, _e, _f, _g, _h;
4217
4360
  if (!(0, types_1.isInstantiableClass)(baseClassAndSymbol.classType)) {
4218
4361
  return;
4219
4362
  }
@@ -4237,6 +4380,31 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
4237
4380
  overrideType = (0, typeUtils_1.partiallySpecializeType)(overrideType, childClassType, childClassSelf);
4238
4381
  if ((0, types_1.isFunction)(baseType) || (0, types_1.isOverloadedFunction)(baseType)) {
4239
4382
  const diagAddendum = new diagnostic_1.DiagnosticAddendum();
4383
+ // Determine whether this is an attempt to override a method marked @final.
4384
+ let reportFinalMethodOverride = false;
4385
+ // Private names (starting with double underscore) are exempt from this check.
4386
+ if (!SymbolNameUtils.isPrivateName(memberName)) {
4387
+ if ((0, types_1.isFunction)(baseType) && types_1.FunctionType.isFinal(baseType)) {
4388
+ reportFinalMethodOverride = true;
4389
+ }
4390
+ else if ((0, types_1.isOverloadedFunction)(baseType) &&
4391
+ baseType.overloads.some((overload) => types_1.FunctionType.isFinal(overload))) {
4392
+ reportFinalMethodOverride = true;
4393
+ }
4394
+ }
4395
+ if (reportFinalMethodOverride) {
4396
+ const decl = (0, symbolUtils_1.getLastTypedDeclaredForSymbol)(overrideSymbol);
4397
+ if (decl && decl.type === 5 /* DeclarationType.Function */) {
4398
+ const diag = this._evaluator.addError(localize_1.Localizer.Diagnostic.finalMethodOverride().format({
4399
+ name: memberName,
4400
+ className: baseClass.details.name,
4401
+ }), decl.node.name);
4402
+ const origDecl = (0, symbolUtils_1.getLastTypedDeclaredForSymbol)(baseClassAndSymbol.symbol);
4403
+ if (diag && origDecl) {
4404
+ diag.addRelatedInfo(localize_1.Localizer.DiagnosticAddendum.finalMethod(), origDecl.uri, origDecl.range);
4405
+ }
4406
+ }
4407
+ }
4240
4408
  if ((0, types_1.isFunction)(overrideType) || (0, types_1.isOverloadedFunction)(overrideType)) {
4241
4409
  // Don't enforce parameter names for dundered methods. Many of them
4242
4410
  // are misnamed in typeshed stubs, so this would result in many
@@ -4257,7 +4425,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
4257
4425
  const diag = this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportIncompatibleMethodOverride, diagnosticRules_1.DiagnosticRule.reportIncompatibleMethodOverride, localize_1.Localizer.Diagnostic.incompatibleMethodOverride().format({
4258
4426
  name: memberName,
4259
4427
  className: baseClass.details.name,
4260
- }) + diagAddendum.getString(), decl.type === 5 /* DeclarationType.Function */ ? decl.node.name : decl.node);
4428
+ }) + diagAddendum.getString(), (_a = (0, declarationUtils_1.getNameNodeForDeclaration)(decl)) !== null && _a !== void 0 ? _a : decl.node);
4261
4429
  const origDecl = (0, symbolUtils_1.getLastTypedDeclaredForSymbol)(baseClassAndSymbol.symbol);
4262
4430
  if (diag && origDecl) {
4263
4431
  diag.addRelatedInfo(localize_1.Localizer.DiagnosticAddendum.overriddenMethod(), origDecl.uri, origDecl.range);
@@ -4265,22 +4433,6 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
4265
4433
  }
4266
4434
  }
4267
4435
  }
4268
- if ((0, types_1.isFunction)(baseType)) {
4269
- // Private names (starting with double underscore) are exempt from this check.
4270
- if (!SymbolNameUtils.isPrivateName(memberName) && types_1.FunctionType.isFinal(baseType)) {
4271
- const decl = (0, symbolUtils_1.getLastTypedDeclaredForSymbol)(overrideSymbol);
4272
- if (decl && decl.type === 5 /* DeclarationType.Function */) {
4273
- const diag = this._evaluator.addError(localize_1.Localizer.Diagnostic.finalMethodOverride().format({
4274
- name: memberName,
4275
- className: baseClass.details.name,
4276
- }), decl.node.name);
4277
- const origDecl = (0, symbolUtils_1.getLastTypedDeclaredForSymbol)(baseClassAndSymbol.symbol);
4278
- if (diag && origDecl) {
4279
- diag.addRelatedInfo(localize_1.Localizer.DiagnosticAddendum.finalMethod(), origDecl.uri, origDecl.range);
4280
- }
4281
- }
4282
- }
4283
- }
4284
4436
  }
4285
4437
  else if (!(0, types_1.isAnyOrUnknown)(overrideType)) {
4286
4438
  // Special-case overrides of methods in '_TypedDict', since
@@ -4294,7 +4446,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
4294
4446
  name: memberName,
4295
4447
  className: baseClass.details.name,
4296
4448
  type: this._evaluator.printType(overrideType),
4297
- }), lastDecl.node);
4449
+ }), (_b = (0, declarationUtils_1.getNameNodeForDeclaration)(lastDecl)) !== null && _b !== void 0 ? _b : lastDecl.node);
4298
4450
  const origDecl = (0, symbolUtils_1.getLastTypedDeclaredForSymbol)(baseClassAndSymbol.symbol);
4299
4451
  if (diag && origDecl) {
4300
4452
  diag.addRelatedInfo(localize_1.Localizer.DiagnosticAddendum.overriddenMethod(), origDecl.uri, origDecl.range);
@@ -4308,10 +4460,11 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
4308
4460
  if (!(0, typeUtils_1.isProperty)(overrideType)) {
4309
4461
  const decls = overrideSymbol.getDeclarations();
4310
4462
  if (decls.length > 0) {
4463
+ const lastDecl = decls[decls.length - 1];
4311
4464
  this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportIncompatibleMethodOverride, diagnosticRules_1.DiagnosticRule.reportIncompatibleMethodOverride, localize_1.Localizer.Diagnostic.propertyOverridden().format({
4312
4465
  name: memberName,
4313
4466
  className: baseClass.details.name,
4314
- }), decls[decls.length - 1].node);
4467
+ }), (_c = (0, declarationUtils_1.getNameNodeForDeclaration)(lastDecl)) !== null && _c !== void 0 ? _c : lastDecl.node);
4315
4468
  }
4316
4469
  }
4317
4470
  else {
@@ -4322,6 +4475,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
4322
4475
  ['fdel', (c) => { var _a; return (_a = c.fdelInfo) === null || _a === void 0 ? void 0 : _a.methodType; }],
4323
4476
  ];
4324
4477
  propMethodInfo.forEach((info) => {
4478
+ var _a;
4325
4479
  const diagAddendum = new diagnostic_1.DiagnosticAddendum();
4326
4480
  const [methodName, methodAccessor] = info;
4327
4481
  const baseClassPropMethod = methodAccessor(baseType);
@@ -4337,10 +4491,11 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
4337
4491
  }));
4338
4492
  const decls = overrideSymbol.getDeclarations();
4339
4493
  if (decls.length > 0) {
4494
+ const lastDecl = decls[decls.length - 1];
4340
4495
  const diag = this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportIncompatibleMethodOverride, diagnosticRules_1.DiagnosticRule.reportIncompatibleMethodOverride, localize_1.Localizer.Diagnostic.propertyOverridden().format({
4341
4496
  name: memberName,
4342
4497
  className: baseClassType.details.name,
4343
- }) + diagAddendum.getString(), decls[decls.length - 1].node);
4498
+ }) + diagAddendum.getString(), (_a = (0, declarationUtils_1.getNameNodeForDeclaration)(lastDecl)) !== null && _a !== void 0 ? _a : lastDecl.node);
4344
4499
  const origDecl = baseClassMethodType.details.declaration;
4345
4500
  if (diag && origDecl) {
4346
4501
  diag.addRelatedInfo(localize_1.Localizer.DiagnosticAddendum.overriddenMethod(), origDecl.uri, origDecl.range);
@@ -4418,7 +4573,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
4418
4573
  const diag = this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportIncompatibleVariableOverride, diagnosticRules_1.DiagnosticRule.reportIncompatibleVariableOverride, localize_1.Localizer.Diagnostic.symbolOverridden().format({
4419
4574
  name: memberName,
4420
4575
  className: baseClass.details.name,
4421
- }) + diagAddendum.getString(), (_a = (0, declarationUtils_1.getNameNodeForDeclaration)(lastDecl)) !== null && _a !== void 0 ? _a : lastDecl.node);
4576
+ }) + diagAddendum.getString(), (_d = (0, declarationUtils_1.getNameNodeForDeclaration)(lastDecl)) !== null && _d !== void 0 ? _d : lastDecl.node);
4422
4577
  const origDecl = (0, symbolUtils_1.getLastTypedDeclaredForSymbol)(baseClassAndSymbol.symbol);
4423
4578
  if (diag && origDecl) {
4424
4579
  diag.addRelatedInfo(localize_1.Localizer.DiagnosticAddendum.overriddenSymbol(), origDecl.uri, origDecl.range);
@@ -4439,14 +4594,14 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
4439
4594
  const message = overrideTDEntry.isRequired
4440
4595
  ? localize_1.Localizer.Diagnostic.typedDictFieldRequiredRedefinition
4441
4596
  : localize_1.Localizer.Diagnostic.typedDictFieldNotRequiredRedefinition;
4442
- this._evaluator.addDiagnostic(AnalyzerNodeInfo.getFileInfo(lastDecl.node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, message().format({ name: memberName }), lastDecl.node);
4597
+ this._evaluator.addDiagnostic(AnalyzerNodeInfo.getFileInfo(lastDecl.node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, message().format({ name: memberName }), (_e = (0, declarationUtils_1.getNameNodeForDeclaration)(lastDecl)) !== null && _e !== void 0 ? _e : lastDecl.node);
4443
4598
  }
4444
4599
  // Make sure that the derived class isn't marking a previously writable
4445
4600
  // entry as read-only.
4446
4601
  if (!overriddenTDEntry.isReadOnly && overrideTDEntry.isReadOnly) {
4447
4602
  this._evaluator.addDiagnostic(AnalyzerNodeInfo.getFileInfo(lastDecl.node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typedDictFieldReadOnlyRedefinition().format({
4448
4603
  name: memberName,
4449
- }), lastDecl.node);
4604
+ }), (_f = (0, declarationUtils_1.getNameNodeForDeclaration)(lastDecl)) !== null && _f !== void 0 ? _f : lastDecl.node);
4450
4605
  }
4451
4606
  }
4452
4607
  // Verify that there is not a Final mismatch.
@@ -4456,7 +4611,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
4456
4611
  const diag = this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportIncompatibleVariableOverride, diagnosticRules_1.DiagnosticRule.reportIncompatibleVariableOverride, localize_1.Localizer.Diagnostic.variableFinalOverride().format({
4457
4612
  name: memberName,
4458
4613
  className: baseClass.details.name,
4459
- }), lastDecl.node);
4614
+ }), (_g = (0, declarationUtils_1.getNameNodeForDeclaration)(lastDecl)) !== null && _g !== void 0 ? _g : lastDecl.node);
4460
4615
  if (diag) {
4461
4616
  diag.addRelatedInfo(localize_1.Localizer.DiagnosticAddendum.overriddenSymbol(), overrideFinalVarDecl.uri, overrideFinalVarDecl.range);
4462
4617
  }
@@ -4485,7 +4640,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
4485
4640
  const diag = this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportIncompatibleVariableOverride, diagnosticRules_1.DiagnosticRule.reportIncompatibleVariableOverride, unformattedMessage.format({
4486
4641
  name: memberName,
4487
4642
  className: baseClass.details.name,
4488
- }), (_b = (0, declarationUtils_1.getNameNodeForDeclaration)(lastDecl)) !== null && _b !== void 0 ? _b : lastDecl.node);
4643
+ }), (_h = (0, declarationUtils_1.getNameNodeForDeclaration)(lastDecl)) !== null && _h !== void 0 ? _h : lastDecl.node);
4489
4644
  const origDecl = (0, symbolUtils_1.getLastTypedDeclaredForSymbol)(baseClassAndSymbol.symbol);
4490
4645
  if (diag && origDecl) {
4491
4646
  diag.addRelatedInfo(localize_1.Localizer.DiagnosticAddendum.overriddenSymbol(), origDecl.uri, origDecl.range);