@zzzen/pyright-internal 1.2.0-dev.2022-07-02 → 1.2.0-dev.20220703
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/aliasDeclarationUtils.js +2 -2
- 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 +133 -30
- package/dist/analyzer/binder.js.map +1 -1
- package/dist/analyzer/checker.d.ts +4 -1
- package/dist/analyzer/checker.js +125 -47
- package/dist/analyzer/checker.js.map +1 -1
- package/dist/analyzer/constraintSolver.js +6 -3
- 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/packageTypeVerifier.js +6 -6
- package/dist/analyzer/parseTreeUtils.d.ts +3 -3
- package/dist/analyzer/parseTreeUtils.js +16 -11
- 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/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/tracePrinter.js +8 -4
- package/dist/analyzer/tracePrinter.js.map +1 -1
- package/dist/analyzer/typeDocStringUtils.js +1 -1
- package/dist/analyzer/typeEvaluator.js +524 -176
- package/dist/analyzer/typeEvaluator.js.map +1 -1
- package/dist/analyzer/typeEvaluatorTypes.d.ts +2 -0
- package/dist/analyzer/typeEvaluatorWithTracker.js +2 -0
- package/dist/analyzer/typeEvaluatorWithTracker.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.js +10 -5
- package/dist/analyzer/typeUtils.js.map +1 -1
- package/dist/analyzer/types.d.ts +11 -4
- package/dist/analyzer/types.js +23 -8
- package/dist/analyzer/types.js.map +1 -1
- package/dist/languageService/autoImporter.js +1 -1
- package/dist/languageService/callHierarchyProvider.js +9 -9
- package/dist/languageService/completionProvider.js +19 -13
- 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/referencesProvider.js +8 -5
- package/dist/languageService/referencesProvider.js.map +1 -1
- package/dist/languageService/tooltipUtils.js +1 -1
- package/dist/localization/localize.d.ts +27 -0
- package/dist/localization/localize.js +16 -0
- package/dist/localization/localize.js.map +1 -1
- package/dist/localization/package.nls.en-us.json +18 -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 +3 -0
- package/dist/parser/parser.js +129 -12
- package/dist/parser/parser.js.map +1 -1
- package/dist/parser/tokenizer.js +4 -3
- 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/tests/typeEvaluator5.test.d.ts +1 -0
- package/dist/tests/typeEvaluator5.test.js +112 -0
- package/dist/tests/typeEvaluator5.test.js.map +1 -0
- package/package.json +1 -1
@@ -660,15 +660,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
660
660
|
typeResult.type.details.illegalRecursionDetected = true;
|
661
661
|
}
|
662
662
|
}
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
writeTypeCache(node, typeResult.type, flags, !!typeResult.isIncomplete, expectedType,
|
668
|
-
/* allowSpeculativeCaching */ true);
|
669
|
-
if (expectedType && !(0, types_1.isAnyOrUnknown)(expectedType) && !(0, types_1.isNever)(expectedType)) {
|
670
|
-
expectedTypeCache.set(node.id, expectedType);
|
671
|
-
}
|
663
|
+
writeTypeCache(node, typeResult.type, flags, !!typeResult.isIncomplete, expectedType,
|
664
|
+
/* allowSpeculativeCaching */ true);
|
665
|
+
if (expectedType && !(0, types_1.isAnyOrUnknown)(expectedType) && !(0, types_1.isNever)(expectedType)) {
|
666
|
+
expectedTypeCache.set(node.id, expectedType);
|
672
667
|
}
|
673
668
|
if (printExpressionTypes) {
|
674
669
|
printExpressionSpaceCount--;
|
@@ -1368,7 +1363,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
1368
1363
|
// Handle the case where the symbol is a class-level variable
|
1369
1364
|
// where the type isn't declared in this class but is in
|
1370
1365
|
// a parent class.
|
1371
|
-
if (getDeclaredTypeOfSymbol(symbol) === undefined &&
|
1366
|
+
if (getDeclaredTypeOfSymbol(symbol, expression) === undefined &&
|
1372
1367
|
symbolWithScope.scope.type === 2 /* Class */) {
|
1373
1368
|
const enclosingClass = ParseTreeUtils.getEnclosingClassOrFunction(expression);
|
1374
1369
|
if (enclosingClass && enclosingClass.nodeType === 10 /* Class */) {
|
@@ -1386,7 +1381,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
1386
1381
|
break;
|
1387
1382
|
}
|
1388
1383
|
case 54 /* TypeAnnotation */: {
|
1389
|
-
return getDeclaredTypeForExpression(expression.valueExpression);
|
1384
|
+
return getDeclaredTypeForExpression(expression.valueExpression, usage);
|
1390
1385
|
}
|
1391
1386
|
case 35 /* MemberAccess */: {
|
1392
1387
|
const baseType = makeTopLevelTypeVarsConcrete(getTypeOfExpression(expression.leftExpression, 2 /* DoNotSpecialize */).type);
|
@@ -2540,9 +2535,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
2540
2535
|
return undefined;
|
2541
2536
|
}
|
2542
2537
|
function getTypeOfName(node, flags) {
|
2543
|
-
var _a;
|
2538
|
+
var _a, _b;
|
2544
2539
|
const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
|
2545
2540
|
const name = node.value;
|
2541
|
+
let symbol;
|
2546
2542
|
let type;
|
2547
2543
|
let isIncomplete = false;
|
2548
2544
|
const allowForwardReferences = (flags & 4 /* AllowForwardReferences */) !== 0 || fileInfo.isStubFile;
|
@@ -2556,96 +2552,104 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
2556
2552
|
};
|
2557
2553
|
}
|
2558
2554
|
}
|
2559
|
-
|
2560
|
-
|
2561
|
-
|
2562
|
-
|
2563
|
-
|
2564
|
-
|
2565
|
-
|
2566
|
-
|
2567
|
-
|
2568
|
-
|
2569
|
-
|
2570
|
-
|
2571
|
-
|
2572
|
-
|
2573
|
-
|
2574
|
-
|
2575
|
-
|
2576
|
-
|
2577
|
-
|
2578
|
-
|
2579
|
-
|
2580
|
-
|
2581
|
-
|
2582
|
-
|
2583
|
-
|
2584
|
-
|
2585
|
-
|
2586
|
-
if (useCodeFlowAnalysis && !isSpecialBuiltIn) {
|
2587
|
-
// See if code flow analysis can tell us anything more about the type.
|
2588
|
-
// If the symbol is declared outside of our execution scope, use its effective
|
2589
|
-
// type. If it's declared inside our execution scope, it generally starts
|
2590
|
-
// as unbound at the start of the code flow.
|
2591
|
-
const typeAtStart = symbolWithScope.isBeyondExecutionScope || !symbol.isInitiallyUnbound()
|
2592
|
-
? effectiveType
|
2593
|
-
: types_1.UnboundType.create();
|
2594
|
-
const codeFlowTypeResult = getFlowTypeOfReference(node, symbol.id, typeAtStart,
|
2595
|
-
/* isInitialTypeIncomplete */ false,
|
2596
|
-
/* startNode */ undefined);
|
2597
|
-
if (codeFlowTypeResult.type) {
|
2598
|
-
type = codeFlowTypeResult.type;
|
2599
|
-
}
|
2600
|
-
if (codeFlowTypeResult.isIncomplete) {
|
2555
|
+
const typeParamSymbol = AnalyzerNodeInfo.getTypeParameterSymbol(node);
|
2556
|
+
if (typeParamSymbol) {
|
2557
|
+
symbol = typeParamSymbol;
|
2558
|
+
type = (_a = getDeclaredTypeOfSymbol(typeParamSymbol)) !== null && _a !== void 0 ? _a : types_1.UnknownType.create();
|
2559
|
+
setSymbolAccessed(fileInfo, symbol, node);
|
2560
|
+
}
|
2561
|
+
else {
|
2562
|
+
// Look for the scope that contains the value definition and
|
2563
|
+
// see if it has a declared type.
|
2564
|
+
const symbolWithScope = lookUpSymbolRecursive(node, name, !allowForwardReferences, allowForwardReferences && (flags & 1024 /* ExpectingTypeAnnotation */) !== 0);
|
2565
|
+
if (symbolWithScope) {
|
2566
|
+
let useCodeFlowAnalysis = !allowForwardReferences;
|
2567
|
+
// If the symbol is implicitly imported from the builtin
|
2568
|
+
// scope, there's no need to use code flow analysis.
|
2569
|
+
if (symbolWithScope.scope.type === 4 /* Builtin */) {
|
2570
|
+
useCodeFlowAnalysis = false;
|
2571
|
+
}
|
2572
|
+
symbol = symbolWithScope.symbol;
|
2573
|
+
// Get the effective type (either the declared type or the inferred type).
|
2574
|
+
// If we're using code flow analysis, pass the usage node so we consider
|
2575
|
+
// only the assignment nodes that are reachable from this usage.
|
2576
|
+
const effectiveTypeInfo = getEffectiveTypeOfSymbolForUsage(symbol, useCodeFlowAnalysis ? node : undefined);
|
2577
|
+
let effectiveType = (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(effectiveTypeInfo.type);
|
2578
|
+
if (effectiveTypeInfo.isIncomplete) {
|
2579
|
+
if ((0, types_1.isUnbound)(effectiveType)) {
|
2580
|
+
effectiveType = types_1.UnknownType.create(/* isIncomplete */ true);
|
2581
|
+
}
|
2601
2582
|
isIncomplete = true;
|
2602
2583
|
}
|
2603
|
-
if (
|
2604
|
-
|
2605
|
-
|
2606
|
-
|
2607
|
-
|
2608
|
-
|
2584
|
+
if (effectiveTypeInfo.isRecursiveDefinition && isNodeReachable(node)) {
|
2585
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.recursiveDefinition().format({ name }), node);
|
2586
|
+
}
|
2587
|
+
const isSpecialBuiltIn = !!effectiveType && (0, types_1.isInstantiableClass)(effectiveType) && types_1.ClassType.isSpecialBuiltIn(effectiveType);
|
2588
|
+
type = effectiveType;
|
2589
|
+
if (useCodeFlowAnalysis && !isSpecialBuiltIn) {
|
2590
|
+
// See if code flow analysis can tell us anything more about the type.
|
2591
|
+
// If the symbol is declared outside of our execution scope, use its effective
|
2592
|
+
// type. If it's declared inside our execution scope, it generally starts
|
2593
|
+
// as unbound at the start of the code flow.
|
2594
|
+
const typeAtStart = symbolWithScope.isBeyondExecutionScope || !symbol.isInitiallyUnbound()
|
2595
|
+
? effectiveType
|
2596
|
+
: types_1.UnboundType.create();
|
2597
|
+
const codeFlowTypeResult = getFlowTypeOfReference(node, symbol.id, typeAtStart,
|
2598
|
+
/* isInitialTypeIncomplete */ false,
|
2599
|
+
/* startNode */ undefined);
|
2600
|
+
if (codeFlowTypeResult.type) {
|
2601
|
+
type = codeFlowTypeResult.type;
|
2602
|
+
}
|
2603
|
+
if (codeFlowTypeResult.isIncomplete) {
|
2609
2604
|
isIncomplete = true;
|
2610
2605
|
}
|
2606
|
+
if (!codeFlowTypeResult.type && symbolWithScope.isBeyondExecutionScope) {
|
2607
|
+
const outerScopeTypeResult = getCodeFlowTypeForCapturedVariable(node, symbolWithScope, effectiveType);
|
2608
|
+
if (outerScopeTypeResult === null || outerScopeTypeResult === void 0 ? void 0 : outerScopeTypeResult.type) {
|
2609
|
+
type = outerScopeTypeResult.type;
|
2610
|
+
}
|
2611
|
+
if (outerScopeTypeResult === null || outerScopeTypeResult === void 0 ? void 0 : outerScopeTypeResult.isIncomplete) {
|
2612
|
+
isIncomplete = true;
|
2613
|
+
}
|
2614
|
+
}
|
2611
2615
|
}
|
2612
|
-
|
2613
|
-
|
2614
|
-
|
2615
|
-
|
2616
|
-
|
2617
|
-
|
2618
|
-
|
2619
|
-
|
2620
|
-
|
2621
|
-
|
2622
|
-
|
2623
|
-
|
2624
|
-
|
2625
|
-
|
2626
|
-
|
2627
|
-
|
2628
|
-
|
2629
|
-
|
2630
|
-
|
2631
|
-
|
2632
|
-
|
2633
|
-
|
2634
|
-
|
2635
|
-
|
2616
|
+
// Detect, report, and fill in missing type arguments if appropriate.
|
2617
|
+
type = reportMissingTypeArguments(node, type, flags);
|
2618
|
+
setSymbolAccessed(fileInfo, symbol, node);
|
2619
|
+
if ((flags & 1024 /* ExpectingTypeAnnotation */) !== 0) {
|
2620
|
+
// Verify that the name does not refer to a (non type alias) variable.
|
2621
|
+
if (effectiveTypeInfo.includesVariableDecl && !type.typeAliasInfo) {
|
2622
|
+
let isAllowedTypeForVariable = (0, types_1.isTypeVar)(type) || (0, typeUtils_1.isTypeAliasPlaceholder)(type);
|
2623
|
+
if ((0, types_1.isClass)(type) && !type.includeSubclasses) {
|
2624
|
+
// This check exempts class types that are created by calling
|
2625
|
+
// NewType, NamedTuple, and by invoking a metaclass directly.
|
2626
|
+
isAllowedTypeForVariable = true;
|
2627
|
+
}
|
2628
|
+
// Disable for assignments in the typings.pyi file, since it defines special forms.
|
2629
|
+
if (!isAllowedTypeForVariable && !fileInfo.isTypingStubFile) {
|
2630
|
+
// This might be a union that was previously a type alias
|
2631
|
+
// but was reconstituted in such a way that we lost the
|
2632
|
+
// typeAliasInfo. Avoid the false positive error by suppressing
|
2633
|
+
// the error when it looks like a plausible type alias type.
|
2634
|
+
if (effectiveTypeInfo.includesIllegalTypeAliasDecl ||
|
2635
|
+
!types_1.TypeBase.isInstantiable(type) ||
|
2636
|
+
(flags & 2 /* DoNotSpecialize */) !== 0) {
|
2637
|
+
addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeAnnotationVariable(), node);
|
2638
|
+
type = types_1.UnknownType.create();
|
2639
|
+
}
|
2636
2640
|
}
|
2637
2641
|
}
|
2638
2642
|
}
|
2639
2643
|
}
|
2640
|
-
}
|
2641
|
-
else {
|
2642
|
-
// Handle the special case of "reveal_type" and "reveal_locals".
|
2643
|
-
if (name === 'reveal_type' || name === 'reveal_locals') {
|
2644
|
-
type = types_1.AnyType.create();
|
2645
|
-
}
|
2646
2644
|
else {
|
2647
|
-
|
2648
|
-
|
2645
|
+
// Handle the special case of "reveal_type" and "reveal_locals".
|
2646
|
+
if (name === 'reveal_type' || name === 'reveal_locals') {
|
2647
|
+
type = types_1.AnyType.create();
|
2648
|
+
}
|
2649
|
+
else {
|
2650
|
+
addDiagnostic(fileInfo.diagnosticRuleSet.reportUndefinedVariable, diagnosticRules_1.DiagnosticRule.reportUndefinedVariable, localize_1.Localizer.Diagnostic.symbolIsUndefined().format({ name }), node);
|
2651
|
+
type = types_1.UnknownType.create();
|
2652
|
+
}
|
2649
2653
|
}
|
2650
2654
|
}
|
2651
2655
|
if ((0, types_1.isParamSpec)(type)) {
|
@@ -2660,7 +2664,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
2660
2664
|
type.details.name === name) {
|
2661
2665
|
// Handle the special case of a PEP 604 union. These can appear within
|
2662
2666
|
// an implied type alias where we are not expecting a type.
|
2663
|
-
const isPep604Union = ((
|
2667
|
+
const isPep604Union = ((_b = node.parent) === null || _b === void 0 ? void 0 : _b.nodeType) === 7 /* BinaryOperation */ &&
|
2664
2668
|
node.parent.operator === 6 /* BitwiseOr */;
|
2665
2669
|
if (!isPep604Union) {
|
2666
2670
|
// A TypeVar in contexts where we're not expecting a type is
|
@@ -2748,6 +2752,20 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
2748
2752
|
type = scopedTypeVarInfo.type;
|
2749
2753
|
if ((flags & 2048 /* DisallowTypeVarsWithScopeId */) !== 0 && type.scopeId !== undefined) {
|
2750
2754
|
if (!type.details.isSynthesized && !type.details.isParamSpec) {
|
2755
|
+
// This TypeVar already has a scope ID assigned to it. See if it
|
2756
|
+
// originates from type parameter syntax. If so, allow it.
|
2757
|
+
if (type.details.isTypeParamSyntax) {
|
2758
|
+
return type;
|
2759
|
+
}
|
2760
|
+
// If this type variable expression is used within a generic class,
|
2761
|
+
// function, or type alias that uses type parameter syntax, there is
|
2762
|
+
// no need to report an error here.
|
2763
|
+
const typeVarScopeNode = ParseTreeUtils.getTypeVarScopeNode(node);
|
2764
|
+
if (typeVarScopeNode &&
|
2765
|
+
typeVarScopeNode.typeParameters &&
|
2766
|
+
!typeVarScopeNode.typeParameters.parameters.some((t) => t.name === node)) {
|
2767
|
+
return type;
|
2768
|
+
}
|
2751
2769
|
addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeVarUsedByOuterScope().format({ name: type.details.name }), node);
|
2752
2770
|
}
|
2753
2771
|
}
|
@@ -2773,6 +2791,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
2773
2791
|
}
|
2774
2792
|
}
|
2775
2793
|
if (enclosingScope) {
|
2794
|
+
// If the enclosing scope is using type parameter syntax, traditional
|
2795
|
+
// type variables can't be used in this context.
|
2796
|
+
if (enclosingScope.typeParameters) {
|
2797
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeParameterNotDeclared().format({
|
2798
|
+
name: type.details.name,
|
2799
|
+
container: enclosingScope.name.value,
|
2800
|
+
}), node);
|
2801
|
+
}
|
2776
2802
|
type = types_1.TypeVarType.cloneForScopeId(type, getScopeIdForNode(enclosingScope), enclosingScope.name.value, enclosingScope.nodeType === 28 /* Function */
|
2777
2803
|
? 1 /* Function */
|
2778
2804
|
: 0 /* Class */);
|
@@ -2866,50 +2892,48 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
2866
2892
|
// Walks up the parse tree to find a function, class, or type alias
|
2867
2893
|
// assignment that provides the context for a type variable.
|
2868
2894
|
function findScopedTypeVar(node, type) {
|
2869
|
-
var _a;
|
2870
2895
|
let curNode = node;
|
2871
2896
|
let nestedClassCount = 0;
|
2872
2897
|
(0, debug_1.assert)(types_1.TypeBase.isInstantiable(type));
|
2873
2898
|
while (curNode) {
|
2874
|
-
|
2875
|
-
// that contains the TypeVar in its signature, but we make an exception
|
2876
|
-
// for TypeVars that are used in a member access expression to accommodate
|
2877
|
-
// ParamSpecs (P.args and P.kwargs).
|
2878
|
-
curNode = ParseTreeUtils.getTypeVarScopeNode(curNode, ((_a = node.parent) === null || _a === void 0 ? void 0 : _a.nodeType) === 35 /* MemberAccess */);
|
2899
|
+
curNode = ParseTreeUtils.getTypeVarScopeNode(curNode);
|
2879
2900
|
if (!curNode) {
|
2880
2901
|
break;
|
2881
2902
|
}
|
2882
|
-
let
|
2903
|
+
let typeParametersForScope;
|
2904
|
+
let scopeUsesTypeParameterSyntax = false;
|
2883
2905
|
if (curNode.nodeType === 10 /* Class */) {
|
2884
2906
|
const classTypeInfo = getTypeOfClass(curNode);
|
2885
|
-
if (classTypeInfo) {
|
2886
|
-
|
2907
|
+
if (classTypeInfo && !types_1.ClassType.isPartiallyEvaluated(classTypeInfo.classType)) {
|
2908
|
+
typeParametersForScope = classTypeInfo.classType.details.typeParameters;
|
2887
2909
|
}
|
2910
|
+
scopeUsesTypeParameterSyntax = !!curNode.typeParameters;
|
2888
2911
|
nestedClassCount++;
|
2889
2912
|
}
|
2890
2913
|
else if (curNode.nodeType === 28 /* Function */) {
|
2891
2914
|
const functionTypeInfo = getTypeOfFunction(curNode);
|
2892
2915
|
if (functionTypeInfo) {
|
2893
|
-
|
2916
|
+
typeParametersForScope = [];
|
2894
2917
|
functionTypeInfo.functionType.details.parameters.forEach((param) => {
|
2895
2918
|
if (param.hasDeclaredType) {
|
2896
|
-
(0, typeUtils_1.addTypeVarsToListIfUnique)(
|
2919
|
+
(0, typeUtils_1.addTypeVarsToListIfUnique)(typeParametersForScope, (0, typeUtils_1.getTypeVarArgumentsRecursive)(param.type));
|
2897
2920
|
}
|
2898
2921
|
});
|
2899
2922
|
if (functionTypeInfo.functionType.details.declaredReturnType) {
|
2900
|
-
(0, typeUtils_1.addTypeVarsToListIfUnique)(
|
2923
|
+
(0, typeUtils_1.addTypeVarsToListIfUnique)(typeParametersForScope, (0, typeUtils_1.getTypeVarArgumentsRecursive)(functionTypeInfo.functionType.details.declaredReturnType));
|
2901
2924
|
}
|
2902
2925
|
}
|
2926
|
+
scopeUsesTypeParameterSyntax = !!curNode.typeParameters;
|
2903
2927
|
}
|
2904
|
-
else if (curNode.nodeType ===
|
2905
|
-
|
2928
|
+
else if (curNode.nodeType === 77 /* TypeAlias */) {
|
2929
|
+
scopeUsesTypeParameterSyntax = !!curNode.typeParameters;
|
2906
2930
|
}
|
2907
|
-
if (
|
2908
|
-
const match =
|
2931
|
+
if (typeParametersForScope) {
|
2932
|
+
const match = typeParametersForScope.find((typeVar) => typeVar.details.name === type.details.name);
|
2909
2933
|
if (match === null || match === void 0 ? void 0 : match.scopeId) {
|
2910
2934
|
// Use the scoped version of the TypeVar rather than the (unscoped) original type.
|
2911
2935
|
type = types_1.TypeVarType.cloneForScopeId(type, match.scopeId, match.scopeName, match.scopeType);
|
2912
|
-
return { type, foundInterveningClass: nestedClassCount > 1 };
|
2936
|
+
return { type, foundInterveningClass: nestedClassCount > 1 && !scopeUsesTypeParameterSyntax };
|
2913
2937
|
}
|
2914
2938
|
}
|
2915
2939
|
curNode = curNode.parent;
|
@@ -2917,14 +2941,29 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
2917
2941
|
// See if this is part of an assignment statement that is defining a type alias.
|
2918
2942
|
curNode = node;
|
2919
2943
|
while (curNode) {
|
2920
|
-
|
2921
|
-
|
2944
|
+
let leftType;
|
2945
|
+
let typeAliasNode = undefined;
|
2946
|
+
if (curNode.nodeType === 77 /* TypeAlias */) {
|
2947
|
+
leftType = readTypeCache(curNode.name, 0 /* None */);
|
2948
|
+
typeAliasNode = curNode;
|
2949
|
+
}
|
2950
|
+
else if (curNode.nodeType === 3 /* Assignment */) {
|
2951
|
+
leftType = readTypeCache(curNode.leftExpression, 0 /* None */);
|
2952
|
+
}
|
2953
|
+
if (leftType) {
|
2922
2954
|
// Is this a placeholder that was temporarily written to the cache for
|
2923
2955
|
// purposes of resolving type aliases?
|
2924
2956
|
if (leftType &&
|
2925
2957
|
(0, types_1.isTypeVar)(leftType) &&
|
2926
2958
|
leftType.details.recursiveTypeAliasScopeId &&
|
2927
2959
|
leftType.details.recursiveTypeAliasName) {
|
2960
|
+
// Type alias statements cannot be used with old-style type variables.
|
2961
|
+
if (typeAliasNode && !type.details.isTypeParamSyntax) {
|
2962
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeParameterNotDeclared().format({
|
2963
|
+
name: type.details.name,
|
2964
|
+
container: typeAliasNode.name.value,
|
2965
|
+
}), node);
|
2966
|
+
}
|
2928
2967
|
return {
|
2929
2968
|
type: types_1.TypeVarType.cloneForScopeId(type, leftType.details.recursiveTypeAliasScopeId, leftType.details.recursiveTypeAliasName, 2 /* TypeAlias */),
|
2930
2969
|
foundInterveningClass: false,
|
@@ -4130,7 +4169,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4130
4169
|
}
|
4131
4170
|
if ((0, typeUtils_1.isTypeAliasPlaceholder)(baseTypeResult.type)) {
|
4132
4171
|
const typeArgTypes = getTypeArgs(node, flags).map((t) => (0, typeUtils_1.convertToInstance)(t.type));
|
4133
|
-
const type = types_1.TypeBase.cloneForTypeAlias(baseTypeResult.type, baseTypeResult.type.details.recursiveTypeAliasName, '', baseTypeResult.type.details.recursiveTypeAliasScopeId,
|
4172
|
+
const type = types_1.TypeBase.cloneForTypeAlias(baseTypeResult.type, baseTypeResult.type.details.recursiveTypeAliasName, '', baseTypeResult.type.details.recursiveTypeAliasScopeId, baseTypeResult.type.details.recursiveTypeParameters, typeArgTypes);
|
4134
4173
|
return { type, node };
|
4135
4174
|
}
|
4136
4175
|
let isIncomplete = false;
|
@@ -5673,6 +5712,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5673
5712
|
return (0, namedTuples_1.createNamedTupleType)(evaluatorInterface, errorNode, argList,
|
5674
5713
|
/* includesTypes */ false);
|
5675
5714
|
}
|
5715
|
+
// Handle the NewType specially, replacing the normal return type.
|
5716
|
+
if (expandedSubtype.details.builtInName === 'NewType') {
|
5717
|
+
return createNewType(errorNode, argList);
|
5718
|
+
}
|
5676
5719
|
let effectiveTypeVarContext = typeVarContext;
|
5677
5720
|
if (!effectiveTypeVarContext) {
|
5678
5721
|
// If a typeVarContext wasn't provided by the caller, allocate one here.
|
@@ -5709,10 +5752,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5709
5752
|
argumentErrors = true;
|
5710
5753
|
}
|
5711
5754
|
}
|
5712
|
-
// Handle the NewType specially, replacing the normal return type.
|
5713
|
-
if (!functionResult.argumentErrors && expandedSubtype.details.builtInName === 'NewType') {
|
5714
|
-
return createNewType(errorNode, argList);
|
5715
|
-
}
|
5716
5755
|
if (expandedSubtype.details.builtInName === '__import__') {
|
5717
5756
|
// For the special __import__ type, we'll override the return type to be "Any".
|
5718
5757
|
// This is required because we don't know what module was imported, and we don't
|
@@ -6881,7 +6920,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
6881
6920
|
// scope.
|
6882
6921
|
let eliminateUnsolvedInUnions = true;
|
6883
6922
|
let curNode = errorNode;
|
6884
|
-
while (
|
6923
|
+
while (curNode) {
|
6885
6924
|
const typeVarScopeNode = ParseTreeUtils.getTypeVarScopeNode(curNode);
|
6886
6925
|
if (!typeVarScopeNode) {
|
6887
6926
|
break;
|
@@ -6890,7 +6929,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
6890
6929
|
if (typeVarContext.hasSolveForScope(typeVarScopeId)) {
|
6891
6930
|
eliminateUnsolvedInUnions = false;
|
6892
6931
|
}
|
6893
|
-
curNode = typeVarScopeNode;
|
6932
|
+
curNode = typeVarScopeNode.parent;
|
6894
6933
|
}
|
6895
6934
|
// If the function is returning a callable, don't eliminate unsolved
|
6896
6935
|
// type vars within a union. There are legit uses for unsolved type vars
|
@@ -7357,21 +7396,21 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7357
7396
|
}
|
7358
7397
|
else if (paramName === 'covariant') {
|
7359
7398
|
if (argList[i].valueExpression && getBooleanValue(argList[i].valueExpression)) {
|
7360
|
-
if (typeVar.details.
|
7399
|
+
if (typeVar.details.declaredVariance === 3 /* Contravariant */) {
|
7361
7400
|
addError(localize_1.Localizer.Diagnostic.typeVarVariance(), argList[i].valueExpression);
|
7362
7401
|
}
|
7363
7402
|
else {
|
7364
|
-
typeVar.details.
|
7403
|
+
typeVar.details.declaredVariance = 2 /* Covariant */;
|
7365
7404
|
}
|
7366
7405
|
}
|
7367
7406
|
}
|
7368
7407
|
else if (paramName === 'contravariant') {
|
7369
7408
|
if (argList[i].valueExpression && getBooleanValue(argList[i].valueExpression)) {
|
7370
|
-
if (typeVar.details.
|
7409
|
+
if (typeVar.details.declaredVariance === 2 /* Covariant */) {
|
7371
7410
|
addError(localize_1.Localizer.Diagnostic.typeVarVariance(), argList[i].valueExpression);
|
7372
7411
|
}
|
7373
7412
|
else {
|
7374
|
-
typeVar.details.
|
7413
|
+
typeVar.details.declaredVariance = 3 /* Contravariant */;
|
7375
7414
|
}
|
7376
7415
|
}
|
7377
7416
|
}
|
@@ -9832,7 +9871,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9832
9871
|
}
|
9833
9872
|
return undefined;
|
9834
9873
|
}
|
9835
|
-
function transformTypeForTypeAlias(type, name, errorNode) {
|
9874
|
+
function transformTypeForTypeAlias(type, name, errorNode, typeParameters) {
|
9836
9875
|
if (!types_1.TypeBase.isInstantiable(type)) {
|
9837
9876
|
return type;
|
9838
9877
|
}
|
@@ -9841,17 +9880,19 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9841
9880
|
if ((0, typeUtils_1.isTypeAliasPlaceholder)(type)) {
|
9842
9881
|
return type;
|
9843
9882
|
}
|
9844
|
-
|
9845
|
-
|
9846
|
-
|
9847
|
-
|
9848
|
-
|
9849
|
-
(0,
|
9850
|
-
(0, typeUtils_1.
|
9851
|
-
|
9883
|
+
if (!typeParameters) {
|
9884
|
+
// Determine if there are any generic type parameters associated
|
9885
|
+
// with this type alias.
|
9886
|
+
typeParameters = [];
|
9887
|
+
// Skip this for a simple TypeVar (one that's not part of a union).
|
9888
|
+
if (!(0, types_1.isTypeVar)(type) || types_1.TypeBase.isAnnotated(type)) {
|
9889
|
+
(0, typeUtils_1.doForEachSubtype)(type, (subtype) => {
|
9890
|
+
(0, typeUtils_1.addTypeVarsToListIfUnique)(typeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(subtype));
|
9891
|
+
});
|
9892
|
+
}
|
9893
|
+
// Don't include any synthesized type variables.
|
9894
|
+
typeParameters = typeParameters.filter((typeVar) => !typeVar.details.isSynthesized);
|
9852
9895
|
}
|
9853
|
-
// Don't include any synthesized type variables.
|
9854
|
-
typeParameters = typeParameters.filter((typeVar) => !typeVar.details.isSynthesized);
|
9855
9896
|
// Convert all type variables to instances.
|
9856
9897
|
typeParameters = typeParameters.map((typeVar) => {
|
9857
9898
|
if (types_1.TypeBase.isInstance(typeVar)) {
|
@@ -10052,7 +10093,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10052
10093
|
}
|
10053
10094
|
if (!rightHandType) {
|
10054
10095
|
// Determine whether there is a declared type.
|
10055
|
-
const declaredType = getDeclaredTypeForExpression(node.leftExpression, {
|
10096
|
+
const declaredType = getDeclaredTypeForExpression(node.leftExpression, {
|
10097
|
+
method: 'set',
|
10098
|
+
});
|
10056
10099
|
let typeAliasNameNode;
|
10057
10100
|
let isSpeculativeTypeAlias = false;
|
10058
10101
|
if (isDeclaredTypeAlias(node.leftExpression)) {
|
@@ -10158,6 +10201,62 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10158
10201
|
/* allowAssignmentToFinalVar */ true, expectedTypeDiagAddendum);
|
10159
10202
|
writeTypeCache(node, rightHandType, 0 /* None */, isIncomplete);
|
10160
10203
|
}
|
10204
|
+
// Evaluates the type of a type alias (i.e. "type") statement. This code
|
10205
|
+
// path does not handle traditional type aliases, which are treated as
|
10206
|
+
// variables since they use normal variable assignment syntax.
|
10207
|
+
function getTypeOfTypeAlias(node) {
|
10208
|
+
const cachedType = readTypeCache(node.name, 0 /* None */);
|
10209
|
+
if (cachedType) {
|
10210
|
+
return cachedType;
|
10211
|
+
}
|
10212
|
+
// Synthesize a type variable that represents the type alias while we're
|
10213
|
+
// evaluating it. This allows us to handle recursive definitions.
|
10214
|
+
const typeAliasTypeVar = types_1.TypeVarType.createInstantiable(`__type_alias_${node.name.value}`);
|
10215
|
+
typeAliasTypeVar.details.isSynthesized = true;
|
10216
|
+
typeAliasTypeVar.details.recursiveTypeAliasName = node.name.value;
|
10217
|
+
const scopeId = getScopeIdForNode(node.name);
|
10218
|
+
typeAliasTypeVar.details.recursiveTypeAliasScopeId = scopeId;
|
10219
|
+
typeAliasTypeVar.scopeId = scopeId;
|
10220
|
+
// Write the type to the type cache. It will be replaced below.
|
10221
|
+
writeTypeCache(node.name, typeAliasTypeVar, /* flags */ undefined, /* isIncomplete */ false);
|
10222
|
+
// Set a partial type to handle recursive (self-referential) type aliases.
|
10223
|
+
const scope = ScopeUtils.getScopeForNode(node);
|
10224
|
+
const typeAliasSymbol = scope === null || scope === void 0 ? void 0 : scope.lookUpSymbolRecursive(node.name.value);
|
10225
|
+
const typeAliasDecl = AnalyzerNodeInfo.getDeclaration(node);
|
10226
|
+
if (typeAliasDecl && typeAliasSymbol) {
|
10227
|
+
setSymbolResolutionPartialType(typeAliasSymbol.symbol, typeAliasDecl, typeAliasTypeVar);
|
10228
|
+
}
|
10229
|
+
let typeParameters = [];
|
10230
|
+
if (node.typeParameters) {
|
10231
|
+
typeParameters = evaluateTypeParameterList(node.typeParameters);
|
10232
|
+
typeAliasTypeVar.details.recursiveTypeParameters = typeParameters;
|
10233
|
+
}
|
10234
|
+
const aliasTypeResult = getTypeOfExpressionExpectingType(node.expression);
|
10235
|
+
let isIncomplete = false;
|
10236
|
+
let aliasType = aliasTypeResult.type;
|
10237
|
+
if (aliasTypeResult.isIncomplete) {
|
10238
|
+
isIncomplete = true;
|
10239
|
+
}
|
10240
|
+
// Clear the temporary type we wrote above.
|
10241
|
+
deleteTypeCacheEntry(node.name);
|
10242
|
+
aliasType = transformTypeForTypeAlias(aliasType, node.name, node.expression, typeParameters);
|
10243
|
+
if ((0, typeUtils_1.isTypeAliasRecursive)(typeAliasTypeVar, aliasType)) {
|
10244
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeAliasIsRecursiveDirect().format({
|
10245
|
+
name: node.name.value,
|
10246
|
+
}), node.expression);
|
10247
|
+
aliasType = types_1.UnknownType.create();
|
10248
|
+
}
|
10249
|
+
// Set the resulting type to the boundType of the original type alias
|
10250
|
+
// to support recursive type aliases.
|
10251
|
+
typeAliasTypeVar.details.boundType = aliasType;
|
10252
|
+
if (typeAliasTypeVar.details.illegalRecursionDetected) {
|
10253
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeAliasIsRecursiveIndirect().format({
|
10254
|
+
name: node.name.value,
|
10255
|
+
}), node.name);
|
10256
|
+
}
|
10257
|
+
writeTypeCache(node.name, aliasType, 0 /* None */, isIncomplete);
|
10258
|
+
return aliasType;
|
10259
|
+
}
|
10161
10260
|
function evaluateTypesForAugmentedAssignment(node) {
|
10162
10261
|
if (readTypeCache(node, 0 /* None */)) {
|
10163
10262
|
return;
|
@@ -10223,7 +10322,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10223
10322
|
writeTypeCache(node.name, classType, /* flags */ undefined, /* isIncomplete */ false);
|
10224
10323
|
// Keep a list of unique type parameters that are used in the
|
10225
10324
|
// base class arguments.
|
10226
|
-
|
10325
|
+
let typeParameters = [];
|
10326
|
+
if (node.typeParameters) {
|
10327
|
+
typeParameters = evaluateTypeParameterList(node.typeParameters).map((t) => types_1.TypeVarType.cloneAsInstance(t));
|
10328
|
+
}
|
10227
10329
|
// If the class derives from "Generic" directly, it will provide
|
10228
10330
|
// all of the type parameters in the specified order.
|
10229
10331
|
let genericTypeParameters;
|
@@ -10344,12 +10446,18 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10344
10446
|
(0, typeUtils_1.addTypeVarsToListIfUnique)(typeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(argType));
|
10345
10447
|
if ((0, types_1.isInstantiableClass)(argType)) {
|
10346
10448
|
if (types_1.ClassType.isBuiltIn(argType, 'Generic')) {
|
10347
|
-
if
|
10348
|
-
|
10349
|
-
|
10449
|
+
// 'Generic' is implicitly added if type parameter syntax is used.
|
10450
|
+
if (node.typeParameters) {
|
10451
|
+
addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.genericBaseClassNotAllowed(), arg.valueExpression);
|
10452
|
+
}
|
10453
|
+
else {
|
10454
|
+
if (!genericTypeParameters) {
|
10455
|
+
if (protocolTypeParameters) {
|
10456
|
+
addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.duplicateGenericAndProtocolBase(), arg.valueExpression);
|
10457
|
+
}
|
10458
|
+
genericTypeParameters = [];
|
10459
|
+
(0, typeUtils_1.addTypeVarsToListIfUnique)(genericTypeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(argType));
|
10350
10460
|
}
|
10351
|
-
genericTypeParameters = [];
|
10352
|
-
(0, typeUtils_1.addTypeVarsToListIfUnique)(genericTypeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(argType));
|
10353
10461
|
}
|
10354
10462
|
}
|
10355
10463
|
else if (types_1.ClassType.isBuiltIn(argType, 'Protocol') &&
|
@@ -10361,6 +10469,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10361
10469
|
}
|
10362
10470
|
protocolTypeParameters = [];
|
10363
10471
|
(0, typeUtils_1.addTypeVarsToListIfUnique)(protocolTypeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(argType));
|
10472
|
+
if (node.typeParameters && protocolTypeParameters.length > 0) {
|
10473
|
+
addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.protocolBaseClassWithTypeArgs(), arg.valueExpression);
|
10474
|
+
protocolTypeParameters = [];
|
10475
|
+
}
|
10364
10476
|
}
|
10365
10477
|
}
|
10366
10478
|
}
|
@@ -10423,10 +10535,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10423
10535
|
// If genericTypeParameters or protocolTypeParameters are provided,
|
10424
10536
|
// make sure that typeParameters is a proper subset.
|
10425
10537
|
genericTypeParameters = genericTypeParameters !== null && genericTypeParameters !== void 0 ? genericTypeParameters : protocolTypeParameters;
|
10426
|
-
if (genericTypeParameters) {
|
10538
|
+
if (genericTypeParameters && !node.typeParameters) {
|
10427
10539
|
verifyGenericTypeParameters(node.name, typeParameters, genericTypeParameters);
|
10428
10540
|
}
|
10429
|
-
classType.details.typeParameters = genericTypeParameters
|
10541
|
+
classType.details.typeParameters = genericTypeParameters !== null && genericTypeParameters !== void 0 ? genericTypeParameters : typeParameters;
|
10542
|
+
// Determine if one or more type parameters is autovariance.
|
10543
|
+
if (classType.details.typeParameters.some((param) => param.details.declaredVariance === 0 /* Auto */ && param.computedVariance === undefined)) {
|
10544
|
+
classType.details.requiresVarianceInference = true;
|
10545
|
+
}
|
10430
10546
|
// Make sure there's at most one variadic type parameter.
|
10431
10547
|
const variadics = classType.details.typeParameters.filter((param) => (0, types_1.isVariadicTypeVar)(param));
|
10432
10548
|
if (variadics.length > 1) {
|
@@ -10456,7 +10572,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10456
10572
|
const initMethod = classType.details.fields.get('__init__');
|
10457
10573
|
if (initMethod) {
|
10458
10574
|
const initDecls = initMethod.getTypedDeclarations();
|
10459
|
-
if (initDecls.length === 1 && initDecls[0].type ===
|
10575
|
+
if (initDecls.length === 1 && initDecls[0].type === 5 /* Function */) {
|
10460
10576
|
const initDeclNode = initDecls[0].node;
|
10461
10577
|
const initParams = initDeclNode.parameters;
|
10462
10578
|
if (initParams.length > 1 &&
|
@@ -10619,6 +10735,79 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10619
10735
|
}
|
10620
10736
|
return { classType, decoratedType };
|
10621
10737
|
}
|
10738
|
+
function inferTypeParameterVarianceForClass(classType) {
|
10739
|
+
if (!classType.details.requiresVarianceInference) {
|
10740
|
+
return;
|
10741
|
+
}
|
10742
|
+
if (!objectType || !(0, types_1.isClassInstance)(objectType)) {
|
10743
|
+
return;
|
10744
|
+
}
|
10745
|
+
// Replace all of the type parameters with invariant TypeVars.
|
10746
|
+
const updatedTypeParams = classType.details.typeParameters.map((typeParam) => types_1.TypeVarType.cloneAsInvariant(typeParam));
|
10747
|
+
const updatedClassType = types_1.ClassType.cloneWithNewTypeParameters(classType, updatedTypeParams);
|
10748
|
+
const dummyTypeObject = types_1.ClassType.createInstantiable('__varianceDummy', '', '', '', 0, 0, undefined, undefined);
|
10749
|
+
updatedTypeParams.forEach((param, paramIndex) => {
|
10750
|
+
// Skip variadics and ParamSpecs.
|
10751
|
+
if (param.details.isVariadic || param.details.isParamSpec) {
|
10752
|
+
return;
|
10753
|
+
}
|
10754
|
+
// Skip type variables without auto-variance.
|
10755
|
+
if (param.details.declaredVariance !== 0 /* Auto */) {
|
10756
|
+
return;
|
10757
|
+
}
|
10758
|
+
// Replace all type arguments with a dummy type except for the
|
10759
|
+
// TypeVar of interest, which is replaced with an object instance.
|
10760
|
+
const srcTypeArgs = updatedTypeParams.map((p, i) => {
|
10761
|
+
if (p.details.isVariadic) {
|
10762
|
+
return p;
|
10763
|
+
}
|
10764
|
+
return i === paramIndex ? objectType : dummyTypeObject;
|
10765
|
+
});
|
10766
|
+
// Replace all type arguments with a dummy type except for the
|
10767
|
+
// TypeVar of interest, which is replaced with itself.
|
10768
|
+
const destTypeArgs = updatedTypeParams.map((p, i) => {
|
10769
|
+
return i === paramIndex || p.details.isVariadic ? p : dummyTypeObject;
|
10770
|
+
});
|
10771
|
+
const srcType = types_1.ClassType.cloneForSpecialization(updatedClassType, srcTypeArgs,
|
10772
|
+
/* isTypeArgumentExplicit */ true);
|
10773
|
+
const destType = types_1.ClassType.cloneForSpecialization(updatedClassType, destTypeArgs,
|
10774
|
+
/* isTypeArgumentExplicit */ true);
|
10775
|
+
const isDestSubtypeOfSrc = assignClassToSelf(srcType, destType);
|
10776
|
+
let inferredVariance;
|
10777
|
+
if (isDestSubtypeOfSrc) {
|
10778
|
+
inferredVariance = 2 /* Covariant */;
|
10779
|
+
}
|
10780
|
+
else {
|
10781
|
+
const isSrcSubtypeOfDest = assignClassToSelf(destType, srcType);
|
10782
|
+
if (isSrcSubtypeOfDest) {
|
10783
|
+
inferredVariance = 3 /* Contravariant */;
|
10784
|
+
}
|
10785
|
+
else {
|
10786
|
+
inferredVariance = 1 /* Invariant */;
|
10787
|
+
}
|
10788
|
+
}
|
10789
|
+
// We assume here that we don't need to clone the type var object
|
10790
|
+
// because it was already cloned when it was associated with this
|
10791
|
+
// class scope.
|
10792
|
+
classType.details.typeParameters[paramIndex].computedVariance = inferredVariance;
|
10793
|
+
});
|
10794
|
+
// Note that variance inference is complete.
|
10795
|
+
classType.details.requiresVarianceInference = false;
|
10796
|
+
}
|
10797
|
+
function evaluateTypeParameterList(node) {
|
10798
|
+
const paramTypes = [];
|
10799
|
+
node.parameters.forEach((param) => {
|
10800
|
+
const paramSymbol = AnalyzerNodeInfo.getTypeParameterSymbol(param.name);
|
10801
|
+
(0, debug_1.assert)(paramSymbol);
|
10802
|
+
const typeOfParam = getDeclaredTypeOfSymbol(paramSymbol, param.name);
|
10803
|
+
if (!typeOfParam || !(0, types_1.isTypeVar)(typeOfParam)) {
|
10804
|
+
return;
|
10805
|
+
}
|
10806
|
+
writeTypeCache(param.name, typeOfParam, 0 /* None */, /* isIncomplete */ false);
|
10807
|
+
paramTypes.push(typeOfParam);
|
10808
|
+
});
|
10809
|
+
return paramTypes;
|
10810
|
+
}
|
10622
10811
|
function computeEffectiveMetaclass(classType, errorNode) {
|
10623
10812
|
let effectiveMetaclass = classType.details.declaredMetaclass;
|
10624
10813
|
let reportedMetaclassConflict = false;
|
@@ -10944,6 +11133,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10944
11133
|
}), node.functionAnnotationComment);
|
10945
11134
|
}
|
10946
11135
|
}
|
11136
|
+
if (node.typeParameters) {
|
11137
|
+
evaluateTypeParameterList(node.typeParameters);
|
11138
|
+
}
|
10947
11139
|
const markParamAccessed = (param) => {
|
10948
11140
|
if (param.name) {
|
10949
11141
|
const symbolWithScope = lookUpSymbolRecursive(param.name, param.name.value, /* honorCodeFlow */ false);
|
@@ -11252,7 +11444,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11252
11444
|
const baseClassMemberInfo = (0, typeUtils_1.lookUpClassMember)(containingClassType, methodName, 1 /* SkipOriginalClass */);
|
11253
11445
|
if (baseClassMemberInfo) {
|
11254
11446
|
const memberDecls = baseClassMemberInfo.symbol.getDeclarations();
|
11255
|
-
if (memberDecls.length === 1 && memberDecls[0].type ===
|
11447
|
+
if (memberDecls.length === 1 && memberDecls[0].type === 5 /* Function */) {
|
11256
11448
|
const baseClassMethodNode = memberDecls[0].node;
|
11257
11449
|
// Does the signature match exactly with the exception of annotations?
|
11258
11450
|
if (baseClassMethodNode.parameters.length === functionNode.parameters.length &&
|
@@ -11529,14 +11721,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11529
11721
|
// to recursion if there is a large number (1000's) of overloads.
|
11530
11722
|
for (let i = 0; i < declIndex; i++) {
|
11531
11723
|
const decl = decls[i];
|
11532
|
-
if (decl.type ===
|
11724
|
+
if (decl.type === 5 /* Function */) {
|
11533
11725
|
getTypeOfFunction(decl.node);
|
11534
11726
|
}
|
11535
11727
|
}
|
11536
11728
|
const overloadedTypes = [];
|
11537
11729
|
// Look at the previous declaration's type.
|
11538
11730
|
const prevDecl = decls[declIndex - 1];
|
11539
|
-
if (prevDecl.type ===
|
11731
|
+
if (prevDecl.type === 5 /* Function */) {
|
11540
11732
|
const prevDeclDeclTypeInfo = getTypeOfFunction(prevDecl.node);
|
11541
11733
|
if (prevDeclDeclTypeInfo) {
|
11542
11734
|
if ((0, types_1.isFunction)(prevDeclDeclTypeInfo.decoratedType)) {
|
@@ -12086,19 +12278,19 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
12086
12278
|
// case, we want to choose the last declaration.
|
12087
12279
|
const filteredDecls = symbolWithScope.symbol
|
12088
12280
|
.getDeclarations()
|
12089
|
-
.filter((decl) => ParseTreeUtils.isNodeContainedWithin(node, decl.node) && decl.type ===
|
12281
|
+
.filter((decl) => ParseTreeUtils.isNodeContainedWithin(node, decl.node) && decl.type === 8 /* Alias */);
|
12090
12282
|
let aliasDecl = filteredDecls.length > 0 ? filteredDecls[filteredDecls.length - 1] : undefined;
|
12091
12283
|
// If we didn't find an exact match, look for any alias associated with
|
12092
12284
|
// this symbol. In cases where we have multiple ImportAs nodes that share
|
12093
12285
|
// the same first-part name (e.g. "import asyncio" and "import asyncio.tasks"),
|
12094
12286
|
// we may not find the declaration associated with this node.
|
12095
12287
|
if (!aliasDecl) {
|
12096
|
-
aliasDecl = symbolWithScope.symbol.getDeclarations().find((decl) => decl.type ===
|
12288
|
+
aliasDecl = symbolWithScope.symbol.getDeclarations().find((decl) => decl.type === 8 /* Alias */);
|
12097
12289
|
}
|
12098
12290
|
if (!aliasDecl) {
|
12099
12291
|
return undefined;
|
12100
12292
|
}
|
12101
|
-
(0, debug_1.assert)(aliasDecl.type ===
|
12293
|
+
(0, debug_1.assert)(aliasDecl.type === 8 /* Alias */);
|
12102
12294
|
const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
|
12103
12295
|
// Try to resolve the alias while honoring external visibility.
|
12104
12296
|
const resolvedAliasInfo = resolveAliasDeclarationWithInfo(aliasDecl,
|
@@ -12135,7 +12327,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
12135
12327
|
// expression or statement that contains it. This contextual evaluation
|
12136
12328
|
// allows for bidirectional type evaluation.
|
12137
12329
|
function evaluateTypesForExpressionInContext(node) {
|
12138
|
-
var _a, _b, _c;
|
12330
|
+
var _a, _b, _c, _d, _e;
|
12139
12331
|
let lastContextualExpression = node;
|
12140
12332
|
let curNode = node;
|
12141
12333
|
function isContextual(node) {
|
@@ -12204,6 +12396,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
12204
12396
|
getTypeOfClass(node.parent);
|
12205
12397
|
return;
|
12206
12398
|
}
|
12399
|
+
else if (node.parent.nodeType === 77 /* TypeAlias */ && node.parent.name === node) {
|
12400
|
+
getTypeOfTypeAlias(node.parent);
|
12401
|
+
return;
|
12402
|
+
}
|
12207
12403
|
else if (node.parent.nodeType === 29 /* Global */ ||
|
12208
12404
|
node.parent.nodeType === 39 /* Nonlocal */) {
|
12209
12405
|
// For global and nonlocal statements, allow forward references so
|
@@ -12242,15 +12438,32 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
12242
12438
|
verifyDeleteExpression(lastContextualExpression);
|
12243
12439
|
return;
|
12244
12440
|
}
|
12441
|
+
// If this is the name node within a type parameter list, see if it's a type alias
|
12442
|
+
// definition. If so, we need to evaluate the type alias contextually.
|
12443
|
+
if (parent.nodeType === 75 /* TypeParameter */ && lastContextualExpression === parent.name) {
|
12444
|
+
if (((_a = parent.parent) === null || _a === void 0 ? void 0 : _a.nodeType) === 76 /* TypeParameterList */ &&
|
12445
|
+
((_b = parent.parent.parent) === null || _b === void 0 ? void 0 : _b.nodeType) === 77 /* TypeAlias */) {
|
12446
|
+
getTypeOfTypeAlias(parent.parent.parent);
|
12447
|
+
return;
|
12448
|
+
}
|
12449
|
+
}
|
12450
|
+
if (parent.nodeType === 75 /* TypeParameter */) {
|
12451
|
+
getTypeOfExpression(parent.name);
|
12452
|
+
return;
|
12453
|
+
}
|
12454
|
+
if (parent.nodeType === 77 /* TypeAlias */) {
|
12455
|
+
getTypeOfTypeAlias(parent);
|
12456
|
+
return;
|
12457
|
+
}
|
12245
12458
|
if (parent.nodeType === 5 /* AugmentedAssignment */) {
|
12246
12459
|
evaluateTypesForAugmentedAssignment(parent);
|
12247
12460
|
return;
|
12248
12461
|
}
|
12249
12462
|
if (parent.nodeType === 13 /* Decorator */) {
|
12250
|
-
if (((
|
12463
|
+
if (((_c = parent.parent) === null || _c === void 0 ? void 0 : _c.nodeType) === 10 /* Class */) {
|
12251
12464
|
getTypeOfClass(parent.parent);
|
12252
12465
|
}
|
12253
|
-
else if (((
|
12466
|
+
else if (((_d = parent.parent) === null || _d === void 0 ? void 0 : _d.nodeType) === 28 /* Function */) {
|
12254
12467
|
getTypeOfFunction(parent.parent);
|
12255
12468
|
}
|
12256
12469
|
return;
|
@@ -12301,7 +12514,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
12301
12514
|
return;
|
12302
12515
|
}
|
12303
12516
|
// A class argument must be evaluated in the context of the class declaration.
|
12304
|
-
if (parent.nodeType === 1 /* Argument */ && ((
|
12517
|
+
if (parent.nodeType === 1 /* Argument */ && ((_e = parent.parent) === null || _e === void 0 ? void 0 : _e.nodeType) === 10 /* Class */) {
|
12305
12518
|
getTypeOfClass(parent.parent);
|
12306
12519
|
return;
|
12307
12520
|
}
|
@@ -12397,6 +12610,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
12397
12610
|
}
|
12398
12611
|
break;
|
12399
12612
|
}
|
12613
|
+
case 77 /* TypeAlias */: {
|
12614
|
+
getTypeOfTypeAlias(curNode);
|
12615
|
+
return;
|
12616
|
+
}
|
12400
12617
|
case 4 /* AssignmentExpression */: {
|
12401
12618
|
getTypeOfExpression(curNode);
|
12402
12619
|
return;
|
@@ -12923,10 +13140,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
12923
13140
|
if (symbolWithScope && honorCodeFlow && scopeTypeHonorsCodeFlow) {
|
12924
13141
|
// Filter the declarations based on flow reachability.
|
12925
13142
|
const reachableDecls = symbolWithScope.symbol.getDeclarations().filter((decl) => {
|
12926
|
-
if (decl.type !==
|
13143
|
+
if (decl.type !== 8 /* Alias */ && decl.type !== 0 /* Intrinsic */) {
|
12927
13144
|
// Is the declaration in the same execution scope as the "usageNode" node?
|
12928
13145
|
const usageScope = ParseTreeUtils.getExecutionScopeNode(node);
|
12929
|
-
const declNode = decl.type ===
|
13146
|
+
const declNode = decl.type === 6 /* Class */ ||
|
13147
|
+
decl.type === 5 /* Function */ ||
|
13148
|
+
decl.type === 4 /* TypeAlias */
|
12930
13149
|
? decl.node.name
|
12931
13150
|
: decl.node;
|
12932
13151
|
const declScope = ParseTreeUtils.getExecutionScopeNode(declNode);
|
@@ -13044,7 +13263,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13044
13263
|
if ((0, types_1.isFunction)(type)) {
|
13045
13264
|
if (type.details.declaration) {
|
13046
13265
|
const functionDecl = type.details.declaration;
|
13047
|
-
if (functionDecl.type ===
|
13266
|
+
if (functionDecl.type === 5 /* Function */) {
|
13048
13267
|
const functionNode = functionDecl.node;
|
13049
13268
|
const functionScope = AnalyzerNodeInfo.getScope(functionNode);
|
13050
13269
|
if (functionScope) {
|
@@ -13108,7 +13327,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13108
13327
|
// The alias could have more decls that don't refer to this import. Filter
|
13109
13328
|
// out the one(s) that specifically associated with this import statement.
|
13110
13329
|
const declsForThisImport = symbolInScope.symbol.getDeclarations().filter((decl) => {
|
13111
|
-
return decl.type ===
|
13330
|
+
return decl.type === 8 /* Alias */ && decl.node === node.parent;
|
13112
13331
|
});
|
13113
13332
|
(0, collectionUtils_1.appendArray)(declarations, (0, declarationUtils_1.getDeclarationsWithUsesLocalNameRemoved)(declsForThisImport));
|
13114
13333
|
}
|
@@ -13232,9 +13451,17 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13232
13451
|
// Determine if this node is within a quoted type annotation.
|
13233
13452
|
const isWithinTypeAnnotation = ParseTreeUtils.isWithinTypeAnnotation(node, !(0, analyzerFileInfo_1.isAnnotationEvaluationPostponed)(AnalyzerNodeInfo.getFileInfo(node)));
|
13234
13453
|
const allowForwardReferences = isWithinTypeAnnotation || fileInfo.isStubFile;
|
13235
|
-
|
13236
|
-
|
13237
|
-
|
13454
|
+
let symbol;
|
13455
|
+
const typeParamSymbol = AnalyzerNodeInfo.getTypeParameterSymbol(node);
|
13456
|
+
if (typeParamSymbol) {
|
13457
|
+
symbol = typeParamSymbol;
|
13458
|
+
}
|
13459
|
+
else {
|
13460
|
+
const symbolWithScope = lookUpSymbolRecursive(node, node.value, !allowForwardReferences, isWithinTypeAnnotation);
|
13461
|
+
symbol = symbolWithScope === null || symbolWithScope === void 0 ? void 0 : symbolWithScope.symbol;
|
13462
|
+
}
|
13463
|
+
if (symbol) {
|
13464
|
+
(0, collectionUtils_1.appendArray)(declarations, symbol.getDeclarations());
|
13238
13465
|
}
|
13239
13466
|
}
|
13240
13467
|
return declarations;
|
@@ -13280,17 +13507,20 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13280
13507
|
}
|
13281
13508
|
return types_1.UnknownType.create();
|
13282
13509
|
}
|
13283
|
-
case
|
13510
|
+
case 6 /* Class */: {
|
13284
13511
|
const classTypeInfo = getTypeOfClass(declaration.node);
|
13285
13512
|
return classTypeInfo === null || classTypeInfo === void 0 ? void 0 : classTypeInfo.decoratedType;
|
13286
13513
|
}
|
13287
|
-
case
|
13514
|
+
case 7 /* SpecialBuiltInClass */: {
|
13288
13515
|
return getTypeOfAnnotation(declaration.node.typeAnnotation);
|
13289
13516
|
}
|
13290
|
-
case
|
13517
|
+
case 5 /* Function */: {
|
13291
13518
|
const functionTypeInfo = getTypeOfFunction(declaration.node);
|
13292
13519
|
return functionTypeInfo === null || functionTypeInfo === void 0 ? void 0 : functionTypeInfo.decoratedType;
|
13293
13520
|
}
|
13521
|
+
case 4 /* TypeAlias */: {
|
13522
|
+
return getTypeOfTypeAlias(declaration.node);
|
13523
|
+
}
|
13294
13524
|
case 2 /* Parameter */: {
|
13295
13525
|
let typeAnnotationNode = declaration.node.typeAnnotation || declaration.node.typeAnnotationComment;
|
13296
13526
|
// If there wasn't an annotation, see if the parent function
|
@@ -13312,6 +13542,62 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13312
13542
|
}
|
13313
13543
|
return undefined;
|
13314
13544
|
}
|
13545
|
+
case 3 /* TypeParameter */: {
|
13546
|
+
let typeVar = types_1.TypeVarType.createInstantiable(declaration.node.name.value);
|
13547
|
+
if (declaration.node.typeParamCategory === parseNodes_1.TypeParameterCategory.TypeVarTuple) {
|
13548
|
+
typeVar.details.isVariadic = true;
|
13549
|
+
}
|
13550
|
+
else if (declaration.node.typeParamCategory === parseNodes_1.TypeParameterCategory.ParamSpec) {
|
13551
|
+
typeVar.details.isParamSpec = true;
|
13552
|
+
}
|
13553
|
+
if (declaration.node.boundExpression) {
|
13554
|
+
if (declaration.node.boundExpression.nodeType === 52 /* Tuple */) {
|
13555
|
+
const constraints = declaration.node.boundExpression.expressions.map((constraint) => {
|
13556
|
+
const constraintType = getTypeOfExpressionExpectingType(constraint).type;
|
13557
|
+
if ((0, typeUtils_1.requiresSpecialization)(constraintType, /* ignorePseudoGeneric */ true)) {
|
13558
|
+
addError(localize_1.Localizer.Diagnostic.typeVarGeneric(), constraint);
|
13559
|
+
}
|
13560
|
+
return (0, typeUtils_1.convertToInstance)(constraintType);
|
13561
|
+
});
|
13562
|
+
if (constraints.length < 2) {
|
13563
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(declaration.node.boundExpression).diagnosticRuleSet
|
13564
|
+
.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeVarSingleConstraint(), declaration.node.boundExpression);
|
13565
|
+
}
|
13566
|
+
else if (declaration.node.typeParamCategory === parseNodes_1.TypeParameterCategory.TypeVar) {
|
13567
|
+
typeVar.details.constraints = constraints;
|
13568
|
+
}
|
13569
|
+
}
|
13570
|
+
else {
|
13571
|
+
const boundType = getTypeOfExpressionExpectingType(declaration.node.boundExpression).type;
|
13572
|
+
if ((0, typeUtils_1.requiresSpecialization)(boundType, /* ignorePseudoGeneric */ true)) {
|
13573
|
+
addError(localize_1.Localizer.Diagnostic.typeVarGeneric(), declaration.node.boundExpression);
|
13574
|
+
}
|
13575
|
+
if (declaration.node.typeParamCategory === parseNodes_1.TypeParameterCategory.TypeVar) {
|
13576
|
+
typeVar.details.boundType = (0, typeUtils_1.convertToInstance)(boundType);
|
13577
|
+
}
|
13578
|
+
}
|
13579
|
+
}
|
13580
|
+
typeVar.details.isTypeParamSyntax = true;
|
13581
|
+
// Associate the type variable with the owning scope.
|
13582
|
+
const scopeNode = ParseTreeUtils.getTypeVarScopeNode(declaration.node);
|
13583
|
+
if (scopeNode) {
|
13584
|
+
let scopeType;
|
13585
|
+
if (scopeNode.nodeType === 10 /* Class */) {
|
13586
|
+
scopeType = 0 /* Class */;
|
13587
|
+
// Set the variance to "auto" for class-scoped TypeVars.
|
13588
|
+
typeVar.details.declaredVariance = 0 /* Auto */;
|
13589
|
+
}
|
13590
|
+
else if (scopeNode.nodeType === 28 /* Function */) {
|
13591
|
+
scopeType = 1 /* Function */;
|
13592
|
+
}
|
13593
|
+
else {
|
13594
|
+
(0, debug_1.assert)(scopeNode.nodeType === 77 /* TypeAlias */);
|
13595
|
+
scopeType = 2 /* TypeAlias */;
|
13596
|
+
}
|
13597
|
+
typeVar = types_1.TypeVarType.cloneForScopeId(typeVar, getScopeIdForNode(scopeNode.nodeType === 77 /* TypeAlias */ ? scopeNode.name : scopeNode), scopeNode.name.value, scopeType);
|
13598
|
+
}
|
13599
|
+
return typeVar;
|
13600
|
+
}
|
13315
13601
|
case 1 /* Variable */: {
|
13316
13602
|
const typeAnnotationNode = declaration.typeAnnotationNode;
|
13317
13603
|
if (typeAnnotationNode) {
|
@@ -13349,7 +13635,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13349
13635
|
}
|
13350
13636
|
return undefined;
|
13351
13637
|
}
|
13352
|
-
case
|
13638
|
+
case 8 /* Alias */: {
|
13353
13639
|
return undefined;
|
13354
13640
|
}
|
13355
13641
|
}
|
@@ -13396,11 +13682,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13396
13682
|
// If the resolved declaration is still an alias, the alias
|
13397
13683
|
// is pointing at a module, and we need to synthesize a
|
13398
13684
|
// module type.
|
13399
|
-
if (resolvedDecl.type ===
|
13685
|
+
if (resolvedDecl.type === 8 /* Alias */) {
|
13400
13686
|
// Build a module type that corresponds to the declaration and
|
13401
13687
|
// its associated loader actions.
|
13402
13688
|
let moduleName = resolvedDecl.moduleName;
|
13403
|
-
if (decl.type ===
|
13689
|
+
if (decl.type === 8 /* Alias */) {
|
13404
13690
|
if (decl.symbolName) {
|
13405
13691
|
moduleName += '.' + decl.symbolName;
|
13406
13692
|
}
|
@@ -13651,7 +13937,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13651
13937
|
considerDecl = false;
|
13652
13938
|
}
|
13653
13939
|
if (usageNode !== undefined) {
|
13654
|
-
if (decl.type !==
|
13940
|
+
if (decl.type !== 8 /* Alias */) {
|
13655
13941
|
// Is the declaration in the same execution scope as the "usageNode" node?
|
13656
13942
|
const usageScope = ParseTreeUtils.getExecutionScopeNode(usageNode);
|
13657
13943
|
const declScope = ParseTreeUtils.getExecutionScopeNode(decl.node);
|
@@ -13764,9 +14050,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13764
14050
|
// reachable from the usage node (if specified). This can happen in
|
13765
14051
|
// cases where a property symbol is redefined to add a setter, deleter,
|
13766
14052
|
// etc.
|
13767
|
-
if (typedDecls.length > 1
|
14053
|
+
if (usageNode && typedDecls.length > 1) {
|
13768
14054
|
const filteredTypedDecls = typedDecls.filter((decl) => {
|
13769
|
-
if (decl.type !==
|
14055
|
+
if (decl.type !== 8 /* Alias */) {
|
13770
14056
|
// Is the declaration in the same execution scope as the "usageNode" node?
|
13771
14057
|
const usageScope = ParseTreeUtils.getExecutionScopeNode(usageNode);
|
13772
14058
|
const declScope = ParseTreeUtils.getExecutionScopeNode(decl.node);
|
@@ -13778,9 +14064,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13778
14064
|
}
|
13779
14065
|
return true;
|
13780
14066
|
});
|
13781
|
-
if (filteredTypedDecls.length
|
13782
|
-
|
14067
|
+
if (filteredTypedDecls.length === 0) {
|
14068
|
+
return types_1.UnboundType.create();
|
13783
14069
|
}
|
14070
|
+
typedDecls = filteredTypedDecls;
|
13784
14071
|
}
|
13785
14072
|
// Start with the last decl. If that's already being resolved,
|
13786
14073
|
// use the next-to-last decl, etc. This can happen when resolving
|
@@ -13806,7 +14093,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13806
14093
|
// in the type cache. This exception is required to handle the
|
13807
14094
|
// circular dependency between the "type" and "object" classes in
|
13808
14095
|
// builtins.pyi (since "object" is a "type" and "type" is an "object").
|
13809
|
-
if (popSymbolResolution(symbol) || decl.type ===
|
14096
|
+
if (popSymbolResolution(symbol) || decl.type === 6 /* Class */) {
|
13810
14097
|
return type;
|
13811
14098
|
}
|
13812
14099
|
}
|
@@ -14157,6 +14444,63 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
14157
14444
|
}));
|
14158
14445
|
return false;
|
14159
14446
|
}
|
14447
|
+
// This function is used to validate or infer the variance of type
|
14448
|
+
// parameters within a class.
|
14449
|
+
function assignClassToSelf(destType, srcType, recursionCount = 0) {
|
14450
|
+
(0, debug_1.assert)(types_1.ClassType.isSameGenericClass(destType, srcType));
|
14451
|
+
(0, debug_1.assert)(destType.details.typeParameters.length > 0);
|
14452
|
+
const diag = new diagnostic_1.DiagnosticAddendum();
|
14453
|
+
const typeVarContext = new typeVarContext_1.TypeVarContext();
|
14454
|
+
let isAssignable = true;
|
14455
|
+
destType.details.fields.forEach((symbol, name) => {
|
14456
|
+
if (isAssignable && symbol.isClassMember() && !symbol.isIgnoredForProtocolMatch()) {
|
14457
|
+
const memberInfo = (0, typeUtils_1.lookUpClassMember)(srcType, name);
|
14458
|
+
(0, debug_1.assert)(memberInfo !== undefined);
|
14459
|
+
let destMemberType = getDeclaredTypeOfSymbol(symbol);
|
14460
|
+
if (destMemberType) {
|
14461
|
+
const srcMemberType = getTypeOfMember(memberInfo);
|
14462
|
+
destMemberType = (0, typeUtils_1.partiallySpecializeType)(destMemberType, destType);
|
14463
|
+
// Properties require special processing.
|
14464
|
+
if ((0, types_1.isClassInstance)(destMemberType) &&
|
14465
|
+
types_1.ClassType.isPropertyClass(destMemberType) &&
|
14466
|
+
(0, types_1.isClassInstance)(srcMemberType) &&
|
14467
|
+
types_1.ClassType.isPropertyClass(srcMemberType)) {
|
14468
|
+
if (!(0, properties_1.assignProperty)(evaluatorInterface, types_1.ClassType.cloneAsInstantiable(destMemberType), types_1.ClassType.cloneAsInstantiable(srcMemberType), destType, srcType, diag, typeVarContext,
|
14469
|
+
/* selfTypeVarContext */ undefined, recursionCount)) {
|
14470
|
+
isAssignable = false;
|
14471
|
+
}
|
14472
|
+
}
|
14473
|
+
else {
|
14474
|
+
const primaryDecl = symbol.getDeclarations()[0];
|
14475
|
+
// Class and instance variables that are mutable need to
|
14476
|
+
// enforce invariance.
|
14477
|
+
const flags = (primaryDecl === null || primaryDecl === void 0 ? void 0 : primaryDecl.type) === 1 /* Variable */ && !primaryDecl.isFinal
|
14478
|
+
? 1 /* EnforceInvariance */
|
14479
|
+
: 0 /* Default */;
|
14480
|
+
if (!assignType(destMemberType, srcMemberType, diag, typeVarContext,
|
14481
|
+
/* srcTypeVarContext */ undefined, flags, recursionCount)) {
|
14482
|
+
isAssignable = false;
|
14483
|
+
}
|
14484
|
+
}
|
14485
|
+
}
|
14486
|
+
}
|
14487
|
+
});
|
14488
|
+
// Now handle generic base classes.
|
14489
|
+
destType.details.baseClasses.forEach((baseClass) => {
|
14490
|
+
if ((0, types_1.isInstantiableClass)(baseClass) &&
|
14491
|
+
!types_1.ClassType.isBuiltIn(baseClass, 'object') &&
|
14492
|
+
!types_1.ClassType.isBuiltIn(baseClass, 'Protocol') &&
|
14493
|
+
!types_1.ClassType.isBuiltIn(baseClass, 'Generic') &&
|
14494
|
+
baseClass.details.typeParameters.length > 0) {
|
14495
|
+
const specializedDestBaseClass = (0, typeUtils_1.specializeForBaseClass)(destType, baseClass);
|
14496
|
+
const specializedSrcBaseClass = (0, typeUtils_1.specializeForBaseClass)(srcType, baseClass);
|
14497
|
+
if (!assignClassToSelf(specializedDestBaseClass, specializedSrcBaseClass, recursionCount)) {
|
14498
|
+
isAssignable = false;
|
14499
|
+
}
|
14500
|
+
}
|
14501
|
+
});
|
14502
|
+
return isAssignable;
|
14503
|
+
}
|
14160
14504
|
function assignTupleTypeArgs(destType, srcType, diag, typeVarContext, flags, recursionCount) {
|
14161
14505
|
var _a, _b;
|
14162
14506
|
const destTypeArgs = [...((_a = destType.tupleTypeArguments) !== null && _a !== void 0 ? _a : [])];
|
@@ -14250,6 +14594,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
14250
14594
|
let curSrcType = srcType;
|
14251
14595
|
let curTypeVarContext = destTypeVarContext !== null && destTypeVarContext !== void 0 ? destTypeVarContext : new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(destType));
|
14252
14596
|
let effectiveFlags = flags;
|
14597
|
+
inferTypeParameterVarianceForClass(destType);
|
14253
14598
|
// If we're using a private typeVarContext, don't skip solving type vars.
|
14254
14599
|
if (!destTypeVarContext) {
|
14255
14600
|
effectiveFlags &= ~8 /* SkipSolveTypeVars */;
|
@@ -14330,6 +14675,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
14330
14675
|
function verifyTypeArgumentsAssignable(destType, srcType, diag, destTypeVarContext, srcTypeVarContext, flags, recursionCount) {
|
14331
14676
|
var _a, _b, _c;
|
14332
14677
|
(0, debug_1.assert)(types_1.ClassType.isSameGenericClass(destType, srcType));
|
14678
|
+
inferTypeParameterVarianceForClass(destType);
|
14333
14679
|
const destTypeParams = types_1.ClassType.getTypeParameters(destType);
|
14334
14680
|
let destTypeArgs;
|
14335
14681
|
let srcTypeArgs;
|
@@ -14356,7 +14702,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
14356
14702
|
const destTypeArg = destArgIndex >= 0 ? destTypeArgs[destArgIndex] : types_1.UnknownType.create();
|
14357
14703
|
const destTypeParam = destArgIndex < destTypeParams.length ? destTypeParams[destArgIndex] : undefined;
|
14358
14704
|
const assignmentDiag = new diagnostic_1.DiagnosticAddendum();
|
14359
|
-
if (!destTypeParam ||
|
14705
|
+
if (!destTypeParam || types_1.TypeVarType.getVariance(destTypeParam) === 2 /* Covariant */) {
|
14360
14706
|
if (!assignType(destTypeArg, srcTypeArg, assignmentDiag, destTypeVarContext, srcTypeVarContext, flags | 128 /* RetainLiteralsForTypeVar */, recursionCount)) {
|
14361
14707
|
if (diag) {
|
14362
14708
|
if (destTypeParam) {
|
@@ -14373,7 +14719,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
14373
14719
|
return false;
|
14374
14720
|
}
|
14375
14721
|
}
|
14376
|
-
else if (
|
14722
|
+
else if (types_1.TypeVarType.getVariance(destTypeParam) === 3 /* Contravariant */) {
|
14377
14723
|
if (!assignType(srcTypeArg, destTypeArg, assignmentDiag, srcTypeVarContext, destTypeVarContext, (flags ^ 2 /* ReverseTypeVarMatching */) | 128 /* RetainLiteralsForTypeVar */, recursionCount)) {
|
14378
14724
|
if (diag) {
|
14379
14725
|
const childDiag = diag.createAddendum();
|
@@ -16347,7 +16693,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
16347
16693
|
if (symbol.isClassMember() || symbol.isNamedTupleMemberMember()) {
|
16348
16694
|
let isAbstract;
|
16349
16695
|
const decl = (0, symbolUtils_1.getLastTypedDeclaredForSymbol)(symbol);
|
16350
|
-
if (decl && decl.type ===
|
16696
|
+
if (decl && decl.type === 5 /* Function */) {
|
16351
16697
|
const functionFlags = getFunctionFlagsFromDecorators(decl.node, true);
|
16352
16698
|
isAbstract = !!(functionFlags & 8 /* AbstractMethod */);
|
16353
16699
|
}
|
@@ -16623,6 +16969,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
16623
16969
|
assignType,
|
16624
16970
|
validateOverrideMethod,
|
16625
16971
|
assignTypeToExpression,
|
16972
|
+
assignClassToSelf,
|
16626
16973
|
getTypedDictClassType,
|
16627
16974
|
getTupleClassType,
|
16628
16975
|
getObjectType,
|
@@ -16630,6 +16977,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
16630
16977
|
getTypingType,
|
16631
16978
|
verifyTypeArgumentsAssignable,
|
16632
16979
|
inferReturnTypeIfNecessary,
|
16980
|
+
inferTypeParameterVarianceForClass,
|
16633
16981
|
addError,
|
16634
16982
|
addWarning,
|
16635
16983
|
addInformation,
|