@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.
- package/dist/analyzer/binder.js +12 -3
- package/dist/analyzer/binder.js.map +1 -1
- package/dist/analyzer/checker.d.ts +4 -0
- package/dist/analyzer/checker.js +191 -36
- package/dist/analyzer/checker.js.map +1 -1
- package/dist/analyzer/codeFlowEngine.js +6 -6
- package/dist/analyzer/codeFlowEngine.js.map +1 -1
- package/dist/analyzer/constraintSolver.js +11 -1
- package/dist/analyzer/constraintSolver.js.map +1 -1
- package/dist/analyzer/dataClasses.js +2 -2
- package/dist/analyzer/dataClasses.js.map +1 -1
- package/dist/analyzer/decorators.js +9 -9
- package/dist/analyzer/decorators.js.map +1 -1
- package/dist/analyzer/importResolver.d.ts +2 -2
- package/dist/analyzer/importResolver.js +93 -24
- package/dist/analyzer/importResolver.js.map +1 -1
- package/dist/analyzer/namedTuples.js +13 -5
- package/dist/analyzer/namedTuples.js.map +1 -1
- package/dist/analyzer/operations.js +4 -3
- package/dist/analyzer/operations.js.map +1 -1
- package/dist/analyzer/parseTreeUtils.js +37 -0
- package/dist/analyzer/parseTreeUtils.js.map +1 -1
- package/dist/analyzer/patternMatching.js +4 -4
- package/dist/analyzer/patternMatching.js.map +1 -1
- package/dist/analyzer/program.js +1 -1
- package/dist/analyzer/program.js.map +1 -1
- package/dist/analyzer/protocols.d.ts +2 -0
- package/dist/analyzer/protocols.js +90 -14
- package/dist/analyzer/protocols.js.map +1 -1
- package/dist/analyzer/scopeUtils.d.ts +1 -0
- package/dist/analyzer/scopeUtils.js +12 -1
- package/dist/analyzer/scopeUtils.js.map +1 -1
- package/dist/analyzer/service.d.ts +1 -1
- package/dist/analyzer/service.js +7 -6
- package/dist/analyzer/service.js.map +1 -1
- package/dist/analyzer/sourceFile.d.ts +2 -2
- package/dist/analyzer/sourceFile.js +5 -5
- package/dist/analyzer/sourceFile.js.map +1 -1
- package/dist/analyzer/sourceFileInfoUtils.js +1 -1
- package/dist/analyzer/sourceFileInfoUtils.js.map +1 -1
- package/dist/analyzer/typeEvaluator.js +399 -223
- package/dist/analyzer/typeEvaluator.js.map +1 -1
- package/dist/analyzer/typeEvaluatorTypes.d.ts +5 -3
- package/dist/analyzer/typeEvaluatorTypes.js +4 -4
- package/dist/analyzer/typeEvaluatorTypes.js.map +1 -1
- package/dist/analyzer/typeGuards.js +22 -13
- package/dist/analyzer/typeGuards.js.map +1 -1
- package/dist/analyzer/typePrinter.js +4 -2
- package/dist/analyzer/typePrinter.js.map +1 -1
- package/dist/analyzer/typeUtils.d.ts +2 -1
- package/dist/analyzer/typeUtils.js +19 -1
- package/dist/analyzer/typeUtils.js.map +1 -1
- package/dist/analyzer/types.d.ts +10 -6
- package/dist/analyzer/types.js +41 -26
- package/dist/analyzer/types.js.map +1 -1
- package/dist/backgroundAnalysisBase.d.ts +12 -11
- package/dist/backgroundAnalysisBase.js +62 -65
- package/dist/backgroundAnalysisBase.js.map +1 -1
- package/dist/backgroundThreadBase.d.ts +6 -4
- package/dist/backgroundThreadBase.js +64 -54
- package/dist/backgroundThreadBase.js.map +1 -1
- package/dist/commands/quickActionCommand.js +1 -1
- package/dist/commands/quickActionCommand.js.map +1 -1
- package/dist/common/cancellationUtils.d.ts +6 -3
- package/dist/common/cancellationUtils.js +29 -5
- package/dist/common/cancellationUtils.js.map +1 -1
- package/dist/common/commandUtils.d.ts +2 -0
- package/dist/common/commandUtils.js +24 -0
- package/dist/common/commandUtils.js.map +1 -0
- package/dist/common/extensibility.d.ts +7 -6
- package/dist/common/extensibility.js.map +1 -1
- package/dist/common/fileBasedCancellationUtils.js +19 -13
- package/dist/common/fileBasedCancellationUtils.js.map +1 -1
- package/dist/common/fullAccessHost.d.ts +1 -1
- package/dist/common/fullAccessHost.js +2 -2
- package/dist/common/fullAccessHost.js.map +1 -1
- package/dist/common/host.d.ts +2 -2
- package/dist/common/host.js.map +1 -1
- package/dist/common/realFileSystem.js +52 -20
- package/dist/common/realFileSystem.js.map +1 -1
- package/dist/common/serviceProvider.js +8 -1
- package/dist/common/serviceProvider.js.map +1 -1
- package/dist/common/uri/baseUri.d.ts +4 -1
- package/dist/common/uri/baseUri.js +7 -1
- package/dist/common/uri/baseUri.js.map +1 -1
- package/dist/common/uri/emptyUri.d.ts +3 -0
- package/dist/common/uri/emptyUri.js +9 -0
- package/dist/common/uri/emptyUri.js.map +1 -1
- package/dist/common/uri/fileUri.d.ts +2 -0
- package/dist/common/uri/fileUri.js +6 -0
- package/dist/common/uri/fileUri.js.map +1 -1
- package/dist/common/uri/memoization.js +1 -1
- package/dist/common/uri/memoization.js.map +1 -1
- package/dist/common/uri/uri.d.ts +4 -1
- package/dist/common/uri/uri.js +5 -2
- package/dist/common/uri/uri.js.map +1 -1
- package/dist/common/uri/uriUtils.d.ts +2 -0
- package/dist/common/uri/uriUtils.js +18 -1
- package/dist/common/uri/uriUtils.js.map +1 -1
- package/dist/common/uri/webUri.d.ts +2 -0
- package/dist/common/uri/webUri.js +7 -1
- package/dist/common/uri/webUri.js.map +1 -1
- package/dist/common/workspaceEditUtils.d.ts +6 -5
- package/dist/common/workspaceEditUtils.js +18 -17
- package/dist/common/workspaceEditUtils.js.map +1 -1
- package/dist/languageServerBase.d.ts +1 -0
- package/dist/languageServerBase.js +28 -25
- package/dist/languageServerBase.js.map +1 -1
- package/dist/languageService/analyzerServiceExecutor.d.ts +1 -2
- package/dist/languageService/analyzerServiceExecutor.js +6 -5
- package/dist/languageService/analyzerServiceExecutor.js.map +1 -1
- package/dist/languageService/autoImporter.js +3 -3
- package/dist/languageService/autoImporter.js.map +1 -1
- package/dist/languageService/callHierarchyProvider.js +9 -7
- package/dist/languageService/callHierarchyProvider.js.map +1 -1
- package/dist/languageService/codeActionProvider.js +3 -2
- package/dist/languageService/codeActionProvider.js.map +1 -1
- package/dist/languageService/completionProvider.d.ts +2 -4
- package/dist/languageService/completionProvider.js +14 -18
- package/dist/languageService/completionProvider.js.map +1 -1
- package/dist/languageService/documentSymbolProvider.js +5 -4
- package/dist/languageService/documentSymbolProvider.js.map +1 -1
- package/dist/languageService/navigationUtils.js +2 -1
- package/dist/languageService/navigationUtils.js.map +1 -1
- package/dist/languageService/renameProvider.js +2 -2
- package/dist/languageService/renameProvider.js.map +1 -1
- package/dist/languageService/workspaceSymbolProvider.js +2 -1
- package/dist/languageService/workspaceSymbolProvider.js.map +1 -1
- package/dist/localization/localize.d.ts +32 -4
- package/dist/localization/localize.js +15 -2
- package/dist/localization/localize.js.map +1 -1
- package/dist/localization/package.nls.cs.json +19 -4
- package/dist/localization/package.nls.de.json +19 -4
- package/dist/localization/package.nls.en-us.json +16 -3
- package/dist/localization/package.nls.es.json +19 -4
- package/dist/localization/package.nls.fr.json +18 -3
- package/dist/localization/package.nls.it.json +19 -4
- package/dist/localization/package.nls.ja.json +19 -4
- package/dist/localization/package.nls.ko.json +19 -4
- package/dist/localization/package.nls.pl.json +19 -4
- package/dist/localization/package.nls.pt-br.json +19 -4
- package/dist/localization/package.nls.qps-ploc.json +19 -4
- package/dist/localization/package.nls.ru.json +18 -3
- package/dist/localization/package.nls.tr.json +19 -4
- package/dist/localization/package.nls.zh-cn.json +19 -4
- package/dist/localization/package.nls.zh-tw.json +19 -4
- package/dist/parser/parser.d.ts +0 -3
- package/dist/parser/parser.js.map +1 -1
- package/dist/parser/tokenizer.d.ts +2 -4
- package/dist/parser/tokenizer.js +5 -6
- package/dist/parser/tokenizer.js.map +1 -1
- package/dist/parser/tokenizerTypes.d.ts +2 -2
- package/dist/parser/tokenizerTypes.js.map +1 -1
- package/dist/pyright.js +3 -3
- package/dist/pyright.js.map +1 -1
- package/dist/tests/chainedSourceFiles.test.js +8 -8
- package/dist/tests/chainedSourceFiles.test.js.map +1 -1
- package/dist/tests/completions.test.js +3 -3
- package/dist/tests/completions.test.js.map +1 -1
- package/dist/tests/config.test.js +10 -2
- package/dist/tests/config.test.js.map +1 -1
- package/dist/tests/filesystem.test.js +4 -4
- package/dist/tests/filesystem.test.js.map +1 -1
- package/dist/tests/fourSlashParser.test.js +22 -8
- package/dist/tests/fourSlashParser.test.js.map +1 -1
- package/dist/tests/fourslash/rename.multipleDecl.fourslash.d.ts +1 -1
- package/dist/tests/harness/fourslash/fourSlashParser.js +4 -0
- package/dist/tests/harness/fourslash/fourSlashParser.js.map +1 -1
- package/dist/tests/harness/fourslash/fourSlashTypes.d.ts +3 -0
- package/dist/tests/harness/fourslash/fourSlashTypes.js.map +1 -1
- package/dist/tests/harness/fourslash/testState.d.ts +13 -0
- package/dist/tests/harness/fourslash/testState.js +13 -8
- package/dist/tests/harness/fourslash/testState.js.map +1 -1
- package/dist/tests/harness/vfs/factory.d.ts +1 -1
- package/dist/tests/harness/vfs/factory.js +4 -4
- package/dist/tests/harness/vfs/factory.js.map +1 -1
- package/dist/tests/importStatementUtils.test.js +1 -1
- package/dist/tests/importStatementUtils.test.js.map +1 -1
- package/dist/tests/ipythonMode.test.js +11 -12
- package/dist/tests/ipythonMode.test.js.map +1 -1
- package/dist/tests/localizer.test.js +1 -1
- package/dist/tests/localizer.test.js.map +1 -1
- package/dist/tests/serialization.test.d.ts +2 -0
- package/dist/tests/serialization.test.js +88 -0
- package/dist/tests/serialization.test.js.map +1 -0
- package/dist/tests/service.test.js +1 -1
- package/dist/tests/service.test.js.map +1 -1
- package/dist/tests/signatureHelp.test.js +2 -3
- package/dist/tests/signatureHelp.test.js.map +1 -1
- package/dist/tests/sourceFile.test.js +3 -3
- package/dist/tests/sourceFile.test.js.map +1 -1
- package/dist/tests/sourceMapperUtils.test.js +2 -2
- package/dist/tests/sourceMapperUtils.test.js.map +1 -1
- package/dist/tests/testState.test.js +1 -1
- package/dist/tests/testState.test.js.map +1 -1
- package/dist/tests/testStateUtils.js +2 -2
- package/dist/tests/testStateUtils.js.map +1 -1
- package/dist/tests/textEditUtil.test.js +1 -2
- package/dist/tests/textEditUtil.test.js.map +1 -1
- package/dist/tests/typeEvaluator1.test.js +13 -1
- package/dist/tests/typeEvaluator1.test.js.map +1 -1
- package/dist/tests/typeEvaluator2.test.js +17 -5
- package/dist/tests/typeEvaluator2.test.js.map +1 -1
- package/dist/tests/typeEvaluator3.test.js +9 -3
- package/dist/tests/typeEvaluator3.test.js.map +1 -1
- package/dist/tests/typeEvaluator4.test.js +10 -6
- package/dist/tests/typeEvaluator4.test.js.map +1 -1
- package/dist/tests/uri.test.js +37 -7
- package/dist/tests/uri.test.js.map +1 -1
- package/dist/tests/workspaceEditUtils.test.js +8 -8
- package/dist/tests/workspaceEditUtils.test.js.map +1 -1
- package/dist/workspaceFactory.js +1 -1
- package/dist/workspaceFactory.js.map +1 -1
- package/package.json +2 -1
package/dist/analyzer/checker.js
CHANGED
@@ -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:
|
166
|
-
baseType:
|
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 (
|
3400
|
-
if (!
|
3401
|
-
|
3402
|
-
|
3403
|
-
|
3404
|
-
|
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
|
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
|
-
}),
|
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(),
|
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(), (
|
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
|
-
}), (
|
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);
|