@zzzen/pyright-internal 1.2.0-dev.20221218 → 1.2.0-dev.20230101
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/analyzer/binder.js +8 -3
- package/dist/analyzer/binder.js.map +1 -1
- package/dist/analyzer/codeFlowEngine.d.ts +16 -1
- package/dist/analyzer/codeFlowEngine.js +41 -20
- package/dist/analyzer/codeFlowEngine.js.map +1 -1
- package/dist/analyzer/constraintSolver.js +133 -53
- package/dist/analyzer/constraintSolver.js.map +1 -1
- package/dist/analyzer/patternMatching.js +3 -2
- package/dist/analyzer/patternMatching.js.map +1 -1
- package/dist/analyzer/program.js +11 -5
- package/dist/analyzer/program.js.map +1 -1
- package/dist/analyzer/properties.js +9 -0
- package/dist/analyzer/properties.js.map +1 -1
- package/dist/analyzer/protocols.js +1 -1
- package/dist/analyzer/protocols.js.map +1 -1
- package/dist/analyzer/sourceFile.js +2 -1
- package/dist/analyzer/sourceFile.js.map +1 -1
- package/dist/analyzer/testWalker.js +5 -0
- package/dist/analyzer/testWalker.js.map +1 -1
- package/dist/analyzer/typeCacheUtils.d.ts +28 -0
- package/dist/analyzer/{typeCache.js → typeCacheUtils.js} +8 -14
- package/dist/analyzer/typeCacheUtils.js.map +1 -0
- package/dist/analyzer/typeEvaluator.js +495 -359
- package/dist/analyzer/typeEvaluator.js.map +1 -1
- package/dist/analyzer/typeGuards.js +1 -2
- package/dist/analyzer/typeGuards.js.map +1 -1
- package/dist/analyzer/typeUtils.d.ts +14 -6
- package/dist/analyzer/typeUtils.js +291 -144
- package/dist/analyzer/typeUtils.js.map +1 -1
- package/dist/analyzer/typeVarContext.d.ts +10 -17
- package/dist/analyzer/typeVarContext.js +58 -39
- package/dist/analyzer/typeVarContext.js.map +1 -1
- package/dist/analyzer/types.d.ts +4 -12
- package/dist/analyzer/types.js +22 -22
- package/dist/analyzer/types.js.map +1 -1
- package/dist/commands/dumpFileDebugInfoCommand.js +2 -2
- package/dist/commands/dumpFileDebugInfoCommand.js.map +1 -1
- package/dist/localization/localize.d.ts +18 -3
- package/dist/localization/localize.js +7 -1
- package/dist/localization/localize.js.map +1 -1
- package/dist/localization/package.nls.en-us.json +8 -2
- package/dist/parser/parseNodes.d.ts +1 -0
- package/dist/parser/parseNodes.js.map +1 -1
- package/dist/parser/parser.js +38 -16
- package/dist/parser/parser.js.map +1 -1
- package/dist/tests/typeEvaluator1.test.js +4 -0
- package/dist/tests/typeEvaluator1.test.js.map +1 -1
- package/dist/tests/typeEvaluator2.test.js +10 -2
- package/dist/tests/typeEvaluator2.test.js.map +1 -1
- package/dist/tests/typeEvaluator3.test.js +21 -3
- package/dist/tests/typeEvaluator3.test.js.map +1 -1
- package/dist/tests/typeEvaluator4.test.js +4 -0
- package/dist/tests/typeEvaluator4.test.js.map +1 -1
- package/dist/tests/typeEvaluator5.test.js +49 -7
- package/dist/tests/typeEvaluator5.test.js.map +1 -1
- package/package.json +2 -2
- package/dist/analyzer/typeCache.d.ts +0 -40
- package/dist/analyzer/typeCache.js.map +0 -1
@@ -67,7 +67,7 @@ const staticExpressions_1 = require("./staticExpressions");
|
|
67
67
|
const symbol_1 = require("./symbol");
|
68
68
|
const symbolNameUtils_1 = require("./symbolNameUtils");
|
69
69
|
const symbolUtils_1 = require("./symbolUtils");
|
70
|
-
const
|
70
|
+
const typeCacheUtils_1 = require("./typeCacheUtils");
|
71
71
|
const typedDicts_1 = require("./typedDicts");
|
72
72
|
const typeEvaluatorTypes_1 = require("./typeEvaluatorTypes");
|
73
73
|
const TypePrinter = __importStar(require("./typePrinter"));
|
@@ -227,9 +227,8 @@ const maxLiteralMathSubtypeCount = 64;
|
|
227
227
|
exports.maxCodeComplexity = 768;
|
228
228
|
function createTypeEvaluator(importLookup, evaluatorOptions) {
|
229
229
|
const symbolResolutionStack = [];
|
230
|
-
const typeCacheFlags = new Map();
|
231
230
|
const asymmetricDescriptorAssignmentCache = new Set();
|
232
|
-
const speculativeTypeTracker = new
|
231
|
+
const speculativeTypeTracker = new typeCacheUtils_1.SpeculativeTypeTracker();
|
233
232
|
const suppressedNodeStack = [];
|
234
233
|
let functionRecursionMap = new Set();
|
235
234
|
let codeFlowAnalyzerCache = new Map();
|
@@ -250,7 +249,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
250
249
|
let strClassType;
|
251
250
|
let dictClassType;
|
252
251
|
let typedDictClassType;
|
253
|
-
let incompleteTypeCache;
|
254
252
|
let printExpressionSpaceCount = 0;
|
255
253
|
const returnTypeInferenceContextStack = [];
|
256
254
|
let returnTypeInferenceTypeCache;
|
@@ -292,25 +290,27 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
292
290
|
else {
|
293
291
|
cachedType = typeCache.get(node.id);
|
294
292
|
}
|
295
|
-
return cachedType !== undefined;
|
293
|
+
return cachedType !== undefined && !cachedType.isIncomplete;
|
296
294
|
}
|
297
|
-
function
|
298
|
-
var _a, _b;
|
299
|
-
let cachedType;
|
295
|
+
function readTypeCacheEntry(node) {
|
300
296
|
// Should we use a temporary cache associated with a contextual
|
301
297
|
// analysis of a function, contextualized based on call-site argument types?
|
302
298
|
if (returnTypeInferenceTypeCache && isNodeInReturnTypeInferenceContext(node)) {
|
303
|
-
|
299
|
+
return returnTypeInferenceTypeCache.get(node.id);
|
304
300
|
}
|
305
301
|
else {
|
306
|
-
|
302
|
+
return typeCache.get(node.id);
|
307
303
|
}
|
308
|
-
|
304
|
+
}
|
305
|
+
function readTypeCache(node, flags) {
|
306
|
+
var _a, _b;
|
307
|
+
const cacheEntry = readTypeCacheEntry(node);
|
308
|
+
if (!cacheEntry || cacheEntry.isIncomplete) {
|
309
309
|
return undefined;
|
310
310
|
}
|
311
311
|
if (evaluatorOptions.verifyTypeCacheEvaluatorFlags || verifyTypeCacheEvaluatorFlags) {
|
312
312
|
if (flags !== undefined) {
|
313
|
-
const expectedFlags =
|
313
|
+
const expectedFlags = cacheEntry.flags;
|
314
314
|
if (expectedFlags !== undefined && flags !== expectedFlags) {
|
315
315
|
const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
|
316
316
|
const position = (0, positionUtils_1.convertOffsetToPosition)(node.start, fileInfo.lines);
|
@@ -327,34 +327,22 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
327
327
|
}
|
328
328
|
}
|
329
329
|
}
|
330
|
-
|
331
|
-
return cachedType;
|
330
|
+
return cacheEntry.type;
|
332
331
|
}
|
333
332
|
function writeTypeCache(node, type, flags, isIncomplete, expectedType, allowSpeculativeCaching = false) {
|
334
|
-
if (isIncomplete) {
|
335
|
-
if (incompleteTypeCache) {
|
336
|
-
incompleteTypeCache.set(node.id, type);
|
337
|
-
}
|
338
|
-
return;
|
339
|
-
}
|
340
333
|
// Should we use a temporary cache associated with a contextual
|
341
334
|
// analysis of a function, contextualized based on call-site argument types?
|
342
335
|
const typeCacheToUse = returnTypeInferenceTypeCache && isNodeInReturnTypeInferenceContext(node)
|
343
336
|
? returnTypeInferenceTypeCache
|
344
337
|
: typeCache;
|
345
|
-
typeCacheToUse.set(node.id, type);
|
346
|
-
if (evaluatorOptions.verifyTypeCacheEvaluatorFlags || verifyTypeCacheEvaluatorFlags) {
|
347
|
-
if (typeCacheToUse === typeCache && flags !== undefined) {
|
348
|
-
typeCacheFlags.set(node.id, flags);
|
349
|
-
}
|
350
|
-
}
|
338
|
+
typeCacheToUse.set(node.id, { type, isIncomplete, flags });
|
351
339
|
// If the entry is located within a part of the parse tree that is currently being
|
352
340
|
// "speculatively" evaluated, track it so we delete the cached entry when we leave
|
353
341
|
// this speculative context.
|
354
342
|
if (speculativeTypeTracker.isSpeculative(node)) {
|
355
343
|
speculativeTypeTracker.trackEntry(typeCacheToUse, node.id);
|
356
344
|
if (allowSpeculativeCaching) {
|
357
|
-
speculativeTypeTracker.addSpeculativeType(node, type, expectedType);
|
345
|
+
speculativeTypeTracker.addSpeculativeType(node, { type, isIncomplete }, expectedType);
|
358
346
|
}
|
359
347
|
}
|
360
348
|
}
|
@@ -517,12 +505,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
517
505
|
}
|
518
506
|
else {
|
519
507
|
// Is it cached in the speculative type cache?
|
520
|
-
const
|
521
|
-
if (
|
508
|
+
const cachedTypeResult = speculativeTypeTracker.getSpeculativeType(node, expectedType);
|
509
|
+
if (cachedTypeResult) {
|
522
510
|
if (printExpressionTypes) {
|
523
|
-
console.log(`${getPrintExpressionTypesSpaces()}${ParseTreeUtils.printExpression(node)} (${getLineNum(node)}): Speculative ${printType(
|
511
|
+
console.log(`${getPrintExpressionTypesSpaces()}${ParseTreeUtils.printExpression(node)} (${getLineNum(node)}): Speculative ${printType(cachedTypeResult.type)}`);
|
524
512
|
}
|
525
|
-
return { type:
|
513
|
+
return { type: cachedTypeResult.type, isIncomplete: cachedTypeResult.isIncomplete };
|
526
514
|
}
|
527
515
|
}
|
528
516
|
if (printExpressionTypes) {
|
@@ -918,24 +906,20 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
918
906
|
return typeResult;
|
919
907
|
}
|
920
908
|
function stripLiteralValue(type) {
|
921
|
-
|
922
|
-
if (
|
923
|
-
|
924
|
-
|
925
|
-
|
926
|
-
|
927
|
-
|
928
|
-
|
909
|
+
return (0, typeUtils_1.mapSubtypes)(type, (subtype) => {
|
910
|
+
if ((0, types_1.isClass)(subtype)) {
|
911
|
+
if (subtype.literalValue !== undefined) {
|
912
|
+
return types_1.ClassType.cloneWithLiteral(subtype, /* value */ undefined);
|
913
|
+
}
|
914
|
+
if (types_1.ClassType.isBuiltIn(subtype, 'LiteralString')) {
|
915
|
+
// Handle "LiteralString" specially.
|
916
|
+
if (strClassType && (0, types_1.isInstantiableClass)(strClassType)) {
|
917
|
+
return types_1.ClassType.cloneAsInstance(strClassType);
|
918
|
+
}
|
929
919
|
}
|
930
920
|
}
|
931
|
-
return
|
932
|
-
}
|
933
|
-
if ((0, types_1.isUnion)(type)) {
|
934
|
-
return (0, typeUtils_1.mapSubtypes)(type, (subtype) => {
|
935
|
-
return stripLiteralValue(subtype);
|
936
|
-
});
|
937
|
-
}
|
938
|
-
return type;
|
921
|
+
return subtype;
|
922
|
+
});
|
939
923
|
}
|
940
924
|
function getTypeOfParameterAnnotation(paramTypeNode, paramCategory) {
|
941
925
|
return getTypeOfAnnotation(paramTypeNode, {
|
@@ -2762,7 +2746,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
2762
2746
|
return undefined;
|
2763
2747
|
}
|
2764
2748
|
function getTypeOfName(node, flags) {
|
2765
|
-
var _a
|
2749
|
+
var _a;
|
2766
2750
|
const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
|
2767
2751
|
const name = node.value;
|
2768
2752
|
let symbol;
|
@@ -2773,7 +2757,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
2773
2757
|
const typeParamSymbol = AnalyzerNodeInfo.getTypeParameterSymbol(node);
|
2774
2758
|
if (typeParamSymbol) {
|
2775
2759
|
symbol = typeParamSymbol;
|
2776
|
-
|
2760
|
+
(0, debug_1.assert)(symbol.getDeclarations().length === 1);
|
2761
|
+
const decl = (0, symbolUtils_1.getLastTypedDeclaredForSymbol)(symbol);
|
2762
|
+
(0, debug_1.assert)((decl === null || decl === void 0 ? void 0 : decl.type) === 3 /* TypeParameter */);
|
2763
|
+
type = getTypeOfTypeParameter(decl.node);
|
2777
2764
|
setSymbolAccessed(fileInfo, symbol, node);
|
2778
2765
|
}
|
2779
2766
|
else {
|
@@ -2914,7 +2901,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
2914
2901
|
type.details.name === name) {
|
2915
2902
|
// Handle the special case of a PEP 604 union. These can appear within
|
2916
2903
|
// an implied type alias where we are not expecting a type.
|
2917
|
-
const isPep604Union = ((
|
2904
|
+
const isPep604Union = ((_a = node.parent) === null || _a === void 0 ? void 0 : _a.nodeType) === 7 /* BinaryOperation */ &&
|
2918
2905
|
node.parent.operator === 6 /* BitwiseOr */;
|
2919
2906
|
if (!isPep604Union) {
|
2920
2907
|
// A TypeVar in contexts where we're not expecting a type is
|
@@ -3030,7 +3017,15 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3030
3017
|
if (memberName === 'args' || memberName === 'kwargs') {
|
3031
3018
|
const outerFunctionScope = ParseTreeUtils.getEnclosingClassOrFunction(enclosingScope);
|
3032
3019
|
if ((outerFunctionScope === null || outerFunctionScope === void 0 ? void 0 : outerFunctionScope.nodeType) === 28 /* Function */) {
|
3033
|
-
|
3020
|
+
if (scopedTypeVarInfo.isRescoped) {
|
3021
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet
|
3022
|
+
.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.paramSpecScopedToReturnType().format({
|
3023
|
+
name: type.details.name,
|
3024
|
+
}), node);
|
3025
|
+
}
|
3026
|
+
else {
|
3027
|
+
enclosingScope = outerFunctionScope;
|
3028
|
+
}
|
3034
3029
|
}
|
3035
3030
|
else if (!scopedTypeVarInfo.type.scopeId) {
|
3036
3031
|
addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.paramSpecNotUsedByOuterScope().format({
|
@@ -3064,9 +3059,17 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3064
3059
|
else if ((flags & 4096 /* DisallowTypeVarsWithoutScopeId */) !== 0) {
|
3065
3060
|
if ((type.scopeId === undefined || scopedTypeVarInfo.foundInterveningClass) &&
|
3066
3061
|
!type.details.isSynthesized) {
|
3067
|
-
|
3068
|
-
|
3069
|
-
|
3062
|
+
let message;
|
3063
|
+
if (scopedTypeVarInfo.isRescoped) {
|
3064
|
+
message = (0, types_1.isParamSpec)(type)
|
3065
|
+
? localize_1.Localizer.Diagnostic.paramSpecScopedToReturnType()
|
3066
|
+
: localize_1.Localizer.Diagnostic.typeVarScopedToReturnType();
|
3067
|
+
}
|
3068
|
+
else {
|
3069
|
+
message = (0, types_1.isParamSpec)(type)
|
3070
|
+
? localize_1.Localizer.Diagnostic.paramSpecNotUsedByOuterScope()
|
3071
|
+
: localize_1.Localizer.Diagnostic.typeVarNotUsedByOuterScope();
|
3072
|
+
}
|
3070
3073
|
addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, message.format({ name: type.details.name }), node);
|
3071
3074
|
}
|
3072
3075
|
}
|
@@ -3082,43 +3085,51 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3082
3085
|
// type arguments. If so, it fills in these type arguments with Unknown
|
3083
3086
|
// and optionally reports an error.
|
3084
3087
|
function reportMissingTypeArguments(node, type, flags) {
|
3085
|
-
if ((flags & 2 /* DoNotSpecialize */)
|
3086
|
-
|
3087
|
-
|
3088
|
-
|
3089
|
-
|
3090
|
-
|
3091
|
-
|
3092
|
-
|
3093
|
-
|
3094
|
-
|
3095
|
-
type = createSpecializedClassType(type, /* typeArgs */ undefined, flags, node);
|
3088
|
+
if ((flags & 2 /* DoNotSpecialize */) !== 0) {
|
3089
|
+
return type;
|
3090
|
+
}
|
3091
|
+
// Is this a generic class that needs to be specialized?
|
3092
|
+
if ((0, types_1.isInstantiableClass)(type)) {
|
3093
|
+
if ((flags & 64 /* ExpectingType */) !== 0) {
|
3094
|
+
if ((0, typeUtils_1.requiresTypeArguments)(type) && !type.typeArguments) {
|
3095
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportMissingTypeArgument, diagnosticRules_1.DiagnosticRule.reportMissingTypeArgument, localize_1.Localizer.Diagnostic.typeArgsMissingForClass().format({
|
3096
|
+
name: type.aliasName || type.details.name,
|
3097
|
+
}), node);
|
3096
3098
|
}
|
3097
3099
|
}
|
3098
|
-
if (
|
3099
|
-
type
|
3100
|
-
|
3101
|
-
|
3102
|
-
|
3103
|
-
|
3104
|
-
|
3105
|
-
|
3106
|
-
|
3107
|
-
|
3108
|
-
|
3109
|
-
|
3110
|
-
|
3111
|
-
|
3112
|
-
|
3113
|
-
|
3114
|
-
|
3115
|
-
|
3116
|
-
|
3117
|
-
|
3118
|
-
|
3100
|
+
if (!type.typeArguments) {
|
3101
|
+
type = createSpecializedClassType(type, /* typeArgs */ undefined, flags, node);
|
3102
|
+
}
|
3103
|
+
}
|
3104
|
+
// Is this a generic type alias that needs to be specialized?
|
3105
|
+
if ((flags & 64 /* ExpectingType */) !== 0 &&
|
3106
|
+
type.typeAliasInfo &&
|
3107
|
+
type.typeAliasInfo.typeParameters &&
|
3108
|
+
type.typeAliasInfo.typeParameters.length > 0 &&
|
3109
|
+
!type.typeAliasInfo.typeArguments) {
|
3110
|
+
let reportMissingTypeArguments = false;
|
3111
|
+
const defaultTypeArgs = [];
|
3112
|
+
const typeVarContext = new typeVarContext_1.TypeVarContext(type.typeAliasInfo.typeVarScopeId);
|
3113
|
+
type.typeAliasInfo.typeParameters.forEach((param) => {
|
3114
|
+
if (!param.details.defaultType) {
|
3115
|
+
reportMissingTypeArguments = true;
|
3116
|
+
}
|
3117
|
+
let defaultType;
|
3118
|
+
if (param.details.defaultType || param.details.isParamSpec) {
|
3119
|
+
defaultType = (0, typeUtils_1.applySolvedTypeVars)(param, typeVarContext, { unknownIfNotFound: true });
|
3120
|
+
}
|
3121
|
+
else {
|
3122
|
+
defaultType = types_1.UnknownType.create();
|
3119
3123
|
}
|
3120
|
-
|
3124
|
+
defaultTypeArgs.push(defaultType);
|
3125
|
+
typeVarContext.setTypeVarType(param, defaultType);
|
3126
|
+
});
|
3127
|
+
if (reportMissingTypeArguments) {
|
3128
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportMissingTypeArgument, diagnosticRules_1.DiagnosticRule.reportMissingTypeArgument, localize_1.Localizer.Diagnostic.typeArgsMissingForAlias().format({
|
3129
|
+
name: type.typeAliasInfo.name,
|
3130
|
+
}), node);
|
3121
3131
|
}
|
3132
|
+
type = types_1.TypeBase.cloneForTypeAlias((0, typeUtils_1.applySolvedTypeVars)(type, typeVarContext, { unknownIfNotFound: true }), type.typeAliasInfo.name, type.typeAliasInfo.fullName, type.typeAliasInfo.typeVarScopeId, type.typeAliasInfo.typeParameters, defaultTypeArgs);
|
3122
3133
|
}
|
3123
3134
|
return type;
|
3124
3135
|
}
|
@@ -3152,8 +3163,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3152
3163
|
return scopeIds;
|
3153
3164
|
}
|
3154
3165
|
// Walks up the parse tree to find a function, class, or type alias
|
3155
|
-
//
|
3166
|
+
// declaration that provides the context for a type variable.
|
3156
3167
|
function findScopedTypeVar(node, type) {
|
3168
|
+
var _a;
|
3157
3169
|
let curNode = node;
|
3158
3170
|
let nestedClassCount = 0;
|
3159
3171
|
(0, debug_1.assert)(types_1.TypeBase.isInstantiable(type));
|
@@ -3175,14 +3187,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3175
3187
|
else if (curNode.nodeType === 28 /* Function */) {
|
3176
3188
|
const functionTypeInfo = getTypeOfFunction(curNode);
|
3177
3189
|
if (functionTypeInfo) {
|
3178
|
-
|
3179
|
-
|
3180
|
-
|
3181
|
-
|
3182
|
-
|
3183
|
-
|
3184
|
-
|
3185
|
-
(0, typeUtils_1.addTypeVarsToListIfUnique)(typeParametersForScope, (0, typeUtils_1.getTypeVarArgumentsRecursive)(functionTypeInfo.functionType.details.declaredReturnType));
|
3190
|
+
const functionDetails = functionTypeInfo.functionType.details;
|
3191
|
+
typeParametersForScope = functionDetails.typeParameters;
|
3192
|
+
// Was this type parameter "rescoped" to a callable found within the
|
3193
|
+
// return type annotation? If so, it is not available for use within
|
3194
|
+
// the function body.
|
3195
|
+
if ((_a = functionDetails.rescopedTypeParameters) === null || _a === void 0 ? void 0 : _a.some((tp) => tp.details.name === type.details.name)) {
|
3196
|
+
return { type, isRescoped: true, foundInterveningClass: false };
|
3186
3197
|
}
|
3187
3198
|
}
|
3188
3199
|
scopeUsesTypeParameterSyntax = !!curNode.typeParameters;
|
@@ -3195,7 +3206,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3195
3206
|
if (match === null || match === void 0 ? void 0 : match.scopeId) {
|
3196
3207
|
// Use the scoped version of the TypeVar rather than the (unscoped) original type.
|
3197
3208
|
type = types_1.TypeVarType.cloneForScopeId(type, match.scopeId, match.scopeName, match.scopeType);
|
3198
|
-
return {
|
3209
|
+
return {
|
3210
|
+
type,
|
3211
|
+
isRescoped: false,
|
3212
|
+
foundInterveningClass: nestedClassCount > 1 && !scopeUsesTypeParameterSyntax,
|
3213
|
+
};
|
3199
3214
|
}
|
3200
3215
|
}
|
3201
3216
|
curNode = curNode.parent;
|
@@ -3228,6 +3243,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3228
3243
|
}
|
3229
3244
|
return {
|
3230
3245
|
type: types_1.TypeVarType.cloneForScopeId(type, leftType.details.recursiveTypeAliasScopeId, leftType.details.recursiveTypeAliasName, 2 /* TypeAlias */),
|
3246
|
+
isRescoped: false,
|
3231
3247
|
foundInterveningClass: false,
|
3232
3248
|
};
|
3233
3249
|
}
|
@@ -3235,7 +3251,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3235
3251
|
curNode = curNode.parent;
|
3236
3252
|
}
|
3237
3253
|
// Return the original type.
|
3238
|
-
return { type, foundInterveningClass: false };
|
3254
|
+
return { type, isRescoped: false, foundInterveningClass: false };
|
3239
3255
|
}
|
3240
3256
|
function getTypeOfMemberAccess(node, flags) {
|
3241
3257
|
const baseTypeFlags = 2 /* DoNotSpecialize */ |
|
@@ -4209,12 +4225,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4209
4225
|
}
|
4210
4226
|
return indexTypeResult;
|
4211
4227
|
}
|
4212
|
-
function adjustTypeArgumentsForVariadicTypeVar(typeArgs, typeParameters, errorNode) {
|
4213
|
-
var _a;
|
4228
|
+
function adjustTypeArgumentsForVariadicTypeVar(typeArgs, typeParameters, typeVarScopeId, errorNode) {
|
4214
4229
|
const variadicIndex = typeParameters.findIndex((param) => (0, types_1.isVariadicTypeVar)(param));
|
4215
4230
|
// Do we need to adjust the type arguments to map to a variadic type
|
4216
4231
|
// param at the end of the list?
|
4217
4232
|
if (variadicIndex >= 0) {
|
4233
|
+
const variadicTypeVar = typeParameters[variadicIndex];
|
4218
4234
|
if (tupleClassType && (0, types_1.isInstantiableClass)(tupleClassType)) {
|
4219
4235
|
if (variadicIndex < typeArgs.length) {
|
4220
4236
|
const variadicTypeResults = typeArgs.slice(variadicIndex, variadicIndex + 1 + typeArgs.length - typeParameters.length);
|
@@ -4254,11 +4270,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4254
4270
|
];
|
4255
4271
|
}
|
4256
4272
|
}
|
4257
|
-
else {
|
4273
|
+
else if (!variadicTypeVar.details.defaultType) {
|
4258
4274
|
// Add an empty tuple that maps to the TypeVarTuple type parameter.
|
4259
4275
|
typeArgs.push({
|
4260
4276
|
node: errorNode,
|
4261
|
-
type: (
|
4277
|
+
type: (0, typeUtils_1.convertToInstance)((0, typeUtils_1.specializeTupleClass)(tupleClassType, [],
|
4262
4278
|
/* isTypeArgumentExplicit */ true,
|
4263
4279
|
/* isUnpackedTuple */ true)),
|
4264
4280
|
});
|
@@ -4295,7 +4311,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4295
4311
|
return undefined;
|
4296
4312
|
}
|
4297
4313
|
const typeParameters = baseType.typeAliasInfo.typeParameters;
|
4298
|
-
let typeArgs = adjustTypeArgumentsForVariadicTypeVar(getTypeArgs(node, flags), typeParameters, node);
|
4314
|
+
let typeArgs = adjustTypeArgumentsForVariadicTypeVar(getTypeArgs(node, flags), typeParameters, baseType.typeAliasInfo.typeVarScopeId, node);
|
4299
4315
|
// PEP 612 says that if the class has only one type parameter consisting
|
4300
4316
|
// of a ParamSpec, the list of arguments does not need to be enclosed in
|
4301
4317
|
// a list. We'll handle that case specially here. Presumably this applies to
|
@@ -4328,7 +4344,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4328
4344
|
const typeVarContext = new typeVarContext_1.TypeVarContext(baseType.typeAliasInfo.typeVarScopeId);
|
4329
4345
|
const diag = new diagnostic_1.DiagnosticAddendum();
|
4330
4346
|
typeParameters.forEach((param, index) => {
|
4331
|
-
var _a;
|
4332
4347
|
if (param.details.isParamSpec && index < typeArgs.length) {
|
4333
4348
|
const typeArgType = typeArgs[index].type;
|
4334
4349
|
if (typeArgs[index].typeList) {
|
@@ -4391,9 +4406,16 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4391
4406
|
if (index < typeArgs.length && typeArgs[index].typeList) {
|
4392
4407
|
addError(localize_1.Localizer.Diagnostic.typeArgListNotAllowed(), typeArgs[index].node);
|
4393
4408
|
}
|
4394
|
-
|
4395
|
-
|
4396
|
-
|
4409
|
+
let typeArgType;
|
4410
|
+
if (index < typeArgs.length) {
|
4411
|
+
typeArgType = (0, typeUtils_1.convertToInstance)(typeArgs[index].type);
|
4412
|
+
}
|
4413
|
+
else if (param.details.defaultType) {
|
4414
|
+
typeArgType = (0, typeUtils_1.applySolvedTypeVars)(param, typeVarContext, { unknownIfNotFound: true });
|
4415
|
+
}
|
4416
|
+
else {
|
4417
|
+
typeArgType = types_1.UnknownType.create();
|
4418
|
+
}
|
4397
4419
|
(0, constraintSolver_1.assignTypeToTypeVar)(evaluatorInterface, param, typeArgType, diag, typeVarContext, 128 /* RetainLiteralsForTypeVar */);
|
4398
4420
|
}
|
4399
4421
|
});
|
@@ -4404,8 +4426,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4404
4426
|
(_b = baseType.typeAliasInfo.typeParameters) === null || _b === void 0 ? void 0 : _b.forEach((typeParam) => {
|
4405
4427
|
let typeVarType;
|
4406
4428
|
if ((0, types_1.isParamSpec)(typeParam)) {
|
4407
|
-
const
|
4408
|
-
typeVarType =
|
4429
|
+
const paramSpecType = typeVarContext.getParamSpecType(typeParam);
|
4430
|
+
typeVarType = paramSpecType ? (0, typeUtils_1.convertParamSpecValueToType)(paramSpecType) : types_1.UnknownType.create();
|
4409
4431
|
}
|
4410
4432
|
else {
|
4411
4433
|
typeVarType = typeVarContext.getTypeVarType(typeParam);
|
@@ -4429,7 +4451,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4429
4451
|
let isIncomplete = baseTypeResult.isIncomplete;
|
4430
4452
|
const type = mapSubtypesExpandTypeVars(baseTypeResult.type,
|
4431
4453
|
/* conditionFilter */ undefined, (concreteSubtype, unexpandedSubtype) => {
|
4432
|
-
var _a;
|
4454
|
+
var _a, _b;
|
4433
4455
|
if ((0, types_1.isAnyOrUnknown)(concreteSubtype)) {
|
4434
4456
|
return concreteSubtype;
|
4435
4457
|
}
|
@@ -4496,7 +4518,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4496
4518
|
const isClassVarAnnotation = (0, types_1.isInstantiableClass)(concreteSubtype) && types_1.ClassType.isBuiltIn(concreteSubtype, 'ClassVar');
|
4497
4519
|
let typeArgs = getTypeArgs(node, flags, isAnnotatedClass, hasCustomClassGetItem || !isGenericClass, isFinalAnnotation, isClassVarAnnotation);
|
4498
4520
|
if (!isAnnotatedClass) {
|
4499
|
-
typeArgs = adjustTypeArgumentsForVariadicTypeVar(typeArgs, concreteSubtype.details.typeParameters, node);
|
4521
|
+
typeArgs = adjustTypeArgumentsForVariadicTypeVar(typeArgs, concreteSubtype.details.typeParameters, (_b = (0, typeUtils_1.getTypeVarScopeId)(concreteSubtype)) !== null && _b !== void 0 ? _b : '', node);
|
4500
4522
|
}
|
4501
4523
|
// If this is a custom __class_getitem__, there's no need to specialize the class.
|
4502
4524
|
// Just return it as is.
|
@@ -4954,6 +4976,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4954
4976
|
}
|
4955
4977
|
const entryTypeResults = node.expressions.map((expr, index) => getTypeOfExpression(expr,
|
4956
4978
|
/* flags */ undefined, index < expectedTypes.length ? expectedTypes[index] : undefined));
|
4979
|
+
const isIncomplete = entryTypeResults.some((result) => result.isIncomplete);
|
4957
4980
|
const type = (0, typeUtils_1.convertToInstance)((0, typeUtils_1.specializeTupleClass)(tupleClassType, buildTupleTypesList(entryTypeResults),
|
4958
4981
|
/* isTypeArgumentExplicit */ true));
|
4959
4982
|
// Copy any expected type diag addenda for precision error reporting.
|
@@ -4966,7 +4989,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4966
4989
|
}
|
4967
4990
|
});
|
4968
4991
|
}
|
4969
|
-
return { type, expectedTypeDiagAddendum };
|
4992
|
+
return { type, expectedTypeDiagAddendum, isIncomplete };
|
4970
4993
|
}
|
4971
4994
|
function getTypeOfTupleInferred(node) {
|
4972
4995
|
const entryTypeResults = node.expressions.map((expr) => getTypeOfExpression(expr));
|
@@ -5953,7 +5976,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5953
5976
|
unsolvedTypeVarsAreUnknown = false;
|
5954
5977
|
}
|
5955
5978
|
}
|
5956
|
-
const specializedType = (0, typeUtils_1.applySolvedTypeVars)(type, typeVarContext,
|
5979
|
+
const specializedType = (0, typeUtils_1.applySolvedTypeVars)(type, typeVarContext, {
|
5980
|
+
unknownIfNotFound: unsolvedTypeVarsAreUnknown,
|
5981
|
+
});
|
5957
5982
|
return types_1.ClassType.cloneAsInstance(specializedType);
|
5958
5983
|
}
|
5959
5984
|
// Similar to applyExpectedTypeForConstructor, this function handles the
|
@@ -7118,7 +7143,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7118
7143
|
}
|
7119
7144
|
const effectiveReturnType = getFunctionEffectiveReturnType(type);
|
7120
7145
|
let effectiveExpectedType = expectedType;
|
7121
|
-
let effectiveFlags =
|
7146
|
+
let effectiveFlags = 0 /* Default */;
|
7122
7147
|
if ((0, typeUtils_1.containsLiteralType)(effectiveExpectedType, /* includeTypeArgs */ true)) {
|
7123
7148
|
effectiveFlags |= 128 /* RetainLiteralsForTypeVar */;
|
7124
7149
|
}
|
@@ -7141,9 +7166,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7141
7166
|
if (effectiveExpectedType) {
|
7142
7167
|
// Prepopulate the typeVarContext based on the specialized expected type if the
|
7143
7168
|
// callee has a declared return type. This will allow us to more closely match
|
7144
|
-
// the expected type if possible.
|
7145
|
-
// SkipStripLiteralForTypeVar flags so the type can be further narrowed
|
7146
|
-
// and so literals are not stripped.
|
7169
|
+
// the expected type if possible.
|
7147
7170
|
// If the return type is not the same as the expected type but is
|
7148
7171
|
// assignable to the expected type, determine which type arguments
|
7149
7172
|
// are needed to match the expected type.
|
@@ -7340,15 +7363,17 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7340
7363
|
// the call below to adjustCallableReturnType will "detach" these
|
7341
7364
|
// TypeVars from the scope of this function and "attach" them to
|
7342
7365
|
// the scope of the callable.
|
7343
|
-
let
|
7366
|
+
let unknownIfNotFound = !(0, types_1.isFunction)(returnType);
|
7344
7367
|
// We'll also leave TypeVars unsolved if the call is a recursive
|
7345
7368
|
// call to a generic function.
|
7346
7369
|
const typeVarScopes = getTypeVarScopesForNode(errorNode);
|
7347
7370
|
if (typeVarScopes.some((typeVarScope) => typeVarContext.hasSolveForScope(typeVarScope))) {
|
7348
|
-
|
7371
|
+
unknownIfNotFound = false;
|
7349
7372
|
}
|
7350
|
-
let specializedReturnType = (0, typeUtils_1.addConditionToType)((0, typeUtils_1.applySolvedTypeVars)(returnType, typeVarContext,
|
7351
|
-
|
7373
|
+
let specializedReturnType = (0, typeUtils_1.addConditionToType)((0, typeUtils_1.applySolvedTypeVars)(returnType, typeVarContext, {
|
7374
|
+
unknownIfNotFound,
|
7375
|
+
eliminateUnsolvedInUnions,
|
7376
|
+
}), typeCondition);
|
7352
7377
|
// If the final return type is an unpacked tuple, turn it into a normal (unpacked) tuple.
|
7353
7378
|
if ((0, types_1.isUnpackedClass)(specializedReturnType)) {
|
7354
7379
|
specializedReturnType = types_1.ClassType.cloneForUnpacked(specializedReturnType, /* isUnpackedTuple */ false);
|
@@ -7413,20 +7438,18 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7413
7438
|
}
|
7414
7439
|
// Determines whether the specified argument list satisfies the function
|
7415
7440
|
// signature bound to the specified ParamSpec. Return value indicates success.
|
7416
|
-
function validateFunctionArgumentsForParamSpec(errorNode, argList, paramSpec,
|
7441
|
+
function validateFunctionArgumentsForParamSpec(errorNode, argList, paramSpec, destTypeVarContext, conditionFilter) {
|
7417
7442
|
var _a;
|
7418
|
-
const
|
7419
|
-
if (!
|
7443
|
+
const paramSpecType = destTypeVarContext.getParamSpecType(paramSpec);
|
7444
|
+
if (!paramSpecType) {
|
7420
7445
|
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.paramSpecNotBound().format({ type: printType(paramSpec) }), ((_a = argList[0]) === null || _a === void 0 ? void 0 : _a.valueExpression) || errorNode);
|
7421
7446
|
return false;
|
7422
7447
|
}
|
7423
|
-
|
7424
|
-
// not yet be solved. Add the TypeVar scope for the bound function.
|
7425
|
-
typeVarContext.addSolveForScope(paramSpecValue.typeVarScopeId);
|
7448
|
+
const srcTypeVarContext = new typeVarContext_1.TypeVarContext(paramSpecType.details.typeVarScopeId);
|
7426
7449
|
let reportedArgError = false;
|
7427
7450
|
// Build a map of all named parameters.
|
7428
7451
|
const paramMap = new Map();
|
7429
|
-
const paramSpecParams =
|
7452
|
+
const paramSpecParams = paramSpecType.details.parameters;
|
7430
7453
|
paramSpecParams.forEach((param) => {
|
7431
7454
|
if (param.name) {
|
7432
7455
|
paramMap.set(param.name, param);
|
@@ -7485,7 +7508,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7485
7508
|
requiresTypeVarMatching: false,
|
7486
7509
|
argument: arg,
|
7487
7510
|
errorNode: arg.valueExpression || errorNode,
|
7488
|
-
},
|
7511
|
+
}, srcTypeVarContext,
|
7489
7512
|
/* functionType */ undefined,
|
7490
7513
|
/* skipUnknownArgCheck */ false,
|
7491
7514
|
/* skipOverloadArg */ false,
|
@@ -7507,7 +7530,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7507
7530
|
const paramInfo = paramMap.get(name);
|
7508
7531
|
return paramInfo.category === 0 /* Simple */ && !paramInfo.hasDefault;
|
7509
7532
|
});
|
7510
|
-
if (unassignedParams.length > 0 && !
|
7533
|
+
if (unassignedParams.length > 0 && !paramSpecType.details.paramSpec) {
|
7511
7534
|
const missingParamNames = unassignedParams.map((p) => `"${p}"`).join(', ');
|
7512
7535
|
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, unassignedParams.length === 1
|
7513
7536
|
? localize_1.Localizer.Diagnostic.argMissingForParam().format({ name: missingParamNames })
|
@@ -7515,6 +7538,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7515
7538
|
reportedArgError = true;
|
7516
7539
|
}
|
7517
7540
|
}
|
7541
|
+
if (!reportedArgError) {
|
7542
|
+
destTypeVarContext.applySourceContextTypeVars(srcTypeVarContext);
|
7543
|
+
}
|
7518
7544
|
return !reportedArgError;
|
7519
7545
|
}
|
7520
7546
|
function validateArgType(argParam, typeVarContext, functionType, skipUnknownCheck, skipOverloadArg, useNarrowBoundOnly, conditionFilter) {
|
@@ -7536,8 +7562,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7536
7562
|
functionType !== undefined &&
|
7537
7563
|
argParam.paramType.scopeId === functionType.details.typeVarScopeId
|
7538
7564
|
? undefined
|
7539
|
-
: (0, typeUtils_1.applySolvedTypeVars)(argParam.paramType, typeVarContext,
|
7540
|
-
/* unknownIfNotFound */ false, useNarrowBoundOnly);
|
7565
|
+
: (0, typeUtils_1.applySolvedTypeVars)(argParam.paramType, typeVarContext, { useNarrowBoundOnly });
|
7541
7566
|
// If the expected type is unknown, don't use an expected type. Instead,
|
7542
7567
|
// use default rules for evaluating the expression type.
|
7543
7568
|
if (expectedType && (0, types_1.isUnknown)(expectedType)) {
|
@@ -7856,8 +7881,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7856
7881
|
// or constraint.
|
7857
7882
|
if (typeVar.details.defaultType && defaultValueNode) {
|
7858
7883
|
const typeVarContext = new typeVarContext_1.TypeVarContext(types_1.WildcardTypeVarScopeId);
|
7859
|
-
const concreteDefaultType = (0, typeUtils_1.applySolvedTypeVars)(typeVar.details.defaultType, typeVarContext,
|
7860
|
-
|
7884
|
+
const concreteDefaultType = makeTopLevelTypeVarsConcrete((0, typeUtils_1.applySolvedTypeVars)(typeVar.details.defaultType, typeVarContext, {
|
7885
|
+
unknownIfNotFound: true,
|
7886
|
+
}));
|
7861
7887
|
if (typeVar.details.boundType) {
|
7862
7888
|
if (!assignType(typeVar.details.boundType, concreteDefaultType)) {
|
7863
7889
|
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeVarDefaultBoundMismatch(), defaultValueNode);
|
@@ -8016,62 +8042,67 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8016
8042
|
// in the Python specification: The static type checker will treat
|
8017
8043
|
// the new type as if it were a subclass of the original type.
|
8018
8044
|
function createNewType(errorNode, argList) {
|
8045
|
+
var _a;
|
8019
8046
|
const fileInfo = AnalyzerNodeInfo.getFileInfo(errorNode);
|
8020
|
-
let className = '
|
8021
|
-
if (argList.length
|
8022
|
-
|
8023
|
-
|
8024
|
-
|
8025
|
-
|
8026
|
-
|
8027
|
-
|
8028
|
-
|
8029
|
-
|
8030
|
-
|
8031
|
-
|
8032
|
-
|
8033
|
-
|
8034
|
-
|
8035
|
-
|
8036
|
-
|
8037
|
-
|
8038
|
-
|
8039
|
-
|
8040
|
-
|
8041
|
-
|
8042
|
-
|
8043
|
-
|
8044
|
-
|
8045
|
-
|
8046
|
-
|
8047
|
-
|
8048
|
-
|
8049
|
-
|
8050
|
-
|
8051
|
-
|
8052
|
-
|
8053
|
-
|
8054
|
-
|
8055
|
-
|
8056
|
-
|
8057
|
-
|
8058
|
-
|
8059
|
-
|
8060
|
-
|
8061
|
-
|
8062
|
-
|
8063
|
-
|
8064
|
-
|
8065
|
-
|
8066
|
-
|
8067
|
-
|
8068
|
-
|
8069
|
-
classType
|
8070
|
-
|
8071
|
-
}
|
8072
|
-
|
8073
|
-
|
8074
|
-
|
8047
|
+
let className = '';
|
8048
|
+
if (argList.length !== 2) {
|
8049
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.newTypeParamCount(), errorNode);
|
8050
|
+
return undefined;
|
8051
|
+
}
|
8052
|
+
const nameArg = argList[0];
|
8053
|
+
if (nameArg.argumentCategory === 0 /* Simple */ &&
|
8054
|
+
nameArg.valueExpression &&
|
8055
|
+
nameArg.valueExpression.nodeType === 48 /* StringList */) {
|
8056
|
+
className = nameArg.valueExpression.strings.map((s) => s.value).join('');
|
8057
|
+
}
|
8058
|
+
if (!className) {
|
8059
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.newTypeBadName(), (_a = argList[0].node) !== null && _a !== void 0 ? _a : errorNode);
|
8060
|
+
return undefined;
|
8061
|
+
}
|
8062
|
+
const baseClass = getTypeOfArgumentExpectingType(argList[1]).type;
|
8063
|
+
if ((0, types_1.isInstantiableClass)(baseClass)) {
|
8064
|
+
if (types_1.ClassType.isProtocolClass(baseClass)) {
|
8065
|
+
addError(localize_1.Localizer.Diagnostic.newTypeProtocolClass(), argList[1].node || errorNode);
|
8066
|
+
}
|
8067
|
+
else if (baseClass.literalValue !== undefined) {
|
8068
|
+
addError(localize_1.Localizer.Diagnostic.newTypeLiteral(), argList[1].node || errorNode);
|
8069
|
+
}
|
8070
|
+
const classFlags = baseClass.details.flags & ~(1 /* BuiltInClass */ | 2 /* SpecialBuiltIn */);
|
8071
|
+
const classType = types_1.ClassType.createInstantiable(className, ParseTreeUtils.getClassFullName(errorNode, fileInfo.moduleName, className), fileInfo.moduleName, fileInfo.filePath, classFlags, ParseTreeUtils.getTypeSourceId(errorNode),
|
8072
|
+
/* declaredMetaclass */ undefined, baseClass.details.effectiveMetaclass);
|
8073
|
+
classType.details.baseClasses.push(baseClass);
|
8074
|
+
(0, typeUtils_1.computeMroLinearization)(classType);
|
8075
|
+
// Synthesize an __init__ method that accepts only the specified type.
|
8076
|
+
const initType = types_1.FunctionType.createSynthesizedInstance('__init__');
|
8077
|
+
types_1.FunctionType.addParameter(initType, {
|
8078
|
+
category: 0 /* Simple */,
|
8079
|
+
name: 'self',
|
8080
|
+
type: types_1.ClassType.cloneAsInstance(classType),
|
8081
|
+
hasDeclaredType: true,
|
8082
|
+
});
|
8083
|
+
types_1.FunctionType.addParameter(initType, {
|
8084
|
+
category: 0 /* Simple */,
|
8085
|
+
name: '_x',
|
8086
|
+
type: types_1.ClassType.cloneAsInstance(baseClass),
|
8087
|
+
hasDeclaredType: true,
|
8088
|
+
});
|
8089
|
+
initType.details.declaredReturnType = types_1.NoneType.createInstance();
|
8090
|
+
classType.details.fields.set('__init__', symbol_1.Symbol.createWithType(4 /* ClassMember */, initType));
|
8091
|
+
// Synthesize a trivial __new__ method.
|
8092
|
+
const newType = types_1.FunctionType.createSynthesizedInstance('__new__', 1 /* ConstructorMethod */);
|
8093
|
+
types_1.FunctionType.addParameter(newType, {
|
8094
|
+
category: 0 /* Simple */,
|
8095
|
+
name: 'cls',
|
8096
|
+
type: classType,
|
8097
|
+
hasDeclaredType: true,
|
8098
|
+
});
|
8099
|
+
types_1.FunctionType.addDefaultParameters(newType);
|
8100
|
+
newType.details.declaredReturnType = types_1.ClassType.cloneAsInstance(classType);
|
8101
|
+
classType.details.fields.set('__new__', symbol_1.Symbol.createWithType(4 /* ClassMember */, newType));
|
8102
|
+
return classType;
|
8103
|
+
}
|
8104
|
+
if (!(0, types_1.isAnyOrUnknown)(baseClass)) {
|
8105
|
+
addError(localize_1.Localizer.Diagnostic.newTypeNotAClass(), argList[1].node || errorNode);
|
8075
8106
|
}
|
8076
8107
|
return undefined;
|
8077
8108
|
}
|
@@ -9296,7 +9327,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9296
9327
|
// type explicitly includes literals.
|
9297
9328
|
let typeVarContext = new typeVarContext_1.TypeVarContext(targetTypeVar.scopeId);
|
9298
9329
|
if (useSynthesizedTypeVar) {
|
9299
|
-
typeVarContext.setTypeVarType(targetTypeVar, isNarrowable ? undefined : expectedType,
|
9330
|
+
typeVarContext.setTypeVarType(targetTypeVar, isNarrowable ? undefined : expectedType,
|
9331
|
+
/* narrowBoundNoLiterals */ undefined, expectedType);
|
9300
9332
|
}
|
9301
9333
|
if (entryTypes.every((entryType) => assignType(targetTypeVar, stripLiteralValue(entryType), /* diag */ undefined, typeVarContext))) {
|
9302
9334
|
return (0, typeUtils_1.applySolvedTypeVars)(targetTypeVar, typeVarContext);
|
@@ -9304,8 +9336,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9304
9336
|
// Allocate a fresh typeVarContext before we try again with literals not stripped.
|
9305
9337
|
typeVarContext = new typeVarContext_1.TypeVarContext(targetTypeVar.scopeId);
|
9306
9338
|
if (useSynthesizedTypeVar) {
|
9307
|
-
typeVarContext.setTypeVarType(targetTypeVar, isNarrowable ? undefined : expectedType,
|
9308
|
-
/*
|
9339
|
+
typeVarContext.setTypeVarType(targetTypeVar, isNarrowable ? undefined : expectedType,
|
9340
|
+
/* narrowBoundNoLiterals */ undefined, expectedType);
|
9309
9341
|
}
|
9310
9342
|
if (entryTypes.every((entryType) => assignType(targetTypeVar, entryType, /* diag */ undefined, typeVarContext))) {
|
9311
9343
|
return (0, typeUtils_1.applySolvedTypeVars)(targetTypeVar, typeVarContext);
|
@@ -10375,7 +10407,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10375
10407
|
}
|
10376
10408
|
return createSpecialType(classType, typeArgs, /* paramLimit */ undefined, /* allowParamSpec */ true);
|
10377
10409
|
}
|
10378
|
-
function transformTypeForTypeAlias(type, name, errorNode, typeParameters) {
|
10410
|
+
function transformTypeForTypeAlias(type, name, errorNode, typeParameters, typeParamNodes) {
|
10379
10411
|
if (!types_1.TypeBase.isInstantiable(type)) {
|
10380
10412
|
return type;
|
10381
10413
|
}
|
@@ -10404,6 +10436,15 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10404
10436
|
}
|
10405
10437
|
return (0, typeUtils_1.convertToInstance)(typeVar);
|
10406
10438
|
});
|
10439
|
+
// Validate the default types for all type parameters.
|
10440
|
+
typeParameters.forEach((typeParam, index) => {
|
10441
|
+
var _a;
|
10442
|
+
let bestErrorNode = errorNode;
|
10443
|
+
if (typeParamNodes && index < typeParamNodes.length) {
|
10444
|
+
bestErrorNode = (_a = typeParamNodes[index].defaultExpression) !== null && _a !== void 0 ? _a : typeParamNodes[index].name;
|
10445
|
+
}
|
10446
|
+
validateTypeParameterDefault(bestErrorNode, typeParam, typeParameters.slice(0, index));
|
10447
|
+
});
|
10407
10448
|
// Verify that we have at most one variadic type variable.
|
10408
10449
|
const variadics = typeParameters.filter((param) => (0, types_1.isVariadicTypeVar)(param));
|
10409
10450
|
if (variadics.length > 1) {
|
@@ -10745,6 +10786,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10745
10786
|
// path does not handle traditional type aliases, which are treated as
|
10746
10787
|
// variables since they use normal variable assignment syntax.
|
10747
10788
|
function getTypeOfTypeAlias(node) {
|
10789
|
+
var _a;
|
10748
10790
|
const cachedType = readTypeCache(node.name, 0 /* None */);
|
10749
10791
|
if (cachedType) {
|
10750
10792
|
return cachedType;
|
@@ -10782,7 +10824,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10782
10824
|
}
|
10783
10825
|
// Clear the temporary type we wrote above.
|
10784
10826
|
deleteTypeCacheEntry(node.name);
|
10785
|
-
aliasType = transformTypeForTypeAlias(aliasType, node.name, node.expression, typeParameters);
|
10827
|
+
aliasType = transformTypeForTypeAlias(aliasType, node.name, node.expression, typeParameters, (_a = node.typeParameters) === null || _a === void 0 ? void 0 : _a.parameters);
|
10786
10828
|
if ((0, typeUtils_1.isTypeAliasRecursive)(typeAliasTypeVar, aliasType)) {
|
10787
10829
|
addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeAliasIsRecursiveDirect().format({
|
10788
10830
|
name: node.name.value,
|
@@ -11100,6 +11142,16 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11100
11142
|
names: variadics.map((v) => `"${v.details.name}"`).join(', '),
|
11101
11143
|
}), node.name, textRange_1.TextRange.combine(node.arguments) || node.name);
|
11102
11144
|
}
|
11145
|
+
// Validate the default types for all type parameters.
|
11146
|
+
classType.details.typeParameters.forEach((typeParam, index) => {
|
11147
|
+
var _a;
|
11148
|
+
let bestErrorNode = node.name;
|
11149
|
+
if (node.typeParameters && index < node.typeParameters.parameters.length) {
|
11150
|
+
const typeParamNode = node.typeParameters.parameters[index];
|
11151
|
+
bestErrorNode = (_a = typeParamNode.defaultExpression) !== null && _a !== void 0 ? _a : typeParamNode.name;
|
11152
|
+
}
|
11153
|
+
validateTypeParameterDefault(bestErrorNode, typeParam, classType.details.typeParameters.slice(0, index));
|
11154
|
+
});
|
11103
11155
|
if (!(0, typeUtils_1.computeMroLinearization)(classType)) {
|
11104
11156
|
addError(localize_1.Localizer.Diagnostic.methodOrdering(), node.name);
|
11105
11157
|
}
|
@@ -11288,6 +11340,34 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11288
11340
|
}
|
11289
11341
|
return { classType, decoratedType };
|
11290
11342
|
}
|
11343
|
+
// Determines whether the type parameters has a default that refers to another
|
11344
|
+
// type parameter. If so, validates that it is in the list of "live" type
|
11345
|
+
// parameters and updates the scope of the type parameter referred to in the
|
11346
|
+
// default type expression.
|
11347
|
+
function validateTypeParameterDefault(errorNode, typeParam, otherLiveTypeParams) {
|
11348
|
+
if (!typeParam.details.defaultType) {
|
11349
|
+
const typeVarWithDefault = otherLiveTypeParams.find((param) => param.details.defaultType);
|
11350
|
+
if (typeVarWithDefault) {
|
11351
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeVarWithoutDefault().format({
|
11352
|
+
name: typeParam.details.name,
|
11353
|
+
other: typeVarWithDefault.details.name,
|
11354
|
+
}), errorNode);
|
11355
|
+
}
|
11356
|
+
return;
|
11357
|
+
}
|
11358
|
+
const invalidTypeVars = new Set();
|
11359
|
+
(0, typeUtils_1.validateTypeVarDefault)(typeParam, otherLiveTypeParams, invalidTypeVars);
|
11360
|
+
// If we found one or more unapplied type variable, report an error.
|
11361
|
+
if (invalidTypeVars.size > 0) {
|
11362
|
+
const diag = new diagnostic_1.DiagnosticAddendum();
|
11363
|
+
invalidTypeVars.forEach((name) => {
|
11364
|
+
diag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeVarDefaultOutOfScope().format({ name }));
|
11365
|
+
});
|
11366
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeVarDefaultInvalidTypeVar().format({
|
11367
|
+
name: typeParam.details.name,
|
11368
|
+
}) + diag.getString(), errorNode);
|
11369
|
+
}
|
11370
|
+
}
|
11291
11371
|
function inferTypeParameterVarianceForClass(classType) {
|
11292
11372
|
if (!classType.details.requiresVarianceInference) {
|
11293
11373
|
return;
|
@@ -11594,6 +11674,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11594
11674
|
});
|
11595
11675
|
}
|
11596
11676
|
function getTypeOfFunction(node) {
|
11677
|
+
var _a, _b;
|
11597
11678
|
const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
|
11598
11679
|
// Is this type already cached?
|
11599
11680
|
const cachedFunctionType = readTypeCache(node.name, 0 /* None */);
|
@@ -11693,8 +11774,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11693
11774
|
}), node.functionAnnotationComment);
|
11694
11775
|
}
|
11695
11776
|
}
|
11777
|
+
// If this function uses PEP 695 syntax for type parameters,
|
11778
|
+
// accumulate the list of type parameters upfront.
|
11779
|
+
const typeParametersSeen = [];
|
11696
11780
|
if (node.typeParameters) {
|
11697
|
-
evaluateTypeParameterList(node.typeParameters);
|
11781
|
+
functionType.details.typeParameters = evaluateTypeParameterList(node.typeParameters);
|
11782
|
+
}
|
11783
|
+
else {
|
11784
|
+
functionType.details.typeParameters = typeParametersSeen;
|
11698
11785
|
}
|
11699
11786
|
const markParamAccessed = (param) => {
|
11700
11787
|
if (param.name) {
|
@@ -11842,6 +11929,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11842
11929
|
isTypeInferred,
|
11843
11930
|
};
|
11844
11931
|
types_1.FunctionType.addParameter(functionType, functionParam);
|
11932
|
+
if (functionParam.hasDeclaredType) {
|
11933
|
+
(0, typeUtils_1.addTypeVarsToListIfUnique)(typeParametersSeen, (0, typeUtils_1.getTypeVarArgumentsRecursive)(functionParam.type));
|
11934
|
+
}
|
11845
11935
|
if (param.name) {
|
11846
11936
|
const variadicParamType = transformVariadicParamType(node, param.category, functionParam.type);
|
11847
11937
|
paramTypes.push(variadicParamType);
|
@@ -11882,19 +11972,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11882
11972
|
// If there was a defined return type, analyze that first so when we
|
11883
11973
|
// walk the contents of the function, return statements can be
|
11884
11974
|
// validated against this type.
|
11885
|
-
|
11975
|
+
const returnTypeAnnotationNode = (_a = node.returnTypeAnnotation) !== null && _a !== void 0 ? _a : (_b = node.functionAnnotationComment) === null || _b === void 0 ? void 0 : _b.returnTypeAnnotation;
|
11976
|
+
if (returnTypeAnnotationNode) {
|
11886
11977
|
// Temporarily set the return type to unknown in case of recursion.
|
11887
11978
|
functionType.details.declaredReturnType = types_1.UnknownType.create();
|
11888
|
-
const returnType = getTypeOfAnnotation(
|
11889
|
-
associateTypeVarsWithScope: true,
|
11890
|
-
disallowRecursiveTypeAlias: true,
|
11891
|
-
});
|
11892
|
-
functionType.details.declaredReturnType = returnType;
|
11893
|
-
}
|
11894
|
-
else if (node.functionAnnotationComment) {
|
11895
|
-
// Temporarily set the return type to unknown in case of recursion.
|
11896
|
-
functionType.details.declaredReturnType = types_1.UnknownType.create();
|
11897
|
-
const returnType = getTypeOfAnnotation(node.functionAnnotationComment.returnTypeAnnotation, {
|
11979
|
+
const returnType = getTypeOfAnnotation(returnTypeAnnotationNode, {
|
11898
11980
|
associateTypeVarsWithScope: true,
|
11899
11981
|
disallowRecursiveTypeAlias: true,
|
11900
11982
|
});
|
@@ -11915,6 +11997,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11915
11997
|
}
|
11916
11998
|
}
|
11917
11999
|
}
|
12000
|
+
// Accumulate any type parameters used in the return type.
|
12001
|
+
if (functionType.details.declaredReturnType && returnTypeAnnotationNode) {
|
12002
|
+
rescopeTypeVarsForCallableReturnType(functionType.details.declaredReturnType, functionType, typeParametersSeen);
|
12003
|
+
}
|
11918
12004
|
// If the return type is explicitly annotated as a generator, mark the
|
11919
12005
|
// function as a generator even though it may not contain a "yield" statement.
|
11920
12006
|
// This is important for generator functions declared in stub files, abstract
|
@@ -11930,6 +12016,16 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11930
12016
|
functionType.details.flags |= 16 /* Generator */;
|
11931
12017
|
}
|
11932
12018
|
}
|
12019
|
+
// Validate the default types for all type parameters.
|
12020
|
+
functionType.details.typeParameters.forEach((typeParam, index) => {
|
12021
|
+
var _a;
|
12022
|
+
let bestErrorNode = node.name;
|
12023
|
+
if (node.typeParameters && index < node.typeParameters.parameters.length) {
|
12024
|
+
const typeParamNode = node.typeParameters.parameters[index];
|
12025
|
+
bestErrorNode = (_a = typeParamNode.defaultExpression) !== null && _a !== void 0 ? _a : typeParamNode.name;
|
12026
|
+
}
|
12027
|
+
validateTypeParameterDefault(bestErrorNode, typeParam, functionType.details.typeParameters.slice(0, index));
|
12028
|
+
});
|
11933
12029
|
// Clear the "partially evaluated" flag to indicate that the functionType
|
11934
12030
|
// is fully evaluated.
|
11935
12031
|
functionType.details.flags &= ~131072 /* PartiallyEvaluated */;
|
@@ -11967,6 +12063,37 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11967
12063
|
writeTypeCache(node, decoratedType, 0 /* None */, /* isIncomplete */ false);
|
11968
12064
|
return { functionType, decoratedType };
|
11969
12065
|
}
|
12066
|
+
// If the declared return type of a function contains type variables that
|
12067
|
+
// are found nowhere else in the signature and are contained within a
|
12068
|
+
// Callable, these type variables are "rescoped" from the function to
|
12069
|
+
// the Callable.
|
12070
|
+
function rescopeTypeVarsForCallableReturnType(returnType, functionType, typeParametersSeen) {
|
12071
|
+
const typeVarsInReturnType = (0, typeUtils_1.getTypeVarArgumentsRecursive)(returnType);
|
12072
|
+
const rescopedTypeVars = [];
|
12073
|
+
typeVarsInReturnType.forEach((typeVar) => {
|
12074
|
+
if (types_1.TypeBase.isInstantiable(typeVar)) {
|
12075
|
+
typeVar = types_1.TypeVarType.cloneAsInstance(typeVar);
|
12076
|
+
}
|
12077
|
+
// If this type variable isn't scoped to this function, it is probably
|
12078
|
+
// associated with an outer scope.
|
12079
|
+
if (typeVar.scopeId !== functionType.details.typeVarScopeId) {
|
12080
|
+
return;
|
12081
|
+
}
|
12082
|
+
// If this type variable was already seen in one or more input parameters,
|
12083
|
+
// don't attempt to rescope it.
|
12084
|
+
if (typeParametersSeen.some((tp) => (0, types_1.isTypeSame)((0, typeUtils_1.convertToInstance)(tp), typeVar))) {
|
12085
|
+
return;
|
12086
|
+
}
|
12087
|
+
// Is this type variable seen outside of a single callable?
|
12088
|
+
if ((0, typeUtils_1.isTypeVarLimitedToCallable)(returnType, typeVar)) {
|
12089
|
+
rescopedTypeVars.push(typeVar);
|
12090
|
+
}
|
12091
|
+
});
|
12092
|
+
(0, typeUtils_1.addTypeVarsToListIfUnique)(typeParametersSeen, typeVarsInReturnType);
|
12093
|
+
// Note that the type parameters have been rescoped so they are not
|
12094
|
+
// considered valid for the body of this function.
|
12095
|
+
functionType.details.rescopedTypeParameters = rescopedTypeVars;
|
12096
|
+
}
|
11970
12097
|
function adjustParameterAnnotatedType(param, type) {
|
11971
12098
|
var _a;
|
11972
12099
|
// PEP 484 indicates that if a parameter has a default value of 'None'
|
@@ -13315,36 +13442,16 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13315
13442
|
// within that tree. If the type cannot be determined (because it's part
|
13316
13443
|
// of a cyclical dependency), the function returns undefined.
|
13317
13444
|
function evaluateTypeForSubnode(subnode, callback) {
|
13318
|
-
// If the type cache is already populated
|
13319
|
-
// doing additional work.
|
13320
|
-
let
|
13321
|
-
if (
|
13322
|
-
return { type:
|
13445
|
+
// If the type cache is already populated with a complete type,
|
13446
|
+
// don't bother doing additional work.
|
13447
|
+
let cacheEntry = readTypeCacheEntry(subnode);
|
13448
|
+
if (cacheEntry && !cacheEntry.isIncomplete) {
|
13449
|
+
return { type: cacheEntry.type };
|
13323
13450
|
}
|
13324
|
-
|
13325
|
-
|
13326
|
-
|
13327
|
-
|
13328
|
-
// abandon it once the last nested call completes.
|
13329
|
-
if (!incompleteTypeCache) {
|
13330
|
-
incompleteTypeCache = new Map();
|
13331
|
-
}
|
13332
|
-
callback();
|
13333
|
-
subnodeType = readTypeCache(subnode, /* flags */ undefined);
|
13334
|
-
if (subnodeType) {
|
13335
|
-
return { type: subnodeType };
|
13336
|
-
}
|
13337
|
-
subnodeType = incompleteTypeCache.get(subnode.id);
|
13338
|
-
if (subnodeType) {
|
13339
|
-
return { type: subnodeType, isIncomplete: true };
|
13340
|
-
}
|
13341
|
-
incompleteTypeCache = oldIncompleteCache;
|
13342
|
-
}
|
13343
|
-
catch (e) {
|
13344
|
-
// We don't use a finally clause here because the debugger doesn't
|
13345
|
-
// handle it well when stepping through code.
|
13346
|
-
incompleteTypeCache = oldIncompleteCache;
|
13347
|
-
throw e;
|
13451
|
+
callback();
|
13452
|
+
cacheEntry = readTypeCacheEntry(subnode);
|
13453
|
+
if (cacheEntry) {
|
13454
|
+
return { type: cacheEntry.type, isIncomplete: cacheEntry.isIncomplete };
|
13348
13455
|
}
|
13349
13456
|
return undefined;
|
13350
13457
|
}
|
@@ -13609,8 +13716,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13609
13716
|
}
|
13610
13717
|
}
|
13611
13718
|
}
|
13719
|
+
const typeVarContext = new typeVarContext_1.TypeVarContext(classType.details.typeVarScopeId);
|
13612
13720
|
fullTypeParams.forEach((typeParam, index) => {
|
13613
|
-
var _a;
|
13614
13721
|
if (typeArgs && index < typeArgs.length) {
|
13615
13722
|
if (typeParam.details.isParamSpec) {
|
13616
13723
|
const typeArg = typeArgs[index];
|
@@ -13620,6 +13727,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13620
13727
|
types_1.FunctionType.addDefaultParameters(functionType);
|
13621
13728
|
functionType.details.flags |= 32768 /* SkipArgsKwargsCompatibilityCheck */;
|
13622
13729
|
typeArgTypes.push(functionType);
|
13730
|
+
typeVarContext.setTypeVarType(typeParam, (0, typeUtils_1.convertTypeToParamSpecValue)(functionType));
|
13623
13731
|
return;
|
13624
13732
|
}
|
13625
13733
|
if (typeArg.typeList) {
|
@@ -13633,6 +13741,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13633
13741
|
});
|
13634
13742
|
});
|
13635
13743
|
typeArgTypes.push(functionType);
|
13744
|
+
typeVarContext.setTypeVarType(typeParam, (0, typeUtils_1.convertTypeToParamSpecValue)(functionType));
|
13636
13745
|
return;
|
13637
13746
|
}
|
13638
13747
|
if ((0, types_1.isInstantiableClass)(typeArg.type) && types_1.ClassType.isBuiltIn(typeArg.type, 'Concatenate')) {
|
@@ -13659,10 +13768,19 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13659
13768
|
return;
|
13660
13769
|
}
|
13661
13770
|
}
|
13662
|
-
|
13771
|
+
const typeArgType = (0, typeUtils_1.convertToInstance)(typeArgs[index].type);
|
13772
|
+
typeArgTypes.push(typeArgType);
|
13773
|
+
typeVarContext.setTypeVarType(typeParam, typeArgType);
|
13663
13774
|
return;
|
13664
13775
|
}
|
13665
|
-
|
13776
|
+
const solvedDefaultType = (0, typeUtils_1.applySolvedTypeVars)(typeParam, typeVarContext, { unknownIfNotFound: true });
|
13777
|
+
typeArgTypes.push(solvedDefaultType);
|
13778
|
+
if ((0, types_1.isParamSpec)(typeParam)) {
|
13779
|
+
typeVarContext.setTypeVarType(typeParam, (0, typeUtils_1.convertTypeToParamSpecValue)(solvedDefaultType));
|
13780
|
+
}
|
13781
|
+
else {
|
13782
|
+
typeVarContext.setTypeVarType(typeParam, solvedDefaultType);
|
13783
|
+
}
|
13666
13784
|
});
|
13667
13785
|
typeArgTypes = typeArgTypes.map((typeArgType, index) => {
|
13668
13786
|
if (index < typeArgCount) {
|
@@ -14202,65 +14320,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
14202
14320
|
return undefined;
|
14203
14321
|
}
|
14204
14322
|
case 3 /* TypeParameter */: {
|
14205
|
-
|
14206
|
-
if (declaration.node.typeParamCategory === parseNodes_1.TypeParameterCategory.TypeVarTuple) {
|
14207
|
-
typeVar.details.isVariadic = true;
|
14208
|
-
}
|
14209
|
-
else if (declaration.node.typeParamCategory === parseNodes_1.TypeParameterCategory.ParamSpec) {
|
14210
|
-
typeVar.details.isParamSpec = true;
|
14211
|
-
}
|
14212
|
-
if (declaration.node.boundExpression) {
|
14213
|
-
if (declaration.node.boundExpression.nodeType === 52 /* Tuple */) {
|
14214
|
-
const constraints = declaration.node.boundExpression.expressions.map((constraint) => {
|
14215
|
-
const constraintType = getTypeOfExpressionExpectingType(constraint).type;
|
14216
|
-
if ((0, typeUtils_1.requiresSpecialization)(constraintType, /* ignorePseudoGeneric */ true)) {
|
14217
|
-
addError(localize_1.Localizer.Diagnostic.typeVarBoundGeneric(), constraint);
|
14218
|
-
}
|
14219
|
-
return (0, typeUtils_1.convertToInstance)(constraintType);
|
14220
|
-
});
|
14221
|
-
if (constraints.length < 2) {
|
14222
|
-
addDiagnostic(AnalyzerNodeInfo.getFileInfo(declaration.node.boundExpression).diagnosticRuleSet
|
14223
|
-
.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeVarSingleConstraint(), declaration.node.boundExpression);
|
14224
|
-
}
|
14225
|
-
else if (declaration.node.typeParamCategory === parseNodes_1.TypeParameterCategory.TypeVar) {
|
14226
|
-
typeVar.details.constraints = constraints;
|
14227
|
-
}
|
14228
|
-
}
|
14229
|
-
else {
|
14230
|
-
const boundType = getTypeOfExpressionExpectingType(declaration.node.boundExpression).type;
|
14231
|
-
if ((0, typeUtils_1.requiresSpecialization)(boundType, /* ignorePseudoGeneric */ true)) {
|
14232
|
-
addError(localize_1.Localizer.Diagnostic.typeVarConstraintGeneric(), declaration.node.boundExpression);
|
14233
|
-
}
|
14234
|
-
if (declaration.node.typeParamCategory === parseNodes_1.TypeParameterCategory.TypeVar) {
|
14235
|
-
typeVar.details.boundType = (0, typeUtils_1.convertToInstance)(boundType);
|
14236
|
-
}
|
14237
|
-
}
|
14238
|
-
}
|
14239
|
-
if (declaration.node.defaultExpression) {
|
14240
|
-
// TODO - need to finish. For now, just evaluate the expression
|
14241
|
-
// to generate any errors.
|
14242
|
-
getTypeOfExpression(declaration.node.defaultExpression, 2097152 /* AllowUnpackedTupleOrTypeVarTuple */);
|
14243
|
-
}
|
14244
|
-
typeVar.details.isTypeParamSyntax = true;
|
14245
|
-
// Associate the type variable with the owning scope.
|
14246
|
-
const scopeNode = ParseTreeUtils.getTypeVarScopeNode(declaration.node);
|
14247
|
-
if (scopeNode) {
|
14248
|
-
let scopeType;
|
14249
|
-
if (scopeNode.nodeType === 10 /* Class */) {
|
14250
|
-
scopeType = 0 /* Class */;
|
14251
|
-
// Set the variance to "auto" for class-scoped TypeVars.
|
14252
|
-
typeVar.details.declaredVariance = 0 /* Auto */;
|
14253
|
-
}
|
14254
|
-
else if (scopeNode.nodeType === 28 /* Function */) {
|
14255
|
-
scopeType = 1 /* Function */;
|
14256
|
-
}
|
14257
|
-
else {
|
14258
|
-
(0, debug_1.assert)(scopeNode.nodeType === 77 /* TypeAlias */);
|
14259
|
-
scopeType = 2 /* TypeAlias */;
|
14260
|
-
}
|
14261
|
-
typeVar = types_1.TypeVarType.cloneForScopeId(typeVar, getScopeIdForNode(scopeNode.nodeType === 77 /* TypeAlias */ ? scopeNode.name : scopeNode), scopeNode.name.value, scopeType);
|
14262
|
-
}
|
14263
|
-
return typeVar;
|
14323
|
+
return getTypeOfTypeParameter(declaration.node);
|
14264
14324
|
}
|
14265
14325
|
case 1 /* Variable */: {
|
14266
14326
|
const typeAnnotationNode = declaration.typeAnnotationNode;
|
@@ -14305,6 +14365,99 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
14305
14365
|
}
|
14306
14366
|
}
|
14307
14367
|
}
|
14368
|
+
function getTypeOfTypeParameter(node) {
|
14369
|
+
// Is this type already cached?
|
14370
|
+
const cachedTypeVarType = readTypeCache(node.name, 0 /* None */);
|
14371
|
+
if (cachedTypeVarType && (0, types_1.isTypeVar)(cachedTypeVarType)) {
|
14372
|
+
return cachedTypeVarType;
|
14373
|
+
}
|
14374
|
+
let typeVar = types_1.TypeVarType.createInstantiable(node.name.value);
|
14375
|
+
typeVar.details.isTypeParamSyntax = true;
|
14376
|
+
if (node.typeParamCategory === parseNodes_1.TypeParameterCategory.TypeVarTuple) {
|
14377
|
+
typeVar.details.isVariadic = true;
|
14378
|
+
}
|
14379
|
+
else if (node.typeParamCategory === parseNodes_1.TypeParameterCategory.ParamSpec) {
|
14380
|
+
typeVar.details.isParamSpec = true;
|
14381
|
+
}
|
14382
|
+
// Cache the value before we evaluate the bound or the default type in
|
14383
|
+
// case it refers to itself in a circular manner.
|
14384
|
+
writeTypeCache(node, typeVar, /* flags */ undefined, /* isIncomplete */ false);
|
14385
|
+
writeTypeCache(node.name, typeVar, /* flags */ undefined, /* isIncomplete */ false);
|
14386
|
+
if (node.boundExpression) {
|
14387
|
+
if (node.boundExpression.nodeType === 52 /* Tuple */) {
|
14388
|
+
const constraints = node.boundExpression.expressions.map((constraint) => {
|
14389
|
+
const constraintType = getTypeOfExpressionExpectingType(constraint).type;
|
14390
|
+
if ((0, typeUtils_1.requiresSpecialization)(constraintType, /* ignorePseudoGeneric */ true)) {
|
14391
|
+
addError(localize_1.Localizer.Diagnostic.typeVarBoundGeneric(), constraint);
|
14392
|
+
}
|
14393
|
+
return (0, typeUtils_1.convertToInstance)(constraintType);
|
14394
|
+
});
|
14395
|
+
if (constraints.length < 2) {
|
14396
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(node.boundExpression).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeVarSingleConstraint(), node.boundExpression);
|
14397
|
+
}
|
14398
|
+
else if (node.typeParamCategory === parseNodes_1.TypeParameterCategory.TypeVar) {
|
14399
|
+
typeVar.details.constraints = constraints;
|
14400
|
+
}
|
14401
|
+
}
|
14402
|
+
else {
|
14403
|
+
const boundType = getTypeOfExpressionExpectingType(node.boundExpression).type;
|
14404
|
+
if ((0, typeUtils_1.requiresSpecialization)(boundType, /* ignorePseudoGeneric */ true)) {
|
14405
|
+
addError(localize_1.Localizer.Diagnostic.typeVarConstraintGeneric(), node.boundExpression);
|
14406
|
+
}
|
14407
|
+
if (node.typeParamCategory === parseNodes_1.TypeParameterCategory.TypeVar) {
|
14408
|
+
typeVar.details.boundType = (0, typeUtils_1.convertToInstance)(boundType);
|
14409
|
+
}
|
14410
|
+
}
|
14411
|
+
}
|
14412
|
+
if (node.defaultExpression) {
|
14413
|
+
if (node.typeParamCategory === parseNodes_1.TypeParameterCategory.ParamSpec) {
|
14414
|
+
typeVar.details.defaultType = getParamSpecDefaultType(node.defaultExpression);
|
14415
|
+
}
|
14416
|
+
else if (node.typeParamCategory === parseNodes_1.TypeParameterCategory.TypeVarTuple) {
|
14417
|
+
typeVar.details.defaultType = getTypeVarTupleDefaultType(node.defaultExpression);
|
14418
|
+
}
|
14419
|
+
else {
|
14420
|
+
typeVar.details.defaultType = (0, typeUtils_1.convertToInstance)(getTypeOfExpressionExpectingType(node.defaultExpression).type);
|
14421
|
+
}
|
14422
|
+
}
|
14423
|
+
// If a default is provided, make sure it is compatible with the bound
|
14424
|
+
// or constraint.
|
14425
|
+
if (typeVar.details.defaultType && node.defaultExpression) {
|
14426
|
+
const typeVarContext = new typeVarContext_1.TypeVarContext(types_1.WildcardTypeVarScopeId);
|
14427
|
+
const concreteDefaultType = (0, typeUtils_1.applySolvedTypeVars)(typeVar.details.defaultType, typeVarContext, {
|
14428
|
+
unknownIfNotFound: true,
|
14429
|
+
});
|
14430
|
+
if (typeVar.details.boundType) {
|
14431
|
+
if (!assignType(typeVar.details.boundType, concreteDefaultType)) {
|
14432
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeVarDefaultBoundMismatch(), node.defaultExpression);
|
14433
|
+
}
|
14434
|
+
}
|
14435
|
+
else if (typeVar.details.constraints.length > 0) {
|
14436
|
+
if (!typeVar.details.constraints.some((constraint) => (0, types_1.isTypeSame)(constraint, concreteDefaultType))) {
|
14437
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeVarDefaultConstraintMismatch(), node.defaultExpression);
|
14438
|
+
}
|
14439
|
+
}
|
14440
|
+
}
|
14441
|
+
// Associate the type variable with the owning scope.
|
14442
|
+
const scopeNode = ParseTreeUtils.getTypeVarScopeNode(node);
|
14443
|
+
if (scopeNode) {
|
14444
|
+
let scopeType;
|
14445
|
+
if (scopeNode.nodeType === 10 /* Class */) {
|
14446
|
+
scopeType = 0 /* Class */;
|
14447
|
+
// Set the variance to "auto" for class-scoped TypeVars.
|
14448
|
+
typeVar.details.declaredVariance = 0 /* Auto */;
|
14449
|
+
}
|
14450
|
+
else if (scopeNode.nodeType === 28 /* Function */) {
|
14451
|
+
scopeType = 1 /* Function */;
|
14452
|
+
}
|
14453
|
+
else {
|
14454
|
+
(0, debug_1.assert)(scopeNode.nodeType === 77 /* TypeAlias */);
|
14455
|
+
scopeType = 2 /* TypeAlias */;
|
14456
|
+
}
|
14457
|
+
typeVar = types_1.TypeVarType.cloneForScopeId(typeVar, getScopeIdForNode(scopeNode.nodeType === 77 /* TypeAlias */ ? scopeNode.name : scopeNode), scopeNode.name.value, scopeType);
|
14458
|
+
}
|
14459
|
+
return typeVar;
|
14460
|
+
}
|
14308
14461
|
function getInferredTypeOfDeclaration(symbol, decl) {
|
14309
14462
|
var _a, _b;
|
14310
14463
|
const resolvedDecl = resolveAliasDeclaration(decl,
|
@@ -15244,7 +15397,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
15244
15397
|
const removedArgs = srcTypeArgs.splice(destVariadicIndex, srcArgsToCapture);
|
15245
15398
|
// Package up the remaining type arguments into a tuple object.
|
15246
15399
|
const variadicTuple = (0, typeUtils_1.convertToInstance)((0, typeUtils_1.specializeTupleClass)(tupleClassType, removedArgs.map((typeArg) => {
|
15247
|
-
return { type:
|
15400
|
+
return { type: typeArg.type, isUnbounded: typeArg.isUnbounded };
|
15248
15401
|
}),
|
15249
15402
|
/* isTypeArgumentExplicit */ true,
|
15250
15403
|
/* isUnpackedTuple */ true));
|
@@ -15272,7 +15425,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
15272
15425
|
for (let argIndex = 0; argIndex < srcTypeArgs.length; argIndex++) {
|
15273
15426
|
const entryDiag = diag === null || diag === void 0 ? void 0 : diag.createAddendum();
|
15274
15427
|
if (!assignType(destTypeArgs[argIndex].type, srcTypeArgs[argIndex].type, entryDiag === null || entryDiag === void 0 ? void 0 : entryDiag.createAddendum(), typeVarContext,
|
15275
|
-
/* srcTypeVarContext */ undefined, flags
|
15428
|
+
/* srcTypeVarContext */ undefined, flags, recursionCount)) {
|
15276
15429
|
if (entryDiag) {
|
15277
15430
|
entryDiag.addMessage(localize_1.Localizer.DiagnosticAddendum.tupleEntryTypeMismatch().format({
|
15278
15431
|
entry: argIndex + 1,
|
@@ -15376,7 +15529,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
15376
15529
|
for (let i = 0; i < destType.details.typeParameters.length; i++) {
|
15377
15530
|
const typeArgType = i < srcTypeArgs.length ? srcTypeArgs[i] : types_1.UnknownType.create();
|
15378
15531
|
destTypeVarContext.setTypeVarType(destType.details.typeParameters[i],
|
15379
|
-
/* narrowBound */ undefined,
|
15532
|
+
/* narrowBound */ undefined,
|
15533
|
+
/* narrowBoundNoLiterals */ undefined, typeArgType);
|
15380
15534
|
}
|
15381
15535
|
}
|
15382
15536
|
return true;
|
@@ -15513,24 +15667,22 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
15513
15667
|
}
|
15514
15668
|
else {
|
15515
15669
|
// Have we already recursed once?
|
15516
|
-
if ((flags &
|
15670
|
+
if ((flags & 4 /* SkipRecursiveTypeCheck */) !== 0) {
|
15517
15671
|
return true;
|
15518
15672
|
}
|
15519
15673
|
// Note that we are comparing two recursive types and do
|
15520
15674
|
// not recursive more than once.
|
15521
|
-
flags |=
|
15675
|
+
flags |= 4 /* SkipRecursiveTypeCheck */;
|
15522
15676
|
}
|
15523
15677
|
}
|
15524
15678
|
// Transform recursive type aliases if necessary.
|
15525
15679
|
const transformedDestType = (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(destType);
|
15526
15680
|
const transformedSrcType = (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(srcType);
|
15527
|
-
// Did
|
15528
|
-
// If so, we
|
15529
|
-
//
|
15530
|
-
if (transformedDestType !== destType &&
|
15531
|
-
transformedSrcType !== srcType &&
|
15532
|
-
(0, types_1.isUnion)(transformedDestType) &&
|
15533
|
-
(0, types_1.isUnion)(transformedSrcType)) {
|
15681
|
+
// Did either the source or dest include recursive type aliases?
|
15682
|
+
// If so, we could be dealing with different recursive type aliases
|
15683
|
+
// or a recursive type alias and a recursive protocol definition.
|
15684
|
+
if ((transformedDestType !== destType && (0, types_1.isUnion)(transformedDestType)) ||
|
15685
|
+
(transformedSrcType !== srcType && (0, types_1.isUnion)(transformedSrcType))) {
|
15534
15686
|
// Use a smaller recursive limit in this case to prevent runaway recursion.
|
15535
15687
|
if (recursionCount > maxRecursiveTypeAliasRecursionCount) {
|
15536
15688
|
return true;
|
@@ -15548,9 +15700,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
15548
15700
|
if ((flags & 16 /* OverloadOverlapCheck */) !== 0) {
|
15549
15701
|
srcType = makeTopLevelTypeVarsConcrete(srcType);
|
15550
15702
|
}
|
15551
|
-
// Strip
|
15703
|
+
// Strip flags we don't want to propagate to other calls.
|
15552
15704
|
const originalFlags = flags;
|
15553
|
-
flags &= ~
|
15705
|
+
flags &= ~64 /* AllowBoolTypeGuard */;
|
15554
15706
|
// Before performing any other checks, see if the dest type is a
|
15555
15707
|
// TypeVar that we are attempting to match.
|
15556
15708
|
if ((0, types_1.isTypeVar)(destType)) {
|
@@ -15628,27 +15780,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
15628
15780
|
/* srcTypeVarContext */ undefined, originalFlags, recursionCount);
|
15629
15781
|
}
|
15630
15782
|
else {
|
15631
|
-
|
15632
|
-
// the source TypeVar. Normally we set the AllowTypeVarNarrowing flag
|
15633
|
-
// so the wide type bound of the TypeVar is set rather than the narrow
|
15634
|
-
// type bound. This allows the type to be further narrowed through other
|
15635
|
-
// assignments. However, if we're populating the expected type in the
|
15636
|
-
// TypeVarContext, we don't want to allow further narrowing.
|
15637
|
-
let effectiveFlags = originalFlags;
|
15638
|
-
if ((originalFlags & 1024 /* PopulatingExpectedType */) !== 0) {
|
15639
|
-
effectiveFlags &= ~(2 /* ReverseTypeVarMatching */ | 4 /* AllowTypeVarNarrowing */);
|
15640
|
-
}
|
15641
|
-
else {
|
15642
|
-
effectiveFlags |= 4 /* AllowTypeVarNarrowing */;
|
15643
|
-
}
|
15644
|
-
if ((0, constraintSolver_1.assignTypeToTypeVar)(evaluatorInterface, srcType, destType, diag, srcTypeVarContext, effectiveFlags, recursionCount)) {
|
15783
|
+
if ((0, constraintSolver_1.assignTypeToTypeVar)(evaluatorInterface, srcType, destType, diag, srcTypeVarContext, originalFlags, recursionCount)) {
|
15645
15784
|
return true;
|
15646
15785
|
}
|
15647
15786
|
// If the dest type is a union, only one of the subtypes needs to match.
|
15648
15787
|
let isAssignable = false;
|
15649
15788
|
if ((0, types_1.isUnion)(destType)) {
|
15650
15789
|
(0, typeUtils_1.doForEachSubtype)(destType, (destSubtype) => {
|
15651
|
-
if ((0, constraintSolver_1.assignTypeToTypeVar)(evaluatorInterface, srcType, destSubtype, diag, srcTypeVarContext, originalFlags
|
15790
|
+
if ((0, constraintSolver_1.assignTypeToTypeVar)(evaluatorInterface, srcType, destSubtype, diag, srcTypeVarContext, originalFlags, recursionCount)) {
|
15652
15791
|
isAssignable = true;
|
15653
15792
|
}
|
15654
15793
|
});
|
@@ -16015,17 +16154,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
16015
16154
|
// to eliminate as many exact type matches between the src and dest.
|
16016
16155
|
if ((0, types_1.isUnion)(destType)) {
|
16017
16156
|
// Handle the special case where the dest is a union of Any and
|
16018
|
-
// a type variable
|
16019
|
-
// in effect. This occurs, for example, with the return type of
|
16157
|
+
// a type variable. This occurs, for example, with the return type of
|
16020
16158
|
// the getattr function.
|
16021
|
-
|
16022
|
-
|
16023
|
-
|
16024
|
-
|
16025
|
-
|
16026
|
-
|
16027
|
-
return true;
|
16028
|
-
}
|
16159
|
+
const nonAnySubtypes = destType.subtypes.filter((t) => !(0, types_1.isAnyOrUnknown)(t));
|
16160
|
+
if (nonAnySubtypes.length === 1 && (0, types_1.isTypeVar)(nonAnySubtypes[0])) {
|
16161
|
+
assignType(nonAnySubtypes[0], srcType,
|
16162
|
+
/* diag */ undefined, destTypeVarContext, srcTypeVarContext, flags, recursionCount);
|
16163
|
+
// This always succeeds because the destination contains Any.
|
16164
|
+
return true;
|
16029
16165
|
}
|
16030
16166
|
const remainingDestSubtypes = [];
|
16031
16167
|
let remainingSrcSubtypes = [...srcType.subtypes];
|
@@ -16457,9 +16593,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
16457
16593
|
let specializedDestType = destType;
|
16458
16594
|
let reverseMatchingFailed = false;
|
16459
16595
|
if ((flags & 2 /* ReverseTypeVarMatching */) === 0) {
|
16460
|
-
specializedDestType = (0, typeUtils_1.applySolvedTypeVars)(destType, destTypeVarContext,
|
16461
|
-
/* unknownIfNotFound */ undefined,
|
16462
|
-
/* useNarrowBoundOnly */ true);
|
16596
|
+
specializedDestType = (0, typeUtils_1.applySolvedTypeVars)(destType, destTypeVarContext, { useNarrowBoundOnly: true });
|
16463
16597
|
if ((0, typeUtils_1.requiresSpecialization)(specializedDestType)) {
|
16464
16598
|
reverseMatchingFailed = !assignType(specializedSrcType, specializedDestType,
|
16465
16599
|
/* diag */ undefined, srcTypeVarContext, destTypeVarContext, (flags ^ 2 /* ReverseTypeVarMatching */) |
|
@@ -16469,9 +16603,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
16469
16603
|
}
|
16470
16604
|
}
|
16471
16605
|
else {
|
16472
|
-
specializedSrcType = (0, typeUtils_1.applySolvedTypeVars)(srcType, srcTypeVarContext,
|
16473
|
-
/* unknownIfNotFound */ undefined,
|
16474
|
-
/* useNarrowBoundOnly */ true);
|
16606
|
+
specializedSrcType = (0, typeUtils_1.applySolvedTypeVars)(srcType, srcTypeVarContext, { useNarrowBoundOnly: true });
|
16475
16607
|
if ((0, typeUtils_1.requiresSpecialization)(specializedSrcType)) {
|
16476
16608
|
reverseMatchingFailed = !assignType(specializedSrcType, specializedDestType,
|
16477
16609
|
/* diag */ undefined, srcTypeVarContext, destTypeVarContext, (flags ^ 2 /* ReverseTypeVarMatching */) |
|
@@ -16496,8 +16628,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
16496
16628
|
if ((0, types_1.isTypeVar)(specializedSrcType) &&
|
16497
16629
|
specializedSrcType.details.isSynthesizedSelf &&
|
16498
16630
|
specializedSrcType.details.boundType) {
|
16499
|
-
specializedSrcType = (0, typeUtils_1.applySolvedTypeVars)(specializedSrcType.details.boundType, new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(specializedSrcType)),
|
16500
|
-
/* unknownIfNotFound */ true);
|
16631
|
+
specializedSrcType = (0, typeUtils_1.applySolvedTypeVars)(specializedSrcType.details.boundType, new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(specializedSrcType)), { unknownIfNotFound: true });
|
16501
16632
|
}
|
16502
16633
|
}
|
16503
16634
|
if (!assignType(specializedSrcType, specializedDestType, diag === null || diag === void 0 ? void 0 : diag.createAddendum(), srcTypeVarContext, destTypeVarContext, flags, recursionCount)) {
|
@@ -16895,18 +17026,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
16895
17026
|
assignType(typeVarEntry.typeVar, effectiveSrcTypeVarContext.getTypeVarType(typeVarEntry.typeVar),
|
16896
17027
|
/* diag */ undefined, destTypeVarContext, srcTypeVarContext, 0 /* Default */, recursionCount);
|
16897
17028
|
});
|
16898
|
-
// Perform partial specialization of type variables to allow for
|
16899
|
-
// "higher-order" type variables.
|
16900
|
-
if (!destTypeVarContext.isLocked()) {
|
16901
|
-
destTypeVarContext.getTypeVars().forEach((entry) => {
|
16902
|
-
if (entry.narrowBound) {
|
16903
|
-
const specializedType = (0, typeUtils_1.applySolvedTypeVars)(entry.narrowBound, destTypeVarContext);
|
16904
|
-
if (specializedType !== entry.narrowBound) {
|
16905
|
-
destTypeVarContext.setTypeVarType(entry.typeVar, specializedType, entry.wideBound, entry.retainLiteral);
|
16906
|
-
}
|
16907
|
-
}
|
16908
|
-
});
|
16909
|
-
}
|
16910
17029
|
// Are we assigning to a function with a ParamSpec?
|
16911
17030
|
if (targetIncludesParamSpec) {
|
16912
17031
|
const effectiveDestType = (flags & 2 /* ReverseTypeVarMatching */) === 0 ? destType : srcType;
|
@@ -17030,6 +17149,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
17030
17149
|
}
|
17031
17150
|
}
|
17032
17151
|
}
|
17152
|
+
// Apply any solved source TypeVars to the dest TypeVar solutions. This
|
17153
|
+
// allows for higher-order functions to accept generic callbacks.
|
17154
|
+
destTypeVarContext.applySourceContextTypeVars(srcTypeVarContext);
|
17033
17155
|
return canAssign;
|
17034
17156
|
}
|
17035
17157
|
// If the declaredType contains type arguments that are "Any" and
|
@@ -17191,9 +17313,23 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
17191
17313
|
// Verify that the positional param count matches exactly or that the override
|
17192
17314
|
// adds only params that preserve the original signature.
|
17193
17315
|
let foundParamCountMismatch = false;
|
17194
|
-
if (overrideParamDetails.positionParamCount < baseParamDetails.positionParamCount
|
17195
|
-
overrideParamDetails.argsIndex === undefined) {
|
17196
|
-
|
17316
|
+
if (overrideParamDetails.positionParamCount < baseParamDetails.positionParamCount) {
|
17317
|
+
if (overrideParamDetails.argsIndex === undefined) {
|
17318
|
+
foundParamCountMismatch = true;
|
17319
|
+
}
|
17320
|
+
else {
|
17321
|
+
const overrideArgsType = overrideParamDetails.params[overrideParamDetails.argsIndex].type;
|
17322
|
+
for (let i = overrideParamDetails.positionParamCount; i < baseParamDetails.positionParamCount; i++) {
|
17323
|
+
if (!assignType(overrideArgsType, baseParamDetails.params[i].type, diag === null || diag === void 0 ? void 0 : diag.createAddendum(), new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(overrideMethod)), new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(baseMethod)), 8 /* SkipSolveTypeVars */)) {
|
17324
|
+
localize_1.Localizer.DiagnosticAddendum.overrideParamType().format({
|
17325
|
+
index: i + 1,
|
17326
|
+
baseType: printType(baseParamDetails.params[i].type),
|
17327
|
+
overrideType: printType(overrideArgsType),
|
17328
|
+
});
|
17329
|
+
canOverride = false;
|
17330
|
+
}
|
17331
|
+
}
|
17332
|
+
}
|
17197
17333
|
}
|
17198
17334
|
else if (overrideParamDetails.positionParamCount > baseParamDetails.positionParamCount) {
|
17199
17335
|
// Verify that all of the override parameters that extend the
|