@zzzen/pyright-internal 1.2.0-dev.2022-07-02 → 1.2.0-dev.20220717
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/aliasDeclarationUtils.js +2 -2
- package/dist/analyzer/analyzerFileInfo.d.ts +2 -1
- package/dist/analyzer/analyzerFileInfo.js.map +1 -1
- package/dist/analyzer/analyzerNodeInfo.d.ts +4 -1
- package/dist/analyzer/analyzerNodeInfo.js +12 -1
- package/dist/analyzer/analyzerNodeInfo.js.map +1 -1
- package/dist/analyzer/binder.d.ts +6 -1
- package/dist/analyzer/binder.js +148 -31
- package/dist/analyzer/binder.js.map +1 -1
- package/dist/analyzer/checker.d.ts +4 -1
- package/dist/analyzer/checker.js +176 -90
- 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 +9 -6
- package/dist/analyzer/constraintSolver.js.map +1 -1
- package/dist/analyzer/declaration.d.ts +18 -6
- package/dist/analyzer/declaration.js +19 -9
- package/dist/analyzer/declaration.js.map +1 -1
- package/dist/analyzer/declarationUtils.d.ts +1 -1
- package/dist/analyzer/declarationUtils.js +19 -16
- package/dist/analyzer/declarationUtils.js.map +1 -1
- package/dist/analyzer/functionTransform.js +2 -1
- package/dist/analyzer/functionTransform.js.map +1 -1
- package/dist/analyzer/importResolver.js +3 -2
- package/dist/analyzer/importResolver.js.map +1 -1
- package/dist/analyzer/packageTypeVerifier.js +6 -6
- package/dist/analyzer/parseTreeUtils.d.ts +6 -3
- package/dist/analyzer/parseTreeUtils.js +65 -21
- package/dist/analyzer/parseTreeUtils.js.map +1 -1
- package/dist/analyzer/parseTreeWalker.d.ts +4 -1
- package/dist/analyzer/parseTreeWalker.js +19 -1
- package/dist/analyzer/parseTreeWalker.js.map +1 -1
- package/dist/analyzer/patternMatching.js +1 -1
- 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/properties.js +2 -0
- package/dist/analyzer/properties.js.map +1 -1
- package/dist/analyzer/protocols.d.ts +0 -1
- package/dist/analyzer/protocols.js +1 -63
- package/dist/analyzer/protocols.js.map +1 -1
- package/dist/analyzer/service.d.ts +3 -2
- package/dist/analyzer/service.js +4 -2
- 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/tracePrinter.js +8 -4
- package/dist/analyzer/tracePrinter.js.map +1 -1
- package/dist/analyzer/typeDocStringUtils.js +1 -1
- package/dist/analyzer/typeEvaluator.d.ts +1 -1
- package/dist/analyzer/typeEvaluator.js +839 -375
- package/dist/analyzer/typeEvaluator.js.map +1 -1
- package/dist/analyzer/typeEvaluatorTypes.d.ts +9 -7
- package/dist/analyzer/typeEvaluatorWithTracker.js +10 -7
- package/dist/analyzer/typeEvaluatorWithTracker.js.map +1 -1
- package/dist/analyzer/typeGuards.js +6 -1
- package/dist/analyzer/typeGuards.js.map +1 -1
- package/dist/analyzer/typePrinter.js +4 -1
- package/dist/analyzer/typePrinter.js.map +1 -1
- package/dist/analyzer/typeStubWriter.d.ts +4 -1
- package/dist/analyzer/typeStubWriter.js +36 -0
- package/dist/analyzer/typeStubWriter.js.map +1 -1
- package/dist/analyzer/typeUtils.d.ts +3 -2
- package/dist/analyzer/typeUtils.js +94 -13
- package/dist/analyzer/typeUtils.js.map +1 -1
- package/dist/analyzer/typedDicts.d.ts +1 -0
- package/dist/analyzer/typedDicts.js +25 -2
- package/dist/analyzer/typedDicts.js.map +1 -1
- package/dist/analyzer/types.d.ts +21 -5
- package/dist/analyzer/types.js +87 -11
- package/dist/analyzer/types.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/diagnosticSink.d.ts +3 -0
- package/dist/common/diagnosticSink.js +15 -2
- package/dist/common/diagnosticSink.js.map +1 -1
- package/dist/languageServerBase.d.ts +5 -8
- package/dist/languageServerBase.js +30 -18
- package/dist/languageServerBase.js.map +1 -1
- package/dist/languageService/autoImporter.js +1 -1
- package/dist/languageService/callHierarchyProvider.js +9 -9
- package/dist/languageService/completionProvider.d.ts +15 -11
- package/dist/languageService/completionProvider.js +95 -18
- package/dist/languageService/completionProvider.js.map +1 -1
- package/dist/languageService/definitionProvider.js +3 -3
- package/dist/languageService/documentSymbolCollector.js +1 -1
- package/dist/languageService/documentSymbolProvider.js +10 -7
- package/dist/languageService/documentSymbolProvider.js.map +1 -1
- package/dist/languageService/hoverProvider.js +19 -5
- package/dist/languageService/hoverProvider.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/referencesProvider.js +8 -5
- package/dist/languageService/referencesProvider.js.map +1 -1
- package/dist/languageService/signatureHelpProvider.js +4 -2
- package/dist/languageService/signatureHelpProvider.js.map +1 -1
- package/dist/languageService/tooltipUtils.js +2 -4
- package/dist/languageService/tooltipUtils.js.map +1 -1
- package/dist/localization/localize.d.ts +32 -0
- package/dist/localization/localize.js +18 -0
- package/dist/localization/localize.js.map +1 -1
- package/dist/localization/package.nls.en-us.json +20 -2
- package/dist/parser/parseNodes.d.ts +41 -5
- package/dist/parser/parseNodes.js +83 -4
- package/dist/parser/parseNodes.js.map +1 -1
- package/dist/parser/parser.d.ts +5 -1
- package/dist/parser/parser.js +140 -14
- package/dist/parser/parser.js.map +1 -1
- package/dist/parser/tokenizer.d.ts +2 -1
- package/dist/parser/tokenizer.js +7 -5
- package/dist/parser/tokenizer.js.map +1 -1
- package/dist/parser/tokenizerTypes.d.ts +5 -3
- package/dist/parser/tokenizerTypes.js +6 -4
- package/dist/parser/tokenizerTypes.js.map +1 -1
- package/dist/pyright.js +3 -1
- package/dist/pyright.js.map +1 -1
- package/dist/pyrightFileSystem.d.ts +1 -1
- package/dist/pyrightFileSystem.js +11 -1
- package/dist/pyrightFileSystem.js.map +1 -1
- package/dist/tests/chainedSourceFiles.test.js +4 -1
- package/dist/tests/chainedSourceFiles.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/testState.js +11 -2
- 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/testUtils.d.ts +2 -1
- package/dist/tests/testUtils.js +10 -6
- package/dist/tests/testUtils.js.map +1 -1
- package/dist/tests/typeEvaluator1.test.js +2 -2
- package/dist/tests/typeEvaluator1.test.js.map +1 -1
- package/dist/tests/typeEvaluator2.test.js +12 -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 +18 -0
- package/dist/tests/typeEvaluator4.test.js.map +1 -1
- package/dist/tests/typeEvaluator5.test.d.ts +1 -0
- package/dist/tests/typeEvaluator5.test.js +118 -0
- package/dist/tests/typeEvaluator5.test.js.map +1 -0
- package/package.json +3 -2
package/dist/analyzer/checker.js
CHANGED
@@ -50,8 +50,8 @@ const importStatementUtils_1 = require("./importStatementUtils");
|
|
50
50
|
const ParseTreeUtils = __importStar(require("./parseTreeUtils"));
|
51
51
|
const parseTreeWalker_1 = require("./parseTreeWalker");
|
52
52
|
const patternMatching_1 = require("./patternMatching");
|
53
|
-
const protocols_1 = require("./protocols");
|
54
53
|
const scopeUtils_1 = require("./scopeUtils");
|
54
|
+
const sourceFile_1 = require("./sourceFile");
|
55
55
|
const sourceMapper_1 = require("./sourceMapper");
|
56
56
|
const staticExpressions_1 = require("./staticExpressions");
|
57
57
|
const SymbolNameUtils = __importStar(require("./symbolNameUtils"));
|
@@ -111,6 +111,8 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
111
111
|
// A list of all nodes that are defined within the module that
|
112
112
|
// have their own scopes.
|
113
113
|
this._scopedNodes = [];
|
114
|
+
// A list of all visited type parameter lists.
|
115
|
+
this._typeParameterLists = [];
|
114
116
|
this._fileInfo = AnalyzerNodeInfo.getFileInfo(_moduleNode);
|
115
117
|
}
|
116
118
|
check() {
|
@@ -156,6 +158,9 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
156
158
|
}
|
157
159
|
visitClass(node) {
|
158
160
|
const classTypeResult = this._evaluator.getTypeOfClass(node);
|
161
|
+
if (node.typeParameters) {
|
162
|
+
this.walk(node.typeParameters);
|
163
|
+
}
|
159
164
|
this.walk(node.suite);
|
160
165
|
this.walkMultiple(node.decorators);
|
161
166
|
this.walkMultiple(node.arguments);
|
@@ -211,6 +216,9 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
211
216
|
}
|
212
217
|
visitFunction(node) {
|
213
218
|
var _a;
|
219
|
+
if (node.typeParameters) {
|
220
|
+
this.walk(node.typeParameters);
|
221
|
+
}
|
214
222
|
const functionTypeResult = this._evaluator.getTypeOfFunction(node);
|
215
223
|
const containingClassNode = ParseTreeUtils.getEnclosingClass(node, /* stopAtFunction */ true);
|
216
224
|
if (functionTypeResult) {
|
@@ -320,7 +328,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
320
328
|
if (annotationNode && index < functionTypeResult.functionType.details.parameters.length) {
|
321
329
|
const paramType = functionTypeResult.functionType.details.parameters[index].type;
|
322
330
|
if ((0, types_1.isTypeVar)(paramType) &&
|
323
|
-
paramType.details.
|
331
|
+
paramType.details.declaredVariance === 3 /* Covariant */ &&
|
324
332
|
!paramType.details.isSynthesized &&
|
325
333
|
functionTypeResult.functionType.details.name !== '__init__') {
|
326
334
|
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.paramTypeCovariant(), annotationNode);
|
@@ -378,14 +386,19 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
378
386
|
}
|
379
387
|
this._scopedNodes.push(node);
|
380
388
|
if (functionTypeResult && (0, types_1.isOverloadedFunction)(functionTypeResult.decoratedType)) {
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
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
|
+
}
|
389
402
|
}
|
390
403
|
}
|
391
404
|
}
|
@@ -854,6 +867,13 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
854
867
|
}
|
855
868
|
return false;
|
856
869
|
}
|
870
|
+
visitTypeParameterList(node) {
|
871
|
+
this._typeParameterLists.push(node);
|
872
|
+
return true;
|
873
|
+
}
|
874
|
+
visitTypeParameter(node) {
|
875
|
+
return false;
|
876
|
+
}
|
857
877
|
visitTypeAnnotation(node) {
|
858
878
|
this._evaluator.getType(node.typeAnnotation);
|
859
879
|
return true;
|
@@ -1270,9 +1290,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
1270
1290
|
_validateOverloadConsistency(node, functionType, prevOverloads) {
|
1271
1291
|
for (let i = 0; i < prevOverloads.length; i++) {
|
1272
1292
|
const prevOverload = prevOverloads[i];
|
1273
|
-
if (
|
1274
|
-
types_1.FunctionType.isOverloaded(prevOverload) &&
|
1275
|
-
this._isOverlappingOverload(functionType, prevOverload)) {
|
1293
|
+
if (this._isOverlappingOverload(functionType, prevOverload)) {
|
1276
1294
|
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportOverlappingOverload, diagnosticRules_1.DiagnosticRule.reportOverlappingOverload, localize_1.Localizer.Diagnostic.overlappingOverload().format({
|
1277
1295
|
name: node.name.value,
|
1278
1296
|
obscured: prevOverloads.length + 1,
|
@@ -1283,9 +1301,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
1283
1301
|
}
|
1284
1302
|
for (let i = 0; i < prevOverloads.length; i++) {
|
1285
1303
|
const prevOverload = prevOverloads[i];
|
1286
|
-
if (
|
1287
|
-
types_1.FunctionType.isOverloaded(prevOverload) &&
|
1288
|
-
this._isOverlappingOverload(prevOverload, functionType)) {
|
1304
|
+
if (this._isOverlappingOverload(prevOverload, functionType)) {
|
1289
1305
|
const prevReturnType = types_1.FunctionType.getSpecializedReturnType(prevOverload);
|
1290
1306
|
const returnType = types_1.FunctionType.getSpecializedReturnType(functionType);
|
1291
1307
|
if (prevReturnType &&
|
@@ -1313,7 +1329,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
1313
1329
|
return undefined;
|
1314
1330
|
}
|
1315
1331
|
for (const decl of decls) {
|
1316
|
-
if (decl.type ===
|
1332
|
+
if (decl.type === 5 /* Function */) {
|
1317
1333
|
const functionType = this._evaluator.getTypeOfFunction(decl.node);
|
1318
1334
|
if ((functionType === null || functionType === void 0 ? void 0 : functionType.functionType) === overloadType) {
|
1319
1335
|
return decl.node;
|
@@ -1373,7 +1389,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
1373
1389
|
const start = statement.start;
|
1374
1390
|
const lastStatement = statements[statements.length - 1];
|
1375
1391
|
const end = textRange_1.TextRange.getEnd(lastStatement);
|
1376
|
-
this._evaluator.
|
1392
|
+
this._evaluator.addUnreachableCode(statement, { start, length: end - start });
|
1377
1393
|
reportedUnreachable = true;
|
1378
1394
|
}
|
1379
1395
|
}
|
@@ -1542,15 +1558,32 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
1542
1558
|
});
|
1543
1559
|
}
|
1544
1560
|
}
|
1561
|
+
// Report unaccessed type parameters.
|
1562
|
+
const accessedSymbolSet = this._fileInfo.accessedSymbolSet;
|
1563
|
+
for (const paramList of this._typeParameterLists) {
|
1564
|
+
for (const param of paramList.parameters) {
|
1565
|
+
const symbol = AnalyzerNodeInfo.getTypeParameterSymbol(param.name);
|
1566
|
+
(0, debug_1.assert)(symbol);
|
1567
|
+
if (!accessedSymbolSet.has(symbol.id)) {
|
1568
|
+
const decls = symbol.getDeclarations();
|
1569
|
+
decls.forEach((decl) => {
|
1570
|
+
this._conditionallyReportUnusedDeclaration(decl, /* isPrivate */ false);
|
1571
|
+
});
|
1572
|
+
}
|
1573
|
+
}
|
1574
|
+
}
|
1545
1575
|
}
|
1546
1576
|
_reportInvalidOverload(name, symbol) {
|
1547
1577
|
const typedDecls = symbol.getTypedDeclarations();
|
1548
1578
|
if (typedDecls.length >= 1) {
|
1549
1579
|
const primaryDecl = typedDecls[0];
|
1550
|
-
if (primaryDecl.type ===
|
1580
|
+
if (primaryDecl.type === 5 /* Function */) {
|
1551
1581
|
const type = this._evaluator.getEffectiveTypeOfSymbol(symbol);
|
1552
|
-
const
|
1553
|
-
|
1582
|
+
const overloadedFunctions = (0, types_1.isOverloadedFunction)(type)
|
1583
|
+
? types_1.OverloadedFunctionType.getOverloads(type)
|
1584
|
+
: (0, types_1.isFunction)(type) && types_1.FunctionType.isOverloaded(type)
|
1585
|
+
? [type]
|
1586
|
+
: [];
|
1554
1587
|
if (overloadedFunctions.length === 1) {
|
1555
1588
|
// There should never be a single overload.
|
1556
1589
|
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.singleOverload().format({ name }), primaryDecl.node.name);
|
@@ -1567,9 +1600,8 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
1567
1600
|
// verify that there is an implementation.
|
1568
1601
|
if (!this._fileInfo.isStubFile && overloadedFunctions.length > 0) {
|
1569
1602
|
let implementationFunction;
|
1570
|
-
if ((0, types_1.isOverloadedFunction)(type) &&
|
1571
|
-
|
1572
|
-
implementationFunction = type.overloads[type.overloads.length - 1];
|
1603
|
+
if ((0, types_1.isOverloadedFunction)(type) && types_1.OverloadedFunctionType.getImplementation(type)) {
|
1604
|
+
implementationFunction = types_1.OverloadedFunctionType.getImplementation(type);
|
1573
1605
|
}
|
1574
1606
|
else if ((0, types_1.isFunction)(type) && !types_1.FunctionType.isOverloaded(type)) {
|
1575
1607
|
implementationFunction = type;
|
@@ -1593,11 +1625,8 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
1593
1625
|
}
|
1594
1626
|
else if ((0, types_1.isOverloadedFunction)(type)) {
|
1595
1627
|
// Verify that all overload signatures are assignable to implementation signature.
|
1596
|
-
type.
|
1628
|
+
types_1.OverloadedFunctionType.getOverloads(type).forEach((overload, index) => {
|
1597
1629
|
var _a, _b, _c, _d;
|
1598
|
-
if (overload === implementationFunction || !types_1.FunctionType.isOverloaded(overload)) {
|
1599
|
-
return;
|
1600
|
-
}
|
1601
1630
|
const diag = new diagnostic_1.DiagnosticAddendum();
|
1602
1631
|
if (!this._isLegalOverloadImplementation(overload, implementationFunction, diag)) {
|
1603
1632
|
if (implementationFunction.details.declaration) {
|
@@ -1697,10 +1726,10 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
1697
1726
|
let otherDecls = symbol.getDeclarations().filter((decl) => decl !== primaryDecl);
|
1698
1727
|
// If it's a function, we can skip any other declarations
|
1699
1728
|
// that are overloads or property setters/deleters.
|
1700
|
-
if (primaryDecl.type ===
|
1729
|
+
if (primaryDecl.type === 5 /* Function */) {
|
1701
1730
|
const primaryDeclTypeInfo = this._evaluator.getTypeOfFunction(primaryDecl.node);
|
1702
1731
|
otherDecls = otherDecls.filter((decl) => {
|
1703
|
-
if (decl.type !==
|
1732
|
+
if (decl.type !== 5 /* Function */) {
|
1704
1733
|
return true;
|
1705
1734
|
}
|
1706
1735
|
const funcTypeInfo = this._evaluator.getTypeOfFunction(decl.node);
|
@@ -1728,7 +1757,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
1728
1757
|
return;
|
1729
1758
|
}
|
1730
1759
|
let primaryDeclInfo;
|
1731
|
-
if (primaryDecl.type ===
|
1760
|
+
if (primaryDecl.type === 5 /* Function */) {
|
1732
1761
|
if (primaryDecl.isMethod) {
|
1733
1762
|
primaryDeclInfo = localize_1.Localizer.DiagnosticAddendum.seeMethodDeclaration();
|
1734
1763
|
}
|
@@ -1736,7 +1765,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
1736
1765
|
primaryDeclInfo = localize_1.Localizer.DiagnosticAddendum.seeFunctionDeclaration();
|
1737
1766
|
}
|
1738
1767
|
}
|
1739
|
-
else if (primaryDecl.type ===
|
1768
|
+
else if (primaryDecl.type === 6 /* Class */) {
|
1740
1769
|
primaryDeclInfo = localize_1.Localizer.DiagnosticAddendum.seeClassDeclaration();
|
1741
1770
|
}
|
1742
1771
|
else if (primaryDecl.type === 2 /* Parameter */) {
|
@@ -1745,13 +1774,16 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
1745
1774
|
else if (primaryDecl.type === 1 /* Variable */) {
|
1746
1775
|
primaryDeclInfo = localize_1.Localizer.DiagnosticAddendum.seeVariableDeclaration();
|
1747
1776
|
}
|
1777
|
+
else if (primaryDecl.type === 4 /* TypeAlias */) {
|
1778
|
+
primaryDeclInfo = localize_1.Localizer.DiagnosticAddendum.seeTypeAliasDeclaration();
|
1779
|
+
}
|
1748
1780
|
else {
|
1749
1781
|
primaryDeclInfo = localize_1.Localizer.DiagnosticAddendum.seeDeclaration();
|
1750
1782
|
}
|
1751
1783
|
const addPrimaryDeclInfo = (diag) => {
|
1752
1784
|
if (diag) {
|
1753
1785
|
let primaryDeclNode;
|
1754
|
-
if (primaryDecl.type ===
|
1786
|
+
if (primaryDecl.type === 5 /* Function */ || primaryDecl.type === 6 /* Class */) {
|
1755
1787
|
primaryDeclNode = primaryDecl.node.name;
|
1756
1788
|
}
|
1757
1789
|
else if (primaryDecl.type === 1 /* Variable */) {
|
@@ -1759,7 +1791,8 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
1759
1791
|
primaryDeclNode = primaryDecl.node;
|
1760
1792
|
}
|
1761
1793
|
}
|
1762
|
-
else if (primaryDecl.type === 2 /* Parameter */
|
1794
|
+
else if (primaryDecl.type === 2 /* Parameter */ ||
|
1795
|
+
primaryDecl.type === 3 /* TypeParameter */) {
|
1763
1796
|
if (primaryDecl.node.name) {
|
1764
1797
|
primaryDeclNode = primaryDecl.node.name;
|
1765
1798
|
}
|
@@ -1770,11 +1803,19 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
1770
1803
|
}
|
1771
1804
|
};
|
1772
1805
|
for (const otherDecl of otherDecls) {
|
1773
|
-
if (otherDecl.type ===
|
1774
|
-
|
1775
|
-
|
1806
|
+
if (otherDecl.type === 6 /* Class */) {
|
1807
|
+
let duplicateIsOk = false;
|
1808
|
+
if (primaryDecl.type === 3 /* TypeParameter */) {
|
1809
|
+
// The error will be reported elsewhere if a type parameter is
|
1810
|
+
// involved, so don't report it here.
|
1811
|
+
duplicateIsOk = true;
|
1812
|
+
}
|
1813
|
+
if (!duplicateIsOk) {
|
1814
|
+
const diag = this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.obscuredClassDeclaration().format({ name }), otherDecl.node.name);
|
1815
|
+
addPrimaryDeclInfo(diag);
|
1816
|
+
}
|
1776
1817
|
}
|
1777
|
-
else if (otherDecl.type ===
|
1818
|
+
else if (otherDecl.type === 5 /* Function */) {
|
1778
1819
|
const primaryType = this._evaluator.getTypeForDeclaration(primaryDecl);
|
1779
1820
|
let duplicateIsOk = false;
|
1780
1821
|
// If the return type has not yet been inferred, do so now.
|
@@ -1797,6 +1838,11 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
1797
1838
|
if (!isInSameStatementList && primaryType && otherType && (0, types_1.isTypeSame)(primaryType, otherType)) {
|
1798
1839
|
duplicateIsOk = true;
|
1799
1840
|
}
|
1841
|
+
if (primaryDecl.type === 3 /* TypeParameter */) {
|
1842
|
+
// The error will be reported elsewhere if a type parameter is
|
1843
|
+
// involved, so don't report it here.
|
1844
|
+
duplicateIsOk = true;
|
1845
|
+
}
|
1800
1846
|
if (!duplicateIsOk) {
|
1801
1847
|
const diag = this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, otherDecl.isMethod
|
1802
1848
|
? localize_1.Localizer.Diagnostic.obscuredMethodDeclaration().format({ name })
|
@@ -1806,8 +1852,17 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
1806
1852
|
}
|
1807
1853
|
else if (otherDecl.type === 2 /* Parameter */) {
|
1808
1854
|
if (otherDecl.node.name) {
|
1809
|
-
|
1810
|
-
|
1855
|
+
let duplicateIsOk = false;
|
1856
|
+
if (primaryDecl.type === 3 /* TypeParameter */) {
|
1857
|
+
// The error will be reported elsewhere if a type parameter is
|
1858
|
+
// involved, so don't report it here.
|
1859
|
+
duplicateIsOk = true;
|
1860
|
+
}
|
1861
|
+
if (!duplicateIsOk) {
|
1862
|
+
const message = localize_1.Localizer.Diagnostic.obscuredParameterDeclaration();
|
1863
|
+
const diag = this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, message.format({ name }), otherDecl.node.name);
|
1864
|
+
addPrimaryDeclInfo(diag);
|
1865
|
+
}
|
1811
1866
|
}
|
1812
1867
|
}
|
1813
1868
|
else if (otherDecl.type === 1 /* Variable */) {
|
@@ -1820,6 +1875,11 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
1820
1875
|
if (primaryType && otherType && (0, types_1.isTypeSame)(primaryType, otherType)) {
|
1821
1876
|
duplicateIsOk = true;
|
1822
1877
|
}
|
1878
|
+
if (primaryDecl.type === 3 /* TypeParameter */) {
|
1879
|
+
// The error will be reported elsewhere if a type parameter is
|
1880
|
+
// involved, so don't report it here.
|
1881
|
+
duplicateIsOk = true;
|
1882
|
+
}
|
1823
1883
|
if (!duplicateIsOk) {
|
1824
1884
|
const diag = this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.obscuredVariableDeclaration().format({ name }), otherDecl.node);
|
1825
1885
|
addPrimaryDeclInfo(diag);
|
@@ -1827,11 +1887,17 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
1827
1887
|
}
|
1828
1888
|
}
|
1829
1889
|
}
|
1890
|
+
else if (otherDecl.type === 4 /* TypeAlias */) {
|
1891
|
+
const diag = this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.obscuredTypeAliasDeclaration().format({ name }), otherDecl.node.name);
|
1892
|
+
addPrimaryDeclInfo(diag);
|
1893
|
+
}
|
1830
1894
|
}
|
1831
1895
|
}
|
1832
1896
|
_conditionallyReportUnusedSymbol(name, symbol, scopeType) {
|
1833
1897
|
const accessedSymbolSet = this._fileInfo.accessedSymbolSet;
|
1834
|
-
if (symbol.isIgnoredForProtocolMatch() ||
|
1898
|
+
if (symbol.isIgnoredForProtocolMatch() ||
|
1899
|
+
accessedSymbolSet.has(symbol.id) ||
|
1900
|
+
this._fileInfo.ipythonMode === sourceFile_1.IPythonMode.CellDocs) {
|
1835
1901
|
return;
|
1836
1902
|
}
|
1837
1903
|
// A name of "_" means "I know this symbol isn't used", so
|
@@ -1853,7 +1919,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
1853
1919
|
let message;
|
1854
1920
|
let rule;
|
1855
1921
|
switch (decl.type) {
|
1856
|
-
case
|
1922
|
+
case 8 /* Alias */:
|
1857
1923
|
diagnosticLevel = this._fileInfo.diagnosticRuleSet.reportUnusedImport;
|
1858
1924
|
rule = diagnosticRules_1.DiagnosticRule.reportUnusedImport;
|
1859
1925
|
if (decl.node.nodeType === 21 /* ImportAs */) {
|
@@ -1892,6 +1958,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
1892
1958
|
message = localize_1.Localizer.Diagnostic.unaccessedImport().format({ name: nameNode.value });
|
1893
1959
|
}
|
1894
1960
|
break;
|
1961
|
+
case 4 /* TypeAlias */:
|
1895
1962
|
case 1 /* Variable */:
|
1896
1963
|
case 2 /* Parameter */:
|
1897
1964
|
if (!isPrivate) {
|
@@ -1913,7 +1980,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
1913
1980
|
}
|
1914
1981
|
else if (decl.node.nodeType === 41 /* Parameter */) {
|
1915
1982
|
nameNode = decl.node.name;
|
1916
|
-
// Don't emit a diagnostic for unused parameters.
|
1983
|
+
// Don't emit a diagnostic for unused parameters or type parameters.
|
1917
1984
|
diagnosticLevel = 'none';
|
1918
1985
|
}
|
1919
1986
|
if (nameNode) {
|
@@ -1921,7 +1988,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
1921
1988
|
message = localize_1.Localizer.Diagnostic.unaccessedVariable().format({ name: nameNode.value });
|
1922
1989
|
}
|
1923
1990
|
break;
|
1924
|
-
case
|
1991
|
+
case 6 /* Class */:
|
1925
1992
|
if (!isPrivate) {
|
1926
1993
|
return;
|
1927
1994
|
}
|
@@ -1935,7 +2002,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
1935
2002
|
rule = diagnosticRules_1.DiagnosticRule.reportUnusedClass;
|
1936
2003
|
message = localize_1.Localizer.Diagnostic.unaccessedClass().format({ name: nameNode.value });
|
1937
2004
|
break;
|
1938
|
-
case
|
2005
|
+
case 5 /* Function */:
|
1939
2006
|
if (!isPrivate) {
|
1940
2007
|
return;
|
1941
2008
|
}
|
@@ -1949,13 +2016,23 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
1949
2016
|
rule = diagnosticRules_1.DiagnosticRule.reportUnusedFunction;
|
1950
2017
|
message = localize_1.Localizer.Diagnostic.unaccessedFunction().format({ name: nameNode.value });
|
1951
2018
|
break;
|
1952
|
-
|
2019
|
+
case 3 /* TypeParameter */:
|
2020
|
+
// Never report a diagnostic for an unused TypeParameter.
|
2021
|
+
diagnosticLevel = 'none';
|
2022
|
+
nameNode = decl.node.name;
|
2023
|
+
break;
|
2024
|
+
case 0 /* Intrinsic */:
|
2025
|
+
case 7 /* SpecialBuiltInClass */:
|
1953
2026
|
return;
|
2027
|
+
default:
|
2028
|
+
(0, debug_1.assertNever)(decl);
|
1954
2029
|
}
|
1955
|
-
|
1956
|
-
|
2030
|
+
const action = rule === diagnosticRules_1.DiagnosticRule.reportUnusedImport ? { action: "pyright.unusedImport" /* unusedImport */ } : undefined;
|
2031
|
+
if (nameNode) {
|
1957
2032
|
this._fileInfo.diagnosticSink.addUnusedCodeWithTextRange(localize_1.Localizer.Diagnostic.unaccessedSymbol().format({ name: nameNode.value }), nameNode, action);
|
1958
|
-
|
2033
|
+
if (rule !== undefined && message) {
|
2034
|
+
this._evaluator.addDiagnostic(diagnosticLevel, rule, message, nameNode);
|
2035
|
+
}
|
1959
2036
|
}
|
1960
2037
|
}
|
1961
2038
|
// Validates that a call to isinstance or issubclass are necessary. This is a
|
@@ -2288,7 +2365,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
2288
2365
|
if (!primaryDeclaration || primaryDeclaration.node === node) {
|
2289
2366
|
return;
|
2290
2367
|
}
|
2291
|
-
if (primaryDeclaration.type ===
|
2368
|
+
if (primaryDeclaration.type === 8 /* Alias */) {
|
2292
2369
|
// If this symbol is an import alias (i.e. it's a local name rather than the
|
2293
2370
|
// original imported name), skip the private check.
|
2294
2371
|
if (primaryDeclaration.usesLocalName) {
|
@@ -2474,7 +2551,8 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
2474
2551
|
}), returnAnnotation);
|
2475
2552
|
}
|
2476
2553
|
const diag = new diagnostic_1.DiagnosticAddendum();
|
2477
|
-
if ((0, types_1.isTypeVar)(declaredReturnType) &&
|
2554
|
+
if ((0, types_1.isTypeVar)(declaredReturnType) &&
|
2555
|
+
declaredReturnType.details.declaredVariance === 4 /* Contravariant */) {
|
2478
2556
|
diag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeVarIsContravariant().format({
|
2479
2557
|
name: types_1.TypeVarType.getReadableName(declaredReturnType),
|
2480
2558
|
}));
|
@@ -2604,7 +2682,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
2604
2682
|
}
|
2605
2683
|
}
|
2606
2684
|
}
|
2607
|
-
else if (decls[0].type ===
|
2685
|
+
else if (decls[0].type === 5 /* Function */) {
|
2608
2686
|
if (ParseTreeUtils.isSuiteEmpty(decls[0].node.suite) && decls[0]) {
|
2609
2687
|
if ((0, pathUtils_1.getFileExtension)(decls[0].path).toLowerCase() !== '.pyi') {
|
2610
2688
|
if (!isSymbolImplemented(name)) {
|
@@ -2793,9 +2871,8 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
2793
2871
|
// the proper variance (invariant, covariant, contravariant). See PEP 544
|
2794
2872
|
// for an explanation for why this is important to enforce.
|
2795
2873
|
_validateProtocolTypeParamVariance(errorNode, classType) {
|
2796
|
-
|
2797
|
-
|
2798
|
-
if (origTypeParams.length === 0) {
|
2874
|
+
// If this protocol has no TypeVars with specified variance, there's nothing to do here.
|
2875
|
+
if (classType.details.typeParameters.length === 0) {
|
2799
2876
|
return;
|
2800
2877
|
}
|
2801
2878
|
const objectType = this._evaluator.getBuiltInType(errorNode, 'object');
|
@@ -2803,13 +2880,17 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
2803
2880
|
return;
|
2804
2881
|
}
|
2805
2882
|
// Replace all of the type parameters with invariant TypeVars.
|
2806
|
-
const updatedTypeParams =
|
2883
|
+
const updatedTypeParams = classType.details.typeParameters.map((typeParam) => types_1.TypeVarType.cloneAsInvariant(typeParam));
|
2807
2884
|
const updatedClassType = types_1.ClassType.cloneWithNewTypeParameters(classType, updatedTypeParams);
|
2808
2885
|
const objectObject = types_1.ClassType.cloneAsInstance(objectType);
|
2809
|
-
const dummyTypeObject = types_1.ClassType.createInstantiable('
|
2886
|
+
const dummyTypeObject = types_1.ClassType.createInstantiable('__varianceDummy', '', '', '', 0, 0, undefined, undefined);
|
2810
2887
|
updatedTypeParams.forEach((param, paramIndex) => {
|
2811
|
-
// Skip variadics.
|
2812
|
-
if (param.details.isVariadic) {
|
2888
|
+
// Skip variadics and ParamSpecs.
|
2889
|
+
if (param.details.isVariadic || param.details.isParamSpec) {
|
2890
|
+
return;
|
2891
|
+
}
|
2892
|
+
// Skip type variables with auto-variance.
|
2893
|
+
if (param.details.declaredVariance === 0 /* Auto */) {
|
2813
2894
|
return;
|
2814
2895
|
}
|
2815
2896
|
// Replace all type arguments with a dummy type except for the
|
@@ -2829,29 +2910,29 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
2829
2910
|
/* isTypeArgumentExplicit */ true);
|
2830
2911
|
const destType = types_1.ClassType.cloneForSpecialization(updatedClassType, destTypeArgs,
|
2831
2912
|
/* isTypeArgumentExplicit */ true);
|
2832
|
-
const isDestSubtypeOfSrc =
|
2913
|
+
const isDestSubtypeOfSrc = this._evaluator.assignClassToSelf(srcType, destType);
|
2833
2914
|
let expectedVariance;
|
2834
2915
|
if (isDestSubtypeOfSrc) {
|
2835
|
-
expectedVariance =
|
2916
|
+
expectedVariance = 3 /* Covariant */;
|
2836
2917
|
}
|
2837
2918
|
else {
|
2838
|
-
const isSrcSubtypeOfDest =
|
2919
|
+
const isSrcSubtypeOfDest = this._evaluator.assignClassToSelf(destType, srcType);
|
2839
2920
|
if (isSrcSubtypeOfDest) {
|
2840
|
-
expectedVariance =
|
2921
|
+
expectedVariance = 4 /* Contravariant */;
|
2841
2922
|
}
|
2842
2923
|
else {
|
2843
|
-
expectedVariance =
|
2924
|
+
expectedVariance = 2 /* Invariant */;
|
2844
2925
|
}
|
2845
2926
|
}
|
2846
|
-
if (expectedVariance !==
|
2927
|
+
if (expectedVariance !== classType.details.typeParameters[paramIndex].details.declaredVariance) {
|
2847
2928
|
let message;
|
2848
|
-
if (expectedVariance ===
|
2929
|
+
if (expectedVariance === 3 /* Covariant */) {
|
2849
2930
|
message = localize_1.Localizer.Diagnostic.protocolVarianceCovariant().format({
|
2850
2931
|
variable: param.details.name,
|
2851
2932
|
class: classType.details.name,
|
2852
2933
|
});
|
2853
2934
|
}
|
2854
|
-
else if (expectedVariance ===
|
2935
|
+
else if (expectedVariance === 4 /* Contravariant */) {
|
2855
2936
|
message = localize_1.Localizer.Diagnostic.protocolVarianceContravariant().format({
|
2856
2937
|
variable: param.details.name,
|
2857
2938
|
class: classType.details.name,
|
@@ -2931,7 +3012,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
2931
3012
|
}
|
2932
3013
|
if ((0, types_1.isOverloadedFunction)(newMemberType)) {
|
2933
3014
|
// Find the implementation, not the overloaded signatures.
|
2934
|
-
newMemberType =
|
3015
|
+
newMemberType = types_1.OverloadedFunctionType.getImplementation(newMemberType);
|
2935
3016
|
if (!newMemberType) {
|
2936
3017
|
return;
|
2937
3018
|
}
|
@@ -2946,7 +3027,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
2946
3027
|
}
|
2947
3028
|
if ((0, types_1.isOverloadedFunction)(initMemberType)) {
|
2948
3029
|
// Find the implementation, not the overloaded signatures.
|
2949
|
-
initMemberType =
|
3030
|
+
initMemberType = types_1.OverloadedFunctionType.getImplementation(initMemberType);
|
2950
3031
|
if (!initMemberType) {
|
2951
3032
|
return;
|
2952
3033
|
}
|
@@ -3084,9 +3165,9 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
3084
3165
|
}
|
3085
3166
|
else if ((0, types_1.isOverloadedFunction)(overrideType)) {
|
3086
3167
|
// Use the last overload.
|
3087
|
-
overrideFunction =
|
3168
|
+
overrideFunction = types_1.OverloadedFunctionType.getImplementation(overrideType);
|
3088
3169
|
// If the last overload isn't an implementation, skip the check for this symbol.
|
3089
|
-
if (
|
3170
|
+
if (!overrideFunction) {
|
3090
3171
|
return;
|
3091
3172
|
}
|
3092
3173
|
}
|
@@ -3094,7 +3175,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
3094
3175
|
if (!this._evaluator.validateOverrideMethod(baseType, overrideFunction, diagAddendum,
|
3095
3176
|
/* enforceParamNameMatch */ true)) {
|
3096
3177
|
const decl = overrideFunction.details.declaration;
|
3097
|
-
if (decl && decl.type ===
|
3178
|
+
if (decl && decl.type === 5 /* Function */) {
|
3098
3179
|
diag = this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportIncompatibleMethodOverride, diagnosticRules_1.DiagnosticRule.reportIncompatibleMethodOverride, localize_1.Localizer.Diagnostic.baseClassMethodTypeIncompatible().format({
|
3099
3180
|
classType: childClassType.details.name,
|
3100
3181
|
name: memberName,
|
@@ -3154,7 +3235,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
3154
3235
|
}
|
3155
3236
|
// If the symbol has no declaration, and the type is inferred,
|
3156
3237
|
// skip this check.
|
3157
|
-
if (!symbol.hasTypedDeclarations()) {
|
3238
|
+
if (!symbol.hasTypedDeclarations() && !(0, symbolUtils_1.isFinalVariable)(symbol)) {
|
3158
3239
|
return;
|
3159
3240
|
}
|
3160
3241
|
// Get the symbol type defined in this class.
|
@@ -3182,7 +3263,6 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
3182
3263
|
});
|
3183
3264
|
}
|
3184
3265
|
_validateBaseClassOverride(baseClassAndSymbol, overrideSymbol, overrideType, childClassType, memberName) {
|
3185
|
-
var _a;
|
3186
3266
|
if (!(0, types_1.isInstantiableClass)(baseClassAndSymbol.classType)) {
|
3187
3267
|
return;
|
3188
3268
|
}
|
@@ -3200,15 +3280,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
3200
3280
|
const baseType = (0, typeUtils_1.partiallySpecializeType)(this._evaluator.getEffectiveTypeOfSymbol(baseClassAndSymbol.symbol), baseClassAndSymbol.classType);
|
3201
3281
|
if ((0, types_1.isFunction)(baseType) || (0, types_1.isOverloadedFunction)(baseType)) {
|
3202
3282
|
const diagAddendum = new diagnostic_1.DiagnosticAddendum();
|
3203
|
-
|
3204
|
-
if ((0, types_1.isFunction)(overrideType)) {
|
3205
|
-
overrideFunction = overrideType;
|
3206
|
-
}
|
3207
|
-
else if ((0, types_1.isOverloadedFunction)(overrideType)) {
|
3208
|
-
// Use the last overload.
|
3209
|
-
overrideFunction = overrideType.overloads[overrideType.overloads.length - 1];
|
3210
|
-
}
|
3211
|
-
if (overrideFunction) {
|
3283
|
+
if ((0, types_1.isFunction)(overrideType) || (0, types_1.isOverloadedFunction)(overrideType)) {
|
3212
3284
|
const exemptMethods = ['__init__', '__new__', '__init_subclass__'];
|
3213
3285
|
// Don't enforce parameter names for dundered methods. Many of them
|
3214
3286
|
// are misnamed in typeshed stubs, so this would result in many
|
@@ -3217,13 +3289,15 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
3217
3289
|
// Don't check certain magic functions or private symbols.
|
3218
3290
|
if (!exemptMethods.some((exempt) => exempt === memberName) &&
|
3219
3291
|
!SymbolNameUtils.isPrivateName(memberName)) {
|
3220
|
-
if (!this._evaluator.validateOverrideMethod(baseType,
|
3221
|
-
const decl = (
|
3292
|
+
if (!this._evaluator.validateOverrideMethod(baseType, overrideType, diagAddendum, enforceParamNameMatch)) {
|
3293
|
+
const decl = (0, types_1.isFunction)(overrideType) && overrideType.details.declaration
|
3294
|
+
? overrideType.details.declaration
|
3295
|
+
: (0, symbolUtils_1.getLastTypedDeclaredForSymbol)(overrideSymbol);
|
3222
3296
|
if (decl) {
|
3223
3297
|
const diag = this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportIncompatibleMethodOverride, diagnosticRules_1.DiagnosticRule.reportIncompatibleMethodOverride, localize_1.Localizer.Diagnostic.incompatibleMethodOverride().format({
|
3224
3298
|
name: memberName,
|
3225
3299
|
className: baseClassAndSymbol.classType.details.name,
|
3226
|
-
}) + diagAddendum.getString(), decl.type ===
|
3300
|
+
}) + diagAddendum.getString(), decl.type === 5 /* Function */ ? decl.node.name : decl.node);
|
3227
3301
|
const origDecl = (0, symbolUtils_1.getLastTypedDeclaredForSymbol)(baseClassAndSymbol.symbol);
|
3228
3302
|
if (diag && origDecl) {
|
3229
3303
|
diag.addRelatedInfo(localize_1.Localizer.DiagnosticAddendum.overriddenMethod(), origDecl.path, origDecl.range);
|
@@ -3235,7 +3309,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
3235
3309
|
// Private names (starting with double underscore) are exempt from this check.
|
3236
3310
|
if (!SymbolNameUtils.isPrivateName(memberName) && types_1.FunctionType.isFinal(baseType)) {
|
3237
3311
|
const decl = (0, symbolUtils_1.getLastTypedDeclaredForSymbol)(overrideSymbol);
|
3238
|
-
if (decl && decl.type ===
|
3312
|
+
if (decl && decl.type === 5 /* Function */) {
|
3239
3313
|
const diag = this._evaluator.addError(localize_1.Localizer.Diagnostic.finalMethodOverride().format({
|
3240
3314
|
name: memberName,
|
3241
3315
|
className: baseClassAndSymbol.classType.details.name,
|
@@ -3317,7 +3391,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
3317
3391
|
name: methodName,
|
3318
3392
|
}));
|
3319
3393
|
const decl = subclassMethodType.details.declaration;
|
3320
|
-
if (decl && decl.type ===
|
3394
|
+
if (decl && decl.type === 5 /* Function */) {
|
3321
3395
|
const diag = this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportIncompatibleMethodOverride, diagnosticRules_1.DiagnosticRule.reportIncompatibleMethodOverride, localize_1.Localizer.Diagnostic.propertyOverridden().format({
|
3322
3396
|
name: memberName,
|
3323
3397
|
className: baseClassType.details.name,
|
@@ -3355,6 +3429,18 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
3355
3429
|
diag.addRelatedInfo(localize_1.Localizer.DiagnosticAddendum.overriddenSymbol(), origDecl.path, origDecl.range);
|
3356
3430
|
}
|
3357
3431
|
}
|
3432
|
+
// Verify that there is not a Final mismatch.
|
3433
|
+
const isBaseVarFinal = (0, symbolUtils_1.isFinalVariable)(baseClassAndSymbol.symbol);
|
3434
|
+
const overrideFinalVarDecl = decls.find((d) => (0, declarationUtils_1.isFinalVariableDeclaration)(d));
|
3435
|
+
if (!isBaseVarFinal && overrideFinalVarDecl) {
|
3436
|
+
const diag = this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportIncompatibleVariableOverride, diagnosticRules_1.DiagnosticRule.reportIncompatibleVariableOverride, localize_1.Localizer.Diagnostic.variableFinalOverride().format({
|
3437
|
+
name: memberName,
|
3438
|
+
className: baseClassAndSymbol.classType.details.name,
|
3439
|
+
}), lastDecl.node);
|
3440
|
+
if (diag) {
|
3441
|
+
diag.addRelatedInfo(localize_1.Localizer.DiagnosticAddendum.overriddenSymbol(), overrideFinalVarDecl.path, overrideFinalVarDecl.range);
|
3442
|
+
}
|
3443
|
+
}
|
3358
3444
|
// Verify that a class variable isn't overriding an instance
|
3359
3445
|
// variable or vice versa.
|
3360
3446
|
const isBaseClassVar = baseClassAndSymbol.symbol.isClassVar();
|
@@ -3368,7 +3454,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
3368
3454
|
}
|
3369
3455
|
// If the subclass is declaring an inner class, we'll consider that
|
3370
3456
|
// to be a ClassVar.
|
3371
|
-
if (overrideSymbol.getTypedDeclarations().every((decl) => decl.type ===
|
3457
|
+
if (overrideSymbol.getTypedDeclarations().every((decl) => decl.type === 6 /* Class */)) {
|
3372
3458
|
isClassVar = true;
|
3373
3459
|
}
|
3374
3460
|
}
|
@@ -3689,7 +3775,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
3689
3775
|
// Were all of the exception types overridden?
|
3690
3776
|
if (typesOfThisExcept.length === overriddenExceptionCount) {
|
3691
3777
|
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.unreachableExcept() + diagAddendum.getString(), except.typeExpression);
|
3692
|
-
this._evaluator.
|
3778
|
+
this._evaluator.addUnreachableCode(except, except.exceptSuite);
|
3693
3779
|
}
|
3694
3780
|
}
|
3695
3781
|
exceptionTypesSoFar.push(...typesOfThisExcept);
|