@zzzen/pyright-internal 1.2.0-dev.20220703 → 1.2.0-dev.20220724
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/README.md +82 -1
- package/dist/analyzer/analysis.js +1 -1
- package/dist/analyzer/analysis.js.map +1 -1
- package/dist/analyzer/analyzerFileInfo.d.ts +2 -1
- package/dist/analyzer/analyzerFileInfo.js.map +1 -1
- package/dist/analyzer/binder.js +15 -1
- package/dist/analyzer/binder.js.map +1 -1
- package/dist/analyzer/checker.d.ts +1 -0
- package/dist/analyzer/checker.js +100 -51
- package/dist/analyzer/checker.js.map +1 -1
- package/dist/analyzer/codeFlowEngine.d.ts +0 -1
- package/dist/analyzer/codeFlowEngine.js +196 -197
- package/dist/analyzer/codeFlowEngine.js.map +1 -1
- package/dist/analyzer/codeFlowTypes.d.ts +1 -1
- package/dist/analyzer/codeFlowTypes.js.map +1 -1
- package/dist/analyzer/constraintSolver.js +6 -7
- package/dist/analyzer/constraintSolver.js.map +1 -1
- package/dist/analyzer/dataClasses.js +13 -4
- package/dist/analyzer/dataClasses.js.map +1 -1
- package/dist/analyzer/functionTransform.js +2 -1
- package/dist/analyzer/functionTransform.js.map +1 -1
- package/dist/analyzer/importResolver.js +5 -4
- package/dist/analyzer/importResolver.js.map +1 -1
- package/dist/analyzer/importStatementUtils.d.ts +1 -1
- package/dist/analyzer/importStatementUtils.js +47 -18
- package/dist/analyzer/importStatementUtils.js.map +1 -1
- package/dist/analyzer/parseTreeUtils.d.ts +6 -1
- package/dist/analyzer/parseTreeUtils.js +118 -10
- package/dist/analyzer/parseTreeUtils.js.map +1 -1
- package/dist/analyzer/patternMatching.js +2 -2
- package/dist/analyzer/patternMatching.js.map +1 -1
- package/dist/analyzer/program.d.ts +2 -2
- package/dist/analyzer/program.js +1 -1
- package/dist/analyzer/program.js.map +1 -1
- package/dist/analyzer/service.d.ts +4 -3
- package/dist/analyzer/service.js +40 -39
- package/dist/analyzer/service.js.map +1 -1
- package/dist/analyzer/sourceFile.d.ts +6 -1
- package/dist/analyzer/sourceFile.js +57 -14
- package/dist/analyzer/sourceFile.js.map +1 -1
- package/dist/analyzer/typeEvaluator.d.ts +1 -1
- package/dist/analyzer/typeEvaluator.js +754 -618
- package/dist/analyzer/typeEvaluator.js.map +1 -1
- package/dist/analyzer/typeEvaluatorTypes.d.ts +15 -15
- package/dist/analyzer/typeEvaluatorWithTracker.js +8 -7
- package/dist/analyzer/typeEvaluatorWithTracker.js.map +1 -1
- package/dist/analyzer/typeGuards.d.ts +2 -0
- package/dist/analyzer/typeGuards.js +47 -14
- package/dist/analyzer/typeGuards.js.map +1 -1
- package/dist/analyzer/typeUtils.d.ts +5 -3
- package/dist/analyzer/typeUtils.js +103 -27
- package/dist/analyzer/typeUtils.js.map +1 -1
- package/dist/analyzer/typedDicts.d.ts +1 -0
- package/dist/analyzer/typedDicts.js +27 -4
- package/dist/analyzer/typedDicts.js.map +1 -1
- package/dist/analyzer/types.d.ts +15 -5
- package/dist/analyzer/types.js +107 -9
- package/dist/analyzer/types.js.map +1 -1
- package/dist/backgroundAnalysisBase.d.ts +2 -1
- package/dist/backgroundAnalysisBase.js +7 -0
- package/dist/backgroundAnalysisBase.js.map +1 -1
- package/dist/backgroundThreadBase.js +1 -0
- package/dist/backgroundThreadBase.js.map +1 -1
- package/dist/common/chokidarFileWatcherProvider.d.ts +1 -2
- package/dist/common/chokidarFileWatcherProvider.js +0 -3
- package/dist/common/chokidarFileWatcherProvider.js.map +1 -1
- package/dist/common/configOptions.d.ts +1 -0
- package/dist/common/configOptions.js +4 -0
- package/dist/common/configOptions.js.map +1 -1
- package/dist/common/diagnostic.d.ts +2 -1
- package/dist/common/diagnostic.js +2 -1
- package/dist/common/diagnostic.js.map +1 -1
- package/dist/common/diagnosticRules.d.ts +1 -0
- package/dist/common/diagnosticRules.js +1 -0
- package/dist/common/diagnosticRules.js.map +1 -1
- package/dist/common/diagnosticSink.d.ts +3 -0
- package/dist/common/diagnosticSink.js +15 -2
- package/dist/common/diagnosticSink.js.map +1 -1
- package/dist/common/editAction.d.ts +6 -0
- package/dist/common/editAction.js +15 -0
- package/dist/common/editAction.js.map +1 -1
- package/dist/common/fileSystem.d.ts +4 -1
- package/dist/common/fileSystem.js +6 -4
- package/dist/common/fileSystem.js.map +1 -1
- package/dist/common/realFileSystem.d.ts +2 -2
- package/dist/common/realFileSystem.js.map +1 -1
- package/dist/common/textEditUtils.d.ts +22 -2
- package/dist/common/textEditUtils.js +138 -1
- package/dist/common/textEditUtils.js.map +1 -1
- package/dist/common/uriParser.d.ts +2 -0
- package/dist/common/uriParser.js +11 -0
- package/dist/common/uriParser.js.map +1 -1
- package/dist/languageServerBase.d.ts +19 -18
- package/dist/languageServerBase.js +75 -61
- package/dist/languageServerBase.js.map +1 -1
- package/dist/languageService/codeActionProvider.d.ts +2 -2
- package/dist/languageService/codeActionProvider.js +1 -1
- package/dist/languageService/codeActionProvider.js.map +1 -1
- package/dist/languageService/completionProvider.d.ts +15 -11
- package/dist/languageService/completionProvider.js +76 -5
- package/dist/languageService/completionProvider.js.map +1 -1
- package/dist/languageService/indentationUtils.js +3 -2
- package/dist/languageService/indentationUtils.js.map +1 -1
- package/dist/languageService/insertionPointUtils.d.ts +9 -0
- package/dist/languageService/insertionPointUtils.js +110 -0
- package/dist/languageService/insertionPointUtils.js.map +1 -0
- package/dist/languageService/renameModuleProvider.d.ts +1 -4
- package/dist/languageService/renameModuleProvider.js +10 -46
- package/dist/languageService/renameModuleProvider.js.map +1 -1
- package/dist/languageService/signatureHelpProvider.js +4 -2
- package/dist/languageService/signatureHelpProvider.js.map +1 -1
- package/dist/languageService/tooltipUtils.js +1 -3
- package/dist/languageService/tooltipUtils.js.map +1 -1
- package/dist/localization/localize.d.ts +13 -0
- package/dist/localization/localize.js +4 -0
- package/dist/localization/localize.js.map +1 -1
- package/dist/localization/package.nls.en-us.json +4 -0
- package/dist/parser/parser.d.ts +2 -1
- package/dist/parser/parser.js +11 -2
- package/dist/parser/parser.js.map +1 -1
- package/dist/parser/tokenizer.d.ts +2 -1
- package/dist/parser/tokenizer.js +3 -2
- package/dist/parser/tokenizer.js.map +1 -1
- package/dist/pyright.js +3 -1
- package/dist/pyright.js.map +1 -1
- package/dist/pyrightFileSystem.d.ts +20 -2
- package/dist/pyrightFileSystem.js +29 -2
- package/dist/pyrightFileSystem.js.map +1 -1
- package/dist/server.js +4 -4
- package/dist/server.js.map +1 -1
- package/dist/tests/chainedSourceFiles.test.js +4 -1
- package/dist/tests/chainedSourceFiles.test.js.map +1 -1
- package/dist/tests/checker.test.js +9 -0
- package/dist/tests/checker.test.js.map +1 -1
- package/dist/tests/fourslash/completions.commitChars.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.commitChars.fourslash.js +47 -0
- package/dist/tests/fourslash/completions.commitChars.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.triggers.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.triggers.fourslash.js +29 -0
- package/dist/tests/fourslash/completions.triggers.fourslash.js.map +1 -0
- package/dist/tests/fourslash/fourslash.d.ts +1 -0
- package/dist/tests/fourslash/import.multipart.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/import.multipart.fourslash.js +18 -0
- package/dist/tests/fourslash/import.multipart.fourslash.js.map +1 -0
- package/dist/tests/fourslash/signature.simple.fourslash.js +16 -0
- package/dist/tests/fourslash/signature.simple.fourslash.js.map +1 -1
- package/dist/tests/harness/fourslash/testLanguageService.js +1 -1
- package/dist/tests/harness/fourslash/testLanguageService.js.map +1 -1
- package/dist/tests/harness/fourslash/testState.js +12 -3
- package/dist/tests/harness/fourslash/testState.js.map +1 -1
- package/dist/tests/insertionPointUtils.test.d.ts +1 -0
- package/dist/tests/insertionPointUtils.test.js +74 -0
- package/dist/tests/insertionPointUtils.test.js.map +1 -0
- package/dist/tests/pyrightFileSystem.test.js +28 -0
- package/dist/tests/pyrightFileSystem.test.js.map +1 -1
- package/dist/tests/renameModuleTestUtils.js +5 -87
- package/dist/tests/renameModuleTestUtils.js.map +1 -1
- package/dist/tests/testStateUtils.d.ts +8 -0
- package/dist/tests/testStateUtils.js +110 -0
- package/dist/tests/testStateUtils.js.map +1 -0
- package/dist/tests/testUtils.d.ts +2 -1
- package/dist/tests/testUtils.js +11 -7
- package/dist/tests/testUtils.js.map +1 -1
- package/dist/tests/typeEvaluator1.test.js +2 -6
- package/dist/tests/typeEvaluator1.test.js.map +1 -1
- package/dist/tests/typeEvaluator2.test.js +16 -4
- package/dist/tests/typeEvaluator2.test.js.map +1 -1
- package/dist/tests/typeEvaluator3.test.js +9 -1
- package/dist/tests/typeEvaluator3.test.js.map +1 -1
- package/dist/tests/typeEvaluator4.test.js +26 -0
- package/dist/tests/typeEvaluator4.test.js.map +1 -1
- package/dist/tests/typeEvaluator5.test.js +6 -0
- package/dist/tests/typeEvaluator5.test.js.map +1 -1
- package/dist/workspaceMap.d.ts +1 -0
- package/dist/workspaceMap.js +10 -0
- package/dist/workspaceMap.js.map +1 -1
- package/package.json +4 -3
package/dist/analyzer/checker.js
CHANGED
@@ -51,6 +51,7 @@ const ParseTreeUtils = __importStar(require("./parseTreeUtils"));
|
|
51
51
|
const parseTreeWalker_1 = require("./parseTreeWalker");
|
52
52
|
const patternMatching_1 = require("./patternMatching");
|
53
53
|
const scopeUtils_1 = require("./scopeUtils");
|
54
|
+
const sourceFile_1 = require("./sourceFile");
|
54
55
|
const sourceMapper_1 = require("./sourceMapper");
|
55
56
|
const staticExpressions_1 = require("./staticExpressions");
|
56
57
|
const SymbolNameUtils = __importStar(require("./symbolNameUtils"));
|
@@ -327,7 +328,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
327
328
|
if (annotationNode && index < functionTypeResult.functionType.details.parameters.length) {
|
328
329
|
const paramType = functionTypeResult.functionType.details.parameters[index].type;
|
329
330
|
if ((0, types_1.isTypeVar)(paramType) &&
|
330
|
-
paramType.details.declaredVariance ===
|
331
|
+
paramType.details.declaredVariance === 3 /* Covariant */ &&
|
331
332
|
!paramType.details.isSynthesized &&
|
332
333
|
functionTypeResult.functionType.details.name !== '__init__') {
|
333
334
|
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.paramTypeCovariant(), annotationNode);
|
@@ -385,14 +386,19 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
385
386
|
}
|
386
387
|
this._scopedNodes.push(node);
|
387
388
|
if (functionTypeResult && (0, types_1.isOverloadedFunction)(functionTypeResult.decoratedType)) {
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
389
|
+
// If this is the implementation for the overloaded function, skip
|
390
|
+
// overload consistency checks.
|
391
|
+
if (types_1.OverloadedFunctionType.getImplementation(functionTypeResult.decoratedType) !==
|
392
|
+
functionTypeResult.functionType) {
|
393
|
+
const overloads = types_1.OverloadedFunctionType.getOverloads(functionTypeResult.decoratedType);
|
394
|
+
if (overloads.length > 1) {
|
395
|
+
const maxOverloadConsistencyCheckLength = 100;
|
396
|
+
// The check is n^2 in time, so if the number of overloads
|
397
|
+
// is very large (which can happen for some generated code),
|
398
|
+
// skip this check to avoid quadratic analysis time.
|
399
|
+
if (overloads.length < maxOverloadConsistencyCheckLength) {
|
400
|
+
this._validateOverloadConsistency(node, overloads[overloads.length - 1], overloads.slice(0, overloads.length - 1));
|
401
|
+
}
|
396
402
|
}
|
397
403
|
}
|
398
404
|
}
|
@@ -731,6 +737,12 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
731
737
|
this._validateComparisonTypes(node);
|
732
738
|
}
|
733
739
|
}
|
740
|
+
else if (node.operator === 41 /* In */ || node.operator === 42 /* NotIn */) {
|
741
|
+
// Don't apply this rule if it's within an assert.
|
742
|
+
if (!ParseTreeUtils.isWithinAssertExpression(node)) {
|
743
|
+
this._validateContainmentTypes(node);
|
744
|
+
}
|
745
|
+
}
|
734
746
|
this._evaluator.getType(node);
|
735
747
|
return true;
|
736
748
|
}
|
@@ -976,11 +988,46 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
976
988
|
}
|
977
989
|
}
|
978
990
|
}
|
991
|
+
_validateContainmentTypes(node) {
|
992
|
+
const leftType = this._evaluator.getType(node.leftExpression);
|
993
|
+
const containerType = this._evaluator.getType(node.rightExpression);
|
994
|
+
if (!leftType || !containerType) {
|
995
|
+
return;
|
996
|
+
}
|
997
|
+
if ((0, types_1.isNever)(leftType) || (0, types_1.isNever)(containerType)) {
|
998
|
+
return;
|
999
|
+
}
|
1000
|
+
// Use the common narrowing logic for containment.
|
1001
|
+
const elementType = (0, typeGuards_1.getElementTypeForContainerNarrowing)(containerType);
|
1002
|
+
if (!elementType) {
|
1003
|
+
return;
|
1004
|
+
}
|
1005
|
+
const narrowedType = (0, typeGuards_1.narrowTypeForContainerElementType)(this._evaluator, leftType, this._evaluator.makeTopLevelTypeVarsConcrete(elementType));
|
1006
|
+
if ((0, types_1.isNever)(narrowedType)) {
|
1007
|
+
const getMessage = () => {
|
1008
|
+
return node.operator === 41 /* In */
|
1009
|
+
? localize_1.Localizer.Diagnostic.containmentAlwaysFalse()
|
1010
|
+
: localize_1.Localizer.Diagnostic.containmentAlwaysTrue();
|
1011
|
+
};
|
1012
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportUnnecessaryContains, diagnosticRules_1.DiagnosticRule.reportUnnecessaryContains, getMessage().format({
|
1013
|
+
leftType: this._evaluator.printType(leftType, /* expandTypeAlias */ true),
|
1014
|
+
rightType: this._evaluator.printType(elementType, /* expandTypeAlias */ true),
|
1015
|
+
}), node);
|
1016
|
+
}
|
1017
|
+
}
|
979
1018
|
// Determines whether the types of the two operands for an == or != operation
|
980
1019
|
// have overlapping types.
|
981
1020
|
_validateComparisonTypes(node) {
|
1021
|
+
let rightExpression = node.rightExpression;
|
1022
|
+
// Check for chained comparisons.
|
1023
|
+
if (rightExpression.nodeType === 7 /* BinaryOperation */ &&
|
1024
|
+
!rightExpression.parenthesized &&
|
1025
|
+
ParseTreeUtils.operatorSupportsChaining(rightExpression.operator)) {
|
1026
|
+
// Use the left side of the right expression for comparison purposes.
|
1027
|
+
rightExpression = rightExpression.leftExpression;
|
1028
|
+
}
|
982
1029
|
const leftType = this._evaluator.getType(node.leftExpression);
|
983
|
-
const rightType = this._evaluator.getType(
|
1030
|
+
const rightType = this._evaluator.getType(rightExpression);
|
984
1031
|
if (!leftType || !rightType) {
|
985
1032
|
return;
|
986
1033
|
}
|
@@ -1284,9 +1331,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
1284
1331
|
_validateOverloadConsistency(node, functionType, prevOverloads) {
|
1285
1332
|
for (let i = 0; i < prevOverloads.length; i++) {
|
1286
1333
|
const prevOverload = prevOverloads[i];
|
1287
|
-
if (
|
1288
|
-
types_1.FunctionType.isOverloaded(prevOverload) &&
|
1289
|
-
this._isOverlappingOverload(functionType, prevOverload)) {
|
1334
|
+
if (this._isOverlappingOverload(functionType, prevOverload)) {
|
1290
1335
|
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportOverlappingOverload, diagnosticRules_1.DiagnosticRule.reportOverlappingOverload, localize_1.Localizer.Diagnostic.overlappingOverload().format({
|
1291
1336
|
name: node.name.value,
|
1292
1337
|
obscured: prevOverloads.length + 1,
|
@@ -1297,9 +1342,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
1297
1342
|
}
|
1298
1343
|
for (let i = 0; i < prevOverloads.length; i++) {
|
1299
1344
|
const prevOverload = prevOverloads[i];
|
1300
|
-
if (
|
1301
|
-
types_1.FunctionType.isOverloaded(prevOverload) &&
|
1302
|
-
this._isOverlappingOverload(prevOverload, functionType)) {
|
1345
|
+
if (this._isOverlappingOverload(prevOverload, functionType)) {
|
1303
1346
|
const prevReturnType = types_1.FunctionType.getSpecializedReturnType(prevOverload);
|
1304
1347
|
const returnType = types_1.FunctionType.getSpecializedReturnType(functionType);
|
1305
1348
|
if (prevReturnType &&
|
@@ -1387,7 +1430,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
1387
1430
|
const start = statement.start;
|
1388
1431
|
const lastStatement = statements[statements.length - 1];
|
1389
1432
|
const end = textRange_1.TextRange.getEnd(lastStatement);
|
1390
|
-
this._evaluator.
|
1433
|
+
this._evaluator.addUnreachableCode(statement, { start, length: end - start });
|
1391
1434
|
reportedUnreachable = true;
|
1392
1435
|
}
|
1393
1436
|
}
|
@@ -1577,8 +1620,11 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
1577
1620
|
const primaryDecl = typedDecls[0];
|
1578
1621
|
if (primaryDecl.type === 5 /* Function */) {
|
1579
1622
|
const type = this._evaluator.getEffectiveTypeOfSymbol(symbol);
|
1580
|
-
const
|
1581
|
-
|
1623
|
+
const overloadedFunctions = (0, types_1.isOverloadedFunction)(type)
|
1624
|
+
? types_1.OverloadedFunctionType.getOverloads(type)
|
1625
|
+
: (0, types_1.isFunction)(type) && types_1.FunctionType.isOverloaded(type)
|
1626
|
+
? [type]
|
1627
|
+
: [];
|
1582
1628
|
if (overloadedFunctions.length === 1) {
|
1583
1629
|
// There should never be a single overload.
|
1584
1630
|
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.singleOverload().format({ name }), primaryDecl.node.name);
|
@@ -1595,9 +1641,8 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
1595
1641
|
// verify that there is an implementation.
|
1596
1642
|
if (!this._fileInfo.isStubFile && overloadedFunctions.length > 0) {
|
1597
1643
|
let implementationFunction;
|
1598
|
-
if ((0, types_1.isOverloadedFunction)(type) &&
|
1599
|
-
|
1600
|
-
implementationFunction = type.overloads[type.overloads.length - 1];
|
1644
|
+
if ((0, types_1.isOverloadedFunction)(type) && types_1.OverloadedFunctionType.getImplementation(type)) {
|
1645
|
+
implementationFunction = types_1.OverloadedFunctionType.getImplementation(type);
|
1601
1646
|
}
|
1602
1647
|
else if ((0, types_1.isFunction)(type) && !types_1.FunctionType.isOverloaded(type)) {
|
1603
1648
|
implementationFunction = type;
|
@@ -1621,11 +1666,8 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
1621
1666
|
}
|
1622
1667
|
else if ((0, types_1.isOverloadedFunction)(type)) {
|
1623
1668
|
// Verify that all overload signatures are assignable to implementation signature.
|
1624
|
-
type.
|
1669
|
+
types_1.OverloadedFunctionType.getOverloads(type).forEach((overload, index) => {
|
1625
1670
|
var _a, _b, _c, _d;
|
1626
|
-
if (overload === implementationFunction || !types_1.FunctionType.isOverloaded(overload)) {
|
1627
|
-
return;
|
1628
|
-
}
|
1629
1671
|
const diag = new diagnostic_1.DiagnosticAddendum();
|
1630
1672
|
if (!this._isLegalOverloadImplementation(overload, implementationFunction, diag)) {
|
1631
1673
|
if (implementationFunction.details.declaration) {
|
@@ -1894,7 +1936,9 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
1894
1936
|
}
|
1895
1937
|
_conditionallyReportUnusedSymbol(name, symbol, scopeType) {
|
1896
1938
|
const accessedSymbolSet = this._fileInfo.accessedSymbolSet;
|
1897
|
-
if (symbol.isIgnoredForProtocolMatch() ||
|
1939
|
+
if (symbol.isIgnoredForProtocolMatch() ||
|
1940
|
+
accessedSymbolSet.has(symbol.id) ||
|
1941
|
+
this._fileInfo.ipythonMode === sourceFile_1.IPythonMode.CellDocs) {
|
1898
1942
|
return;
|
1899
1943
|
}
|
1900
1944
|
// A name of "_" means "I know this symbol isn't used", so
|
@@ -2549,7 +2593,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
2549
2593
|
}
|
2550
2594
|
const diag = new diagnostic_1.DiagnosticAddendum();
|
2551
2595
|
if ((0, types_1.isTypeVar)(declaredReturnType) &&
|
2552
|
-
declaredReturnType.details.declaredVariance ===
|
2596
|
+
declaredReturnType.details.declaredVariance === 4 /* Contravariant */) {
|
2553
2597
|
diag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeVarIsContravariant().format({
|
2554
2598
|
name: types_1.TypeVarType.getReadableName(declaredReturnType),
|
2555
2599
|
}));
|
@@ -2910,26 +2954,26 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
2910
2954
|
const isDestSubtypeOfSrc = this._evaluator.assignClassToSelf(srcType, destType);
|
2911
2955
|
let expectedVariance;
|
2912
2956
|
if (isDestSubtypeOfSrc) {
|
2913
|
-
expectedVariance =
|
2957
|
+
expectedVariance = 3 /* Covariant */;
|
2914
2958
|
}
|
2915
2959
|
else {
|
2916
2960
|
const isSrcSubtypeOfDest = this._evaluator.assignClassToSelf(destType, srcType);
|
2917
2961
|
if (isSrcSubtypeOfDest) {
|
2918
|
-
expectedVariance =
|
2962
|
+
expectedVariance = 4 /* Contravariant */;
|
2919
2963
|
}
|
2920
2964
|
else {
|
2921
|
-
expectedVariance =
|
2965
|
+
expectedVariance = 2 /* Invariant */;
|
2922
2966
|
}
|
2923
2967
|
}
|
2924
2968
|
if (expectedVariance !== classType.details.typeParameters[paramIndex].details.declaredVariance) {
|
2925
2969
|
let message;
|
2926
|
-
if (expectedVariance ===
|
2970
|
+
if (expectedVariance === 3 /* Covariant */) {
|
2927
2971
|
message = localize_1.Localizer.Diagnostic.protocolVarianceCovariant().format({
|
2928
2972
|
variable: param.details.name,
|
2929
2973
|
class: classType.details.name,
|
2930
2974
|
});
|
2931
2975
|
}
|
2932
|
-
else if (expectedVariance ===
|
2976
|
+
else if (expectedVariance === 4 /* Contravariant */) {
|
2933
2977
|
message = localize_1.Localizer.Diagnostic.protocolVarianceContravariant().format({
|
2934
2978
|
variable: param.details.name,
|
2935
2979
|
class: classType.details.name,
|
@@ -3009,7 +3053,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
3009
3053
|
}
|
3010
3054
|
if ((0, types_1.isOverloadedFunction)(newMemberType)) {
|
3011
3055
|
// Find the implementation, not the overloaded signatures.
|
3012
|
-
newMemberType =
|
3056
|
+
newMemberType = types_1.OverloadedFunctionType.getImplementation(newMemberType);
|
3013
3057
|
if (!newMemberType) {
|
3014
3058
|
return;
|
3015
3059
|
}
|
@@ -3024,7 +3068,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
3024
3068
|
}
|
3025
3069
|
if ((0, types_1.isOverloadedFunction)(initMemberType)) {
|
3026
3070
|
// Find the implementation, not the overloaded signatures.
|
3027
|
-
initMemberType =
|
3071
|
+
initMemberType = types_1.OverloadedFunctionType.getImplementation(initMemberType);
|
3028
3072
|
if (!initMemberType) {
|
3029
3073
|
return;
|
3030
3074
|
}
|
@@ -3162,9 +3206,9 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
3162
3206
|
}
|
3163
3207
|
else if ((0, types_1.isOverloadedFunction)(overrideType)) {
|
3164
3208
|
// Use the last overload.
|
3165
|
-
overrideFunction =
|
3209
|
+
overrideFunction = types_1.OverloadedFunctionType.getImplementation(overrideType);
|
3166
3210
|
// If the last overload isn't an implementation, skip the check for this symbol.
|
3167
|
-
if (
|
3211
|
+
if (!overrideFunction) {
|
3168
3212
|
return;
|
3169
3213
|
}
|
3170
3214
|
}
|
@@ -3232,7 +3276,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
3232
3276
|
}
|
3233
3277
|
// If the symbol has no declaration, and the type is inferred,
|
3234
3278
|
// skip this check.
|
3235
|
-
if (!symbol.hasTypedDeclarations()) {
|
3279
|
+
if (!symbol.hasTypedDeclarations() && !(0, symbolUtils_1.isFinalVariable)(symbol)) {
|
3236
3280
|
return;
|
3237
3281
|
}
|
3238
3282
|
// Get the symbol type defined in this class.
|
@@ -3260,7 +3304,6 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
3260
3304
|
});
|
3261
3305
|
}
|
3262
3306
|
_validateBaseClassOverride(baseClassAndSymbol, overrideSymbol, overrideType, childClassType, memberName) {
|
3263
|
-
var _a;
|
3264
3307
|
if (!(0, types_1.isInstantiableClass)(baseClassAndSymbol.classType)) {
|
3265
3308
|
return;
|
3266
3309
|
}
|
@@ -3278,15 +3321,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
3278
3321
|
const baseType = (0, typeUtils_1.partiallySpecializeType)(this._evaluator.getEffectiveTypeOfSymbol(baseClassAndSymbol.symbol), baseClassAndSymbol.classType);
|
3279
3322
|
if ((0, types_1.isFunction)(baseType) || (0, types_1.isOverloadedFunction)(baseType)) {
|
3280
3323
|
const diagAddendum = new diagnostic_1.DiagnosticAddendum();
|
3281
|
-
|
3282
|
-
if ((0, types_1.isFunction)(overrideType)) {
|
3283
|
-
overrideFunction = overrideType;
|
3284
|
-
}
|
3285
|
-
else if ((0, types_1.isOverloadedFunction)(overrideType)) {
|
3286
|
-
// Use the last overload.
|
3287
|
-
overrideFunction = overrideType.overloads[overrideType.overloads.length - 1];
|
3288
|
-
}
|
3289
|
-
if (overrideFunction) {
|
3324
|
+
if ((0, types_1.isFunction)(overrideType) || (0, types_1.isOverloadedFunction)(overrideType)) {
|
3290
3325
|
const exemptMethods = ['__init__', '__new__', '__init_subclass__'];
|
3291
3326
|
// Don't enforce parameter names for dundered methods. Many of them
|
3292
3327
|
// are misnamed in typeshed stubs, so this would result in many
|
@@ -3295,8 +3330,10 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
3295
3330
|
// Don't check certain magic functions or private symbols.
|
3296
3331
|
if (!exemptMethods.some((exempt) => exempt === memberName) &&
|
3297
3332
|
!SymbolNameUtils.isPrivateName(memberName)) {
|
3298
|
-
if (!this._evaluator.validateOverrideMethod(baseType,
|
3299
|
-
const decl = (
|
3333
|
+
if (!this._evaluator.validateOverrideMethod(baseType, overrideType, diagAddendum, enforceParamNameMatch)) {
|
3334
|
+
const decl = (0, types_1.isFunction)(overrideType) && overrideType.details.declaration
|
3335
|
+
? overrideType.details.declaration
|
3336
|
+
: (0, symbolUtils_1.getLastTypedDeclaredForSymbol)(overrideSymbol);
|
3300
3337
|
if (decl) {
|
3301
3338
|
const diag = this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportIncompatibleMethodOverride, diagnosticRules_1.DiagnosticRule.reportIncompatibleMethodOverride, localize_1.Localizer.Diagnostic.incompatibleMethodOverride().format({
|
3302
3339
|
name: memberName,
|
@@ -3433,6 +3470,18 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
3433
3470
|
diag.addRelatedInfo(localize_1.Localizer.DiagnosticAddendum.overriddenSymbol(), origDecl.path, origDecl.range);
|
3434
3471
|
}
|
3435
3472
|
}
|
3473
|
+
// Verify that there is not a Final mismatch.
|
3474
|
+
const isBaseVarFinal = (0, symbolUtils_1.isFinalVariable)(baseClassAndSymbol.symbol);
|
3475
|
+
const overrideFinalVarDecl = decls.find((d) => (0, declarationUtils_1.isFinalVariableDeclaration)(d));
|
3476
|
+
if (!isBaseVarFinal && overrideFinalVarDecl) {
|
3477
|
+
const diag = this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportIncompatibleVariableOverride, diagnosticRules_1.DiagnosticRule.reportIncompatibleVariableOverride, localize_1.Localizer.Diagnostic.variableFinalOverride().format({
|
3478
|
+
name: memberName,
|
3479
|
+
className: baseClassAndSymbol.classType.details.name,
|
3480
|
+
}), lastDecl.node);
|
3481
|
+
if (diag) {
|
3482
|
+
diag.addRelatedInfo(localize_1.Localizer.DiagnosticAddendum.overriddenSymbol(), overrideFinalVarDecl.path, overrideFinalVarDecl.range);
|
3483
|
+
}
|
3484
|
+
}
|
3436
3485
|
// Verify that a class variable isn't overriding an instance
|
3437
3486
|
// variable or vice versa.
|
3438
3487
|
const isBaseClassVar = baseClassAndSymbol.symbol.isClassVar();
|
@@ -3767,7 +3816,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
3767
3816
|
// Were all of the exception types overridden?
|
3768
3817
|
if (typesOfThisExcept.length === overriddenExceptionCount) {
|
3769
3818
|
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.unreachableExcept() + diagAddendum.getString(), except.typeExpression);
|
3770
|
-
this._evaluator.
|
3819
|
+
this._evaluator.addUnreachableCode(except, except.exceptSuite);
|
3771
3820
|
}
|
3772
3821
|
}
|
3773
3822
|
exceptionTypesSoFar.push(...typesOfThisExcept);
|