@zzzen/pyright-internal 1.2.0-dev.20221225 → 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 +5 -3
- package/dist/analyzer/binder.js.map +1 -1
- package/dist/analyzer/codeFlowEngine.d.ts +16 -1
- package/dist/analyzer/codeFlowEngine.js +17 -9
- package/dist/analyzer/codeFlowEngine.js.map +1 -1
- package/dist/analyzer/constraintSolver.js +30 -31
- 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/sourceFile.js +1 -0
- package/dist/analyzer/sourceFile.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 +447 -281
- 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 +12 -3
- package/dist/analyzer/typeUtils.js +283 -134
- package/dist/analyzer/typeUtils.js.map +1 -1
- package/dist/analyzer/typeVarContext.d.ts +2 -10
- package/dist/analyzer/typeVarContext.js +12 -31
- 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 +7 -1
- package/dist/parser/parser.js +3 -1
- package/dist/parser/parser.js.map +1 -1
- package/dist/tests/typeEvaluator2.test.js +1 -1
- package/dist/tests/typeEvaluator3.test.js +5 -1
- 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 +1 -1
- 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) {
|
@@ -2758,7 +2746,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
2758
2746
|
return undefined;
|
2759
2747
|
}
|
2760
2748
|
function getTypeOfName(node, flags) {
|
2761
|
-
var _a
|
2749
|
+
var _a;
|
2762
2750
|
const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
|
2763
2751
|
const name = node.value;
|
2764
2752
|
let symbol;
|
@@ -2769,7 +2757,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
2769
2757
|
const typeParamSymbol = AnalyzerNodeInfo.getTypeParameterSymbol(node);
|
2770
2758
|
if (typeParamSymbol) {
|
2771
2759
|
symbol = typeParamSymbol;
|
2772
|
-
|
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);
|
2773
2764
|
setSymbolAccessed(fileInfo, symbol, node);
|
2774
2765
|
}
|
2775
2766
|
else {
|
@@ -2910,7 +2901,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
2910
2901
|
type.details.name === name) {
|
2911
2902
|
// Handle the special case of a PEP 604 union. These can appear within
|
2912
2903
|
// an implied type alias where we are not expecting a type.
|
2913
|
-
const isPep604Union = ((
|
2904
|
+
const isPep604Union = ((_a = node.parent) === null || _a === void 0 ? void 0 : _a.nodeType) === 7 /* BinaryOperation */ &&
|
2914
2905
|
node.parent.operator === 6 /* BitwiseOr */;
|
2915
2906
|
if (!isPep604Union) {
|
2916
2907
|
// A TypeVar in contexts where we're not expecting a type is
|
@@ -3026,7 +3017,15 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3026
3017
|
if (memberName === 'args' || memberName === 'kwargs') {
|
3027
3018
|
const outerFunctionScope = ParseTreeUtils.getEnclosingClassOrFunction(enclosingScope);
|
3028
3019
|
if ((outerFunctionScope === null || outerFunctionScope === void 0 ? void 0 : outerFunctionScope.nodeType) === 28 /* Function */) {
|
3029
|
-
|
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
|
+
}
|
3030
3029
|
}
|
3031
3030
|
else if (!scopedTypeVarInfo.type.scopeId) {
|
3032
3031
|
addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.paramSpecNotUsedByOuterScope().format({
|
@@ -3060,9 +3059,17 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3060
3059
|
else if ((flags & 4096 /* DisallowTypeVarsWithoutScopeId */) !== 0) {
|
3061
3060
|
if ((type.scopeId === undefined || scopedTypeVarInfo.foundInterveningClass) &&
|
3062
3061
|
!type.details.isSynthesized) {
|
3063
|
-
|
3064
|
-
|
3065
|
-
|
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
|
+
}
|
3066
3073
|
addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, message.format({ name: type.details.name }), node);
|
3067
3074
|
}
|
3068
3075
|
}
|
@@ -3078,43 +3085,51 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3078
3085
|
// type arguments. If so, it fills in these type arguments with Unknown
|
3079
3086
|
// and optionally reports an error.
|
3080
3087
|
function reportMissingTypeArguments(node, type, flags) {
|
3081
|
-
if ((flags & 2 /* DoNotSpecialize */)
|
3082
|
-
|
3083
|
-
|
3084
|
-
|
3085
|
-
|
3086
|
-
|
3087
|
-
|
3088
|
-
|
3089
|
-
|
3090
|
-
|
3091
|
-
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);
|
3092
3098
|
}
|
3093
3099
|
}
|
3094
|
-
if (
|
3095
|
-
type
|
3096
|
-
|
3097
|
-
|
3098
|
-
|
3099
|
-
|
3100
|
-
|
3101
|
-
|
3102
|
-
|
3103
|
-
|
3104
|
-
|
3105
|
-
|
3106
|
-
|
3107
|
-
|
3108
|
-
|
3109
|
-
|
3110
|
-
|
3111
|
-
|
3112
|
-
|
3113
|
-
|
3114
|
-
|
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();
|
3115
3123
|
}
|
3116
|
-
|
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);
|
3117
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);
|
3118
3133
|
}
|
3119
3134
|
return type;
|
3120
3135
|
}
|
@@ -3148,8 +3163,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3148
3163
|
return scopeIds;
|
3149
3164
|
}
|
3150
3165
|
// Walks up the parse tree to find a function, class, or type alias
|
3151
|
-
//
|
3166
|
+
// declaration that provides the context for a type variable.
|
3152
3167
|
function findScopedTypeVar(node, type) {
|
3168
|
+
var _a;
|
3153
3169
|
let curNode = node;
|
3154
3170
|
let nestedClassCount = 0;
|
3155
3171
|
(0, debug_1.assert)(types_1.TypeBase.isInstantiable(type));
|
@@ -3171,14 +3187,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3171
3187
|
else if (curNode.nodeType === 28 /* Function */) {
|
3172
3188
|
const functionTypeInfo = getTypeOfFunction(curNode);
|
3173
3189
|
if (functionTypeInfo) {
|
3174
|
-
|
3175
|
-
|
3176
|
-
|
3177
|
-
|
3178
|
-
|
3179
|
-
|
3180
|
-
|
3181
|
-
(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 };
|
3182
3197
|
}
|
3183
3198
|
}
|
3184
3199
|
scopeUsesTypeParameterSyntax = !!curNode.typeParameters;
|
@@ -3191,7 +3206,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3191
3206
|
if (match === null || match === void 0 ? void 0 : match.scopeId) {
|
3192
3207
|
// Use the scoped version of the TypeVar rather than the (unscoped) original type.
|
3193
3208
|
type = types_1.TypeVarType.cloneForScopeId(type, match.scopeId, match.scopeName, match.scopeType);
|
3194
|
-
return {
|
3209
|
+
return {
|
3210
|
+
type,
|
3211
|
+
isRescoped: false,
|
3212
|
+
foundInterveningClass: nestedClassCount > 1 && !scopeUsesTypeParameterSyntax,
|
3213
|
+
};
|
3195
3214
|
}
|
3196
3215
|
}
|
3197
3216
|
curNode = curNode.parent;
|
@@ -3224,6 +3243,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3224
3243
|
}
|
3225
3244
|
return {
|
3226
3245
|
type: types_1.TypeVarType.cloneForScopeId(type, leftType.details.recursiveTypeAliasScopeId, leftType.details.recursiveTypeAliasName, 2 /* TypeAlias */),
|
3246
|
+
isRescoped: false,
|
3227
3247
|
foundInterveningClass: false,
|
3228
3248
|
};
|
3229
3249
|
}
|
@@ -3231,7 +3251,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3231
3251
|
curNode = curNode.parent;
|
3232
3252
|
}
|
3233
3253
|
// Return the original type.
|
3234
|
-
return { type, foundInterveningClass: false };
|
3254
|
+
return { type, isRescoped: false, foundInterveningClass: false };
|
3235
3255
|
}
|
3236
3256
|
function getTypeOfMemberAccess(node, flags) {
|
3237
3257
|
const baseTypeFlags = 2 /* DoNotSpecialize */ |
|
@@ -4205,12 +4225,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4205
4225
|
}
|
4206
4226
|
return indexTypeResult;
|
4207
4227
|
}
|
4208
|
-
function adjustTypeArgumentsForVariadicTypeVar(typeArgs, typeParameters, errorNode) {
|
4209
|
-
var _a;
|
4228
|
+
function adjustTypeArgumentsForVariadicTypeVar(typeArgs, typeParameters, typeVarScopeId, errorNode) {
|
4210
4229
|
const variadicIndex = typeParameters.findIndex((param) => (0, types_1.isVariadicTypeVar)(param));
|
4211
4230
|
// Do we need to adjust the type arguments to map to a variadic type
|
4212
4231
|
// param at the end of the list?
|
4213
4232
|
if (variadicIndex >= 0) {
|
4233
|
+
const variadicTypeVar = typeParameters[variadicIndex];
|
4214
4234
|
if (tupleClassType && (0, types_1.isInstantiableClass)(tupleClassType)) {
|
4215
4235
|
if (variadicIndex < typeArgs.length) {
|
4216
4236
|
const variadicTypeResults = typeArgs.slice(variadicIndex, variadicIndex + 1 + typeArgs.length - typeParameters.length);
|
@@ -4250,11 +4270,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4250
4270
|
];
|
4251
4271
|
}
|
4252
4272
|
}
|
4253
|
-
else {
|
4273
|
+
else if (!variadicTypeVar.details.defaultType) {
|
4254
4274
|
// Add an empty tuple that maps to the TypeVarTuple type parameter.
|
4255
4275
|
typeArgs.push({
|
4256
4276
|
node: errorNode,
|
4257
|
-
type: (
|
4277
|
+
type: (0, typeUtils_1.convertToInstance)((0, typeUtils_1.specializeTupleClass)(tupleClassType, [],
|
4258
4278
|
/* isTypeArgumentExplicit */ true,
|
4259
4279
|
/* isUnpackedTuple */ true)),
|
4260
4280
|
});
|
@@ -4291,7 +4311,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4291
4311
|
return undefined;
|
4292
4312
|
}
|
4293
4313
|
const typeParameters = baseType.typeAliasInfo.typeParameters;
|
4294
|
-
let typeArgs = adjustTypeArgumentsForVariadicTypeVar(getTypeArgs(node, flags), typeParameters, node);
|
4314
|
+
let typeArgs = adjustTypeArgumentsForVariadicTypeVar(getTypeArgs(node, flags), typeParameters, baseType.typeAliasInfo.typeVarScopeId, node);
|
4295
4315
|
// PEP 612 says that if the class has only one type parameter consisting
|
4296
4316
|
// of a ParamSpec, the list of arguments does not need to be enclosed in
|
4297
4317
|
// a list. We'll handle that case specially here. Presumably this applies to
|
@@ -4324,7 +4344,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4324
4344
|
const typeVarContext = new typeVarContext_1.TypeVarContext(baseType.typeAliasInfo.typeVarScopeId);
|
4325
4345
|
const diag = new diagnostic_1.DiagnosticAddendum();
|
4326
4346
|
typeParameters.forEach((param, index) => {
|
4327
|
-
var _a;
|
4328
4347
|
if (param.details.isParamSpec && index < typeArgs.length) {
|
4329
4348
|
const typeArgType = typeArgs[index].type;
|
4330
4349
|
if (typeArgs[index].typeList) {
|
@@ -4387,9 +4406,16 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4387
4406
|
if (index < typeArgs.length && typeArgs[index].typeList) {
|
4388
4407
|
addError(localize_1.Localizer.Diagnostic.typeArgListNotAllowed(), typeArgs[index].node);
|
4389
4408
|
}
|
4390
|
-
|
4391
|
-
|
4392
|
-
|
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
|
+
}
|
4393
4419
|
(0, constraintSolver_1.assignTypeToTypeVar)(evaluatorInterface, param, typeArgType, diag, typeVarContext, 128 /* RetainLiteralsForTypeVar */);
|
4394
4420
|
}
|
4395
4421
|
});
|
@@ -4400,8 +4426,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4400
4426
|
(_b = baseType.typeAliasInfo.typeParameters) === null || _b === void 0 ? void 0 : _b.forEach((typeParam) => {
|
4401
4427
|
let typeVarType;
|
4402
4428
|
if ((0, types_1.isParamSpec)(typeParam)) {
|
4403
|
-
const
|
4404
|
-
typeVarType =
|
4429
|
+
const paramSpecType = typeVarContext.getParamSpecType(typeParam);
|
4430
|
+
typeVarType = paramSpecType ? (0, typeUtils_1.convertParamSpecValueToType)(paramSpecType) : types_1.UnknownType.create();
|
4405
4431
|
}
|
4406
4432
|
else {
|
4407
4433
|
typeVarType = typeVarContext.getTypeVarType(typeParam);
|
@@ -4425,7 +4451,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4425
4451
|
let isIncomplete = baseTypeResult.isIncomplete;
|
4426
4452
|
const type = mapSubtypesExpandTypeVars(baseTypeResult.type,
|
4427
4453
|
/* conditionFilter */ undefined, (concreteSubtype, unexpandedSubtype) => {
|
4428
|
-
var _a;
|
4454
|
+
var _a, _b;
|
4429
4455
|
if ((0, types_1.isAnyOrUnknown)(concreteSubtype)) {
|
4430
4456
|
return concreteSubtype;
|
4431
4457
|
}
|
@@ -4492,7 +4518,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4492
4518
|
const isClassVarAnnotation = (0, types_1.isInstantiableClass)(concreteSubtype) && types_1.ClassType.isBuiltIn(concreteSubtype, 'ClassVar');
|
4493
4519
|
let typeArgs = getTypeArgs(node, flags, isAnnotatedClass, hasCustomClassGetItem || !isGenericClass, isFinalAnnotation, isClassVarAnnotation);
|
4494
4520
|
if (!isAnnotatedClass) {
|
4495
|
-
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);
|
4496
4522
|
}
|
4497
4523
|
// If this is a custom __class_getitem__, there's no need to specialize the class.
|
4498
4524
|
// Just return it as is.
|
@@ -4950,6 +4976,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4950
4976
|
}
|
4951
4977
|
const entryTypeResults = node.expressions.map((expr, index) => getTypeOfExpression(expr,
|
4952
4978
|
/* flags */ undefined, index < expectedTypes.length ? expectedTypes[index] : undefined));
|
4979
|
+
const isIncomplete = entryTypeResults.some((result) => result.isIncomplete);
|
4953
4980
|
const type = (0, typeUtils_1.convertToInstance)((0, typeUtils_1.specializeTupleClass)(tupleClassType, buildTupleTypesList(entryTypeResults),
|
4954
4981
|
/* isTypeArgumentExplicit */ true));
|
4955
4982
|
// Copy any expected type diag addenda for precision error reporting.
|
@@ -4962,7 +4989,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4962
4989
|
}
|
4963
4990
|
});
|
4964
4991
|
}
|
4965
|
-
return { type, expectedTypeDiagAddendum };
|
4992
|
+
return { type, expectedTypeDiagAddendum, isIncomplete };
|
4966
4993
|
}
|
4967
4994
|
function getTypeOfTupleInferred(node) {
|
4968
4995
|
const entryTypeResults = node.expressions.map((expr) => getTypeOfExpression(expr));
|
@@ -5949,7 +5976,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5949
5976
|
unsolvedTypeVarsAreUnknown = false;
|
5950
5977
|
}
|
5951
5978
|
}
|
5952
|
-
const specializedType = (0, typeUtils_1.applySolvedTypeVars)(type, typeVarContext,
|
5979
|
+
const specializedType = (0, typeUtils_1.applySolvedTypeVars)(type, typeVarContext, {
|
5980
|
+
unknownIfNotFound: unsolvedTypeVarsAreUnknown,
|
5981
|
+
});
|
5953
5982
|
return types_1.ClassType.cloneAsInstance(specializedType);
|
5954
5983
|
}
|
5955
5984
|
// Similar to applyExpectedTypeForConstructor, this function handles the
|
@@ -7334,15 +7363,17 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7334
7363
|
// the call below to adjustCallableReturnType will "detach" these
|
7335
7364
|
// TypeVars from the scope of this function and "attach" them to
|
7336
7365
|
// the scope of the callable.
|
7337
|
-
let
|
7366
|
+
let unknownIfNotFound = !(0, types_1.isFunction)(returnType);
|
7338
7367
|
// We'll also leave TypeVars unsolved if the call is a recursive
|
7339
7368
|
// call to a generic function.
|
7340
7369
|
const typeVarScopes = getTypeVarScopesForNode(errorNode);
|
7341
7370
|
if (typeVarScopes.some((typeVarScope) => typeVarContext.hasSolveForScope(typeVarScope))) {
|
7342
|
-
|
7371
|
+
unknownIfNotFound = false;
|
7343
7372
|
}
|
7344
|
-
let specializedReturnType = (0, typeUtils_1.addConditionToType)((0, typeUtils_1.applySolvedTypeVars)(returnType, typeVarContext,
|
7345
|
-
|
7373
|
+
let specializedReturnType = (0, typeUtils_1.addConditionToType)((0, typeUtils_1.applySolvedTypeVars)(returnType, typeVarContext, {
|
7374
|
+
unknownIfNotFound,
|
7375
|
+
eliminateUnsolvedInUnions,
|
7376
|
+
}), typeCondition);
|
7346
7377
|
// If the final return type is an unpacked tuple, turn it into a normal (unpacked) tuple.
|
7347
7378
|
if ((0, types_1.isUnpackedClass)(specializedReturnType)) {
|
7348
7379
|
specializedReturnType = types_1.ClassType.cloneForUnpacked(specializedReturnType, /* isUnpackedTuple */ false);
|
@@ -7409,16 +7440,16 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7409
7440
|
// signature bound to the specified ParamSpec. Return value indicates success.
|
7410
7441
|
function validateFunctionArgumentsForParamSpec(errorNode, argList, paramSpec, destTypeVarContext, conditionFilter) {
|
7411
7442
|
var _a;
|
7412
|
-
const
|
7413
|
-
|
7414
|
-
if (!paramSpecValue) {
|
7443
|
+
const paramSpecType = destTypeVarContext.getParamSpecType(paramSpec);
|
7444
|
+
if (!paramSpecType) {
|
7415
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);
|
7416
7446
|
return false;
|
7417
7447
|
}
|
7448
|
+
const srcTypeVarContext = new typeVarContext_1.TypeVarContext(paramSpecType.details.typeVarScopeId);
|
7418
7449
|
let reportedArgError = false;
|
7419
7450
|
// Build a map of all named parameters.
|
7420
7451
|
const paramMap = new Map();
|
7421
|
-
const paramSpecParams =
|
7452
|
+
const paramSpecParams = paramSpecType.details.parameters;
|
7422
7453
|
paramSpecParams.forEach((param) => {
|
7423
7454
|
if (param.name) {
|
7424
7455
|
paramMap.set(param.name, param);
|
@@ -7499,7 +7530,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7499
7530
|
const paramInfo = paramMap.get(name);
|
7500
7531
|
return paramInfo.category === 0 /* Simple */ && !paramInfo.hasDefault;
|
7501
7532
|
});
|
7502
|
-
if (unassignedParams.length > 0 && !
|
7533
|
+
if (unassignedParams.length > 0 && !paramSpecType.details.paramSpec) {
|
7503
7534
|
const missingParamNames = unassignedParams.map((p) => `"${p}"`).join(', ');
|
7504
7535
|
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, unassignedParams.length === 1
|
7505
7536
|
? localize_1.Localizer.Diagnostic.argMissingForParam().format({ name: missingParamNames })
|
@@ -7531,8 +7562,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7531
7562
|
functionType !== undefined &&
|
7532
7563
|
argParam.paramType.scopeId === functionType.details.typeVarScopeId
|
7533
7564
|
? undefined
|
7534
|
-
: (0, typeUtils_1.applySolvedTypeVars)(argParam.paramType, typeVarContext,
|
7535
|
-
/* unknownIfNotFound */ false, useNarrowBoundOnly);
|
7565
|
+
: (0, typeUtils_1.applySolvedTypeVars)(argParam.paramType, typeVarContext, { useNarrowBoundOnly });
|
7536
7566
|
// If the expected type is unknown, don't use an expected type. Instead,
|
7537
7567
|
// use default rules for evaluating the expression type.
|
7538
7568
|
if (expectedType && (0, types_1.isUnknown)(expectedType)) {
|
@@ -7851,8 +7881,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7851
7881
|
// or constraint.
|
7852
7882
|
if (typeVar.details.defaultType && defaultValueNode) {
|
7853
7883
|
const typeVarContext = new typeVarContext_1.TypeVarContext(types_1.WildcardTypeVarScopeId);
|
7854
|
-
const concreteDefaultType = (0, typeUtils_1.applySolvedTypeVars)(typeVar.details.defaultType, typeVarContext,
|
7855
|
-
|
7884
|
+
const concreteDefaultType = makeTopLevelTypeVarsConcrete((0, typeUtils_1.applySolvedTypeVars)(typeVar.details.defaultType, typeVarContext, {
|
7885
|
+
unknownIfNotFound: true,
|
7886
|
+
}));
|
7856
7887
|
if (typeVar.details.boundType) {
|
7857
7888
|
if (!assignType(typeVar.details.boundType, concreteDefaultType)) {
|
7858
7889
|
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeVarDefaultBoundMismatch(), defaultValueNode);
|
@@ -8011,62 +8042,67 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8011
8042
|
// in the Python specification: The static type checker will treat
|
8012
8043
|
// the new type as if it were a subclass of the original type.
|
8013
8044
|
function createNewType(errorNode, argList) {
|
8045
|
+
var _a;
|
8014
8046
|
const fileInfo = AnalyzerNodeInfo.getFileInfo(errorNode);
|
8015
|
-
let className = '
|
8016
|
-
if (argList.length
|
8017
|
-
|
8018
|
-
|
8019
|
-
|
8020
|
-
|
8021
|
-
|
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
|
-
classType
|
8065
|
-
|
8066
|
-
}
|
8067
|
-
|
8068
|
-
|
8069
|
-
|
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);
|
8070
8106
|
}
|
8071
8107
|
return undefined;
|
8072
8108
|
}
|
@@ -10371,7 +10407,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10371
10407
|
}
|
10372
10408
|
return createSpecialType(classType, typeArgs, /* paramLimit */ undefined, /* allowParamSpec */ true);
|
10373
10409
|
}
|
10374
|
-
function transformTypeForTypeAlias(type, name, errorNode, typeParameters) {
|
10410
|
+
function transformTypeForTypeAlias(type, name, errorNode, typeParameters, typeParamNodes) {
|
10375
10411
|
if (!types_1.TypeBase.isInstantiable(type)) {
|
10376
10412
|
return type;
|
10377
10413
|
}
|
@@ -10400,6 +10436,15 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10400
10436
|
}
|
10401
10437
|
return (0, typeUtils_1.convertToInstance)(typeVar);
|
10402
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
|
+
});
|
10403
10448
|
// Verify that we have at most one variadic type variable.
|
10404
10449
|
const variadics = typeParameters.filter((param) => (0, types_1.isVariadicTypeVar)(param));
|
10405
10450
|
if (variadics.length > 1) {
|
@@ -10741,6 +10786,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10741
10786
|
// path does not handle traditional type aliases, which are treated as
|
10742
10787
|
// variables since they use normal variable assignment syntax.
|
10743
10788
|
function getTypeOfTypeAlias(node) {
|
10789
|
+
var _a;
|
10744
10790
|
const cachedType = readTypeCache(node.name, 0 /* None */);
|
10745
10791
|
if (cachedType) {
|
10746
10792
|
return cachedType;
|
@@ -10778,7 +10824,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10778
10824
|
}
|
10779
10825
|
// Clear the temporary type we wrote above.
|
10780
10826
|
deleteTypeCacheEntry(node.name);
|
10781
|
-
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);
|
10782
10828
|
if ((0, typeUtils_1.isTypeAliasRecursive)(typeAliasTypeVar, aliasType)) {
|
10783
10829
|
addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeAliasIsRecursiveDirect().format({
|
10784
10830
|
name: node.name.value,
|
@@ -11096,6 +11142,16 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11096
11142
|
names: variadics.map((v) => `"${v.details.name}"`).join(', '),
|
11097
11143
|
}), node.name, textRange_1.TextRange.combine(node.arguments) || node.name);
|
11098
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
|
+
});
|
11099
11155
|
if (!(0, typeUtils_1.computeMroLinearization)(classType)) {
|
11100
11156
|
addError(localize_1.Localizer.Diagnostic.methodOrdering(), node.name);
|
11101
11157
|
}
|
@@ -11284,6 +11340,34 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11284
11340
|
}
|
11285
11341
|
return { classType, decoratedType };
|
11286
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
|
+
}
|
11287
11371
|
function inferTypeParameterVarianceForClass(classType) {
|
11288
11372
|
if (!classType.details.requiresVarianceInference) {
|
11289
11373
|
return;
|
@@ -11590,6 +11674,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11590
11674
|
});
|
11591
11675
|
}
|
11592
11676
|
function getTypeOfFunction(node) {
|
11677
|
+
var _a, _b;
|
11593
11678
|
const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
|
11594
11679
|
// Is this type already cached?
|
11595
11680
|
const cachedFunctionType = readTypeCache(node.name, 0 /* None */);
|
@@ -11689,8 +11774,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11689
11774
|
}), node.functionAnnotationComment);
|
11690
11775
|
}
|
11691
11776
|
}
|
11777
|
+
// If this function uses PEP 695 syntax for type parameters,
|
11778
|
+
// accumulate the list of type parameters upfront.
|
11779
|
+
const typeParametersSeen = [];
|
11692
11780
|
if (node.typeParameters) {
|
11693
|
-
evaluateTypeParameterList(node.typeParameters);
|
11781
|
+
functionType.details.typeParameters = evaluateTypeParameterList(node.typeParameters);
|
11782
|
+
}
|
11783
|
+
else {
|
11784
|
+
functionType.details.typeParameters = typeParametersSeen;
|
11694
11785
|
}
|
11695
11786
|
const markParamAccessed = (param) => {
|
11696
11787
|
if (param.name) {
|
@@ -11838,6 +11929,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11838
11929
|
isTypeInferred,
|
11839
11930
|
};
|
11840
11931
|
types_1.FunctionType.addParameter(functionType, functionParam);
|
11932
|
+
if (functionParam.hasDeclaredType) {
|
11933
|
+
(0, typeUtils_1.addTypeVarsToListIfUnique)(typeParametersSeen, (0, typeUtils_1.getTypeVarArgumentsRecursive)(functionParam.type));
|
11934
|
+
}
|
11841
11935
|
if (param.name) {
|
11842
11936
|
const variadicParamType = transformVariadicParamType(node, param.category, functionParam.type);
|
11843
11937
|
paramTypes.push(variadicParamType);
|
@@ -11878,19 +11972,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11878
11972
|
// If there was a defined return type, analyze that first so when we
|
11879
11973
|
// walk the contents of the function, return statements can be
|
11880
11974
|
// validated against this type.
|
11881
|
-
|
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) {
|
11882
11977
|
// Temporarily set the return type to unknown in case of recursion.
|
11883
11978
|
functionType.details.declaredReturnType = types_1.UnknownType.create();
|
11884
|
-
const returnType = getTypeOfAnnotation(
|
11885
|
-
associateTypeVarsWithScope: true,
|
11886
|
-
disallowRecursiveTypeAlias: true,
|
11887
|
-
});
|
11888
|
-
functionType.details.declaredReturnType = returnType;
|
11889
|
-
}
|
11890
|
-
else if (node.functionAnnotationComment) {
|
11891
|
-
// Temporarily set the return type to unknown in case of recursion.
|
11892
|
-
functionType.details.declaredReturnType = types_1.UnknownType.create();
|
11893
|
-
const returnType = getTypeOfAnnotation(node.functionAnnotationComment.returnTypeAnnotation, {
|
11979
|
+
const returnType = getTypeOfAnnotation(returnTypeAnnotationNode, {
|
11894
11980
|
associateTypeVarsWithScope: true,
|
11895
11981
|
disallowRecursiveTypeAlias: true,
|
11896
11982
|
});
|
@@ -11911,6 +11997,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11911
11997
|
}
|
11912
11998
|
}
|
11913
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
|
+
}
|
11914
12004
|
// If the return type is explicitly annotated as a generator, mark the
|
11915
12005
|
// function as a generator even though it may not contain a "yield" statement.
|
11916
12006
|
// This is important for generator functions declared in stub files, abstract
|
@@ -11926,6 +12016,16 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11926
12016
|
functionType.details.flags |= 16 /* Generator */;
|
11927
12017
|
}
|
11928
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
|
+
});
|
11929
12029
|
// Clear the "partially evaluated" flag to indicate that the functionType
|
11930
12030
|
// is fully evaluated.
|
11931
12031
|
functionType.details.flags &= ~131072 /* PartiallyEvaluated */;
|
@@ -11963,6 +12063,37 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11963
12063
|
writeTypeCache(node, decoratedType, 0 /* None */, /* isIncomplete */ false);
|
11964
12064
|
return { functionType, decoratedType };
|
11965
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
|
+
}
|
11966
12097
|
function adjustParameterAnnotatedType(param, type) {
|
11967
12098
|
var _a;
|
11968
12099
|
// PEP 484 indicates that if a parameter has a default value of 'None'
|
@@ -13311,36 +13442,16 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13311
13442
|
// within that tree. If the type cannot be determined (because it's part
|
13312
13443
|
// of a cyclical dependency), the function returns undefined.
|
13313
13444
|
function evaluateTypeForSubnode(subnode, callback) {
|
13314
|
-
// If the type cache is already populated
|
13315
|
-
// doing additional work.
|
13316
|
-
let
|
13317
|
-
if (
|
13318
|
-
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 };
|
13319
13450
|
}
|
13320
|
-
|
13321
|
-
|
13322
|
-
|
13323
|
-
|
13324
|
-
// abandon it once the last nested call completes.
|
13325
|
-
if (!incompleteTypeCache) {
|
13326
|
-
incompleteTypeCache = new Map();
|
13327
|
-
}
|
13328
|
-
callback();
|
13329
|
-
subnodeType = readTypeCache(subnode, /* flags */ undefined);
|
13330
|
-
if (subnodeType) {
|
13331
|
-
return { type: subnodeType };
|
13332
|
-
}
|
13333
|
-
subnodeType = incompleteTypeCache.get(subnode.id);
|
13334
|
-
if (subnodeType) {
|
13335
|
-
return { type: subnodeType, isIncomplete: true };
|
13336
|
-
}
|
13337
|
-
incompleteTypeCache = oldIncompleteCache;
|
13338
|
-
}
|
13339
|
-
catch (e) {
|
13340
|
-
// We don't use a finally clause here because the debugger doesn't
|
13341
|
-
// handle it well when stepping through code.
|
13342
|
-
incompleteTypeCache = oldIncompleteCache;
|
13343
|
-
throw e;
|
13451
|
+
callback();
|
13452
|
+
cacheEntry = readTypeCacheEntry(subnode);
|
13453
|
+
if (cacheEntry) {
|
13454
|
+
return { type: cacheEntry.type, isIncomplete: cacheEntry.isIncomplete };
|
13344
13455
|
}
|
13345
13456
|
return undefined;
|
13346
13457
|
}
|
@@ -13605,8 +13716,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13605
13716
|
}
|
13606
13717
|
}
|
13607
13718
|
}
|
13719
|
+
const typeVarContext = new typeVarContext_1.TypeVarContext(classType.details.typeVarScopeId);
|
13608
13720
|
fullTypeParams.forEach((typeParam, index) => {
|
13609
|
-
var _a;
|
13610
13721
|
if (typeArgs && index < typeArgs.length) {
|
13611
13722
|
if (typeParam.details.isParamSpec) {
|
13612
13723
|
const typeArg = typeArgs[index];
|
@@ -13616,6 +13727,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13616
13727
|
types_1.FunctionType.addDefaultParameters(functionType);
|
13617
13728
|
functionType.details.flags |= 32768 /* SkipArgsKwargsCompatibilityCheck */;
|
13618
13729
|
typeArgTypes.push(functionType);
|
13730
|
+
typeVarContext.setTypeVarType(typeParam, (0, typeUtils_1.convertTypeToParamSpecValue)(functionType));
|
13619
13731
|
return;
|
13620
13732
|
}
|
13621
13733
|
if (typeArg.typeList) {
|
@@ -13629,6 +13741,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13629
13741
|
});
|
13630
13742
|
});
|
13631
13743
|
typeArgTypes.push(functionType);
|
13744
|
+
typeVarContext.setTypeVarType(typeParam, (0, typeUtils_1.convertTypeToParamSpecValue)(functionType));
|
13632
13745
|
return;
|
13633
13746
|
}
|
13634
13747
|
if ((0, types_1.isInstantiableClass)(typeArg.type) && types_1.ClassType.isBuiltIn(typeArg.type, 'Concatenate')) {
|
@@ -13655,10 +13768,19 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13655
13768
|
return;
|
13656
13769
|
}
|
13657
13770
|
}
|
13658
|
-
|
13771
|
+
const typeArgType = (0, typeUtils_1.convertToInstance)(typeArgs[index].type);
|
13772
|
+
typeArgTypes.push(typeArgType);
|
13773
|
+
typeVarContext.setTypeVarType(typeParam, typeArgType);
|
13659
13774
|
return;
|
13660
13775
|
}
|
13661
|
-
|
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
|
+
}
|
13662
13784
|
});
|
13663
13785
|
typeArgTypes = typeArgTypes.map((typeArgType, index) => {
|
13664
13786
|
if (index < typeArgCount) {
|
@@ -14198,65 +14320,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
14198
14320
|
return undefined;
|
14199
14321
|
}
|
14200
14322
|
case 3 /* TypeParameter */: {
|
14201
|
-
|
14202
|
-
if (declaration.node.typeParamCategory === parseNodes_1.TypeParameterCategory.TypeVarTuple) {
|
14203
|
-
typeVar.details.isVariadic = true;
|
14204
|
-
}
|
14205
|
-
else if (declaration.node.typeParamCategory === parseNodes_1.TypeParameterCategory.ParamSpec) {
|
14206
|
-
typeVar.details.isParamSpec = true;
|
14207
|
-
}
|
14208
|
-
if (declaration.node.boundExpression) {
|
14209
|
-
if (declaration.node.boundExpression.nodeType === 52 /* Tuple */) {
|
14210
|
-
const constraints = declaration.node.boundExpression.expressions.map((constraint) => {
|
14211
|
-
const constraintType = getTypeOfExpressionExpectingType(constraint).type;
|
14212
|
-
if ((0, typeUtils_1.requiresSpecialization)(constraintType, /* ignorePseudoGeneric */ true)) {
|
14213
|
-
addError(localize_1.Localizer.Diagnostic.typeVarBoundGeneric(), constraint);
|
14214
|
-
}
|
14215
|
-
return (0, typeUtils_1.convertToInstance)(constraintType);
|
14216
|
-
});
|
14217
|
-
if (constraints.length < 2) {
|
14218
|
-
addDiagnostic(AnalyzerNodeInfo.getFileInfo(declaration.node.boundExpression).diagnosticRuleSet
|
14219
|
-
.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeVarSingleConstraint(), declaration.node.boundExpression);
|
14220
|
-
}
|
14221
|
-
else if (declaration.node.typeParamCategory === parseNodes_1.TypeParameterCategory.TypeVar) {
|
14222
|
-
typeVar.details.constraints = constraints;
|
14223
|
-
}
|
14224
|
-
}
|
14225
|
-
else {
|
14226
|
-
const boundType = getTypeOfExpressionExpectingType(declaration.node.boundExpression).type;
|
14227
|
-
if ((0, typeUtils_1.requiresSpecialization)(boundType, /* ignorePseudoGeneric */ true)) {
|
14228
|
-
addError(localize_1.Localizer.Diagnostic.typeVarConstraintGeneric(), declaration.node.boundExpression);
|
14229
|
-
}
|
14230
|
-
if (declaration.node.typeParamCategory === parseNodes_1.TypeParameterCategory.TypeVar) {
|
14231
|
-
typeVar.details.boundType = (0, typeUtils_1.convertToInstance)(boundType);
|
14232
|
-
}
|
14233
|
-
}
|
14234
|
-
}
|
14235
|
-
if (declaration.node.defaultExpression) {
|
14236
|
-
// TODO - need to finish. For now, just evaluate the expression
|
14237
|
-
// to generate any errors.
|
14238
|
-
getTypeOfExpression(declaration.node.defaultExpression, 2097152 /* AllowUnpackedTupleOrTypeVarTuple */);
|
14239
|
-
}
|
14240
|
-
typeVar.details.isTypeParamSyntax = true;
|
14241
|
-
// Associate the type variable with the owning scope.
|
14242
|
-
const scopeNode = ParseTreeUtils.getTypeVarScopeNode(declaration.node);
|
14243
|
-
if (scopeNode) {
|
14244
|
-
let scopeType;
|
14245
|
-
if (scopeNode.nodeType === 10 /* Class */) {
|
14246
|
-
scopeType = 0 /* Class */;
|
14247
|
-
// Set the variance to "auto" for class-scoped TypeVars.
|
14248
|
-
typeVar.details.declaredVariance = 0 /* Auto */;
|
14249
|
-
}
|
14250
|
-
else if (scopeNode.nodeType === 28 /* Function */) {
|
14251
|
-
scopeType = 1 /* Function */;
|
14252
|
-
}
|
14253
|
-
else {
|
14254
|
-
(0, debug_1.assert)(scopeNode.nodeType === 77 /* TypeAlias */);
|
14255
|
-
scopeType = 2 /* TypeAlias */;
|
14256
|
-
}
|
14257
|
-
typeVar = types_1.TypeVarType.cloneForScopeId(typeVar, getScopeIdForNode(scopeNode.nodeType === 77 /* TypeAlias */ ? scopeNode.name : scopeNode), scopeNode.name.value, scopeType);
|
14258
|
-
}
|
14259
|
-
return typeVar;
|
14323
|
+
return getTypeOfTypeParameter(declaration.node);
|
14260
14324
|
}
|
14261
14325
|
case 1 /* Variable */: {
|
14262
14326
|
const typeAnnotationNode = declaration.typeAnnotationNode;
|
@@ -14301,6 +14365,99 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
14301
14365
|
}
|
14302
14366
|
}
|
14303
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
|
+
}
|
14304
14461
|
function getInferredTypeOfDeclaration(symbol, decl) {
|
14305
14462
|
var _a, _b;
|
14306
14463
|
const resolvedDecl = resolveAliasDeclaration(decl,
|
@@ -16436,9 +16593,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
16436
16593
|
let specializedDestType = destType;
|
16437
16594
|
let reverseMatchingFailed = false;
|
16438
16595
|
if ((flags & 2 /* ReverseTypeVarMatching */) === 0) {
|
16439
|
-
specializedDestType = (0, typeUtils_1.applySolvedTypeVars)(destType, destTypeVarContext,
|
16440
|
-
/* unknownIfNotFound */ undefined,
|
16441
|
-
/* useNarrowBoundOnly */ true);
|
16596
|
+
specializedDestType = (0, typeUtils_1.applySolvedTypeVars)(destType, destTypeVarContext, { useNarrowBoundOnly: true });
|
16442
16597
|
if ((0, typeUtils_1.requiresSpecialization)(specializedDestType)) {
|
16443
16598
|
reverseMatchingFailed = !assignType(specializedSrcType, specializedDestType,
|
16444
16599
|
/* diag */ undefined, srcTypeVarContext, destTypeVarContext, (flags ^ 2 /* ReverseTypeVarMatching */) |
|
@@ -16448,9 +16603,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
16448
16603
|
}
|
16449
16604
|
}
|
16450
16605
|
else {
|
16451
|
-
specializedSrcType = (0, typeUtils_1.applySolvedTypeVars)(srcType, srcTypeVarContext,
|
16452
|
-
/* unknownIfNotFound */ undefined,
|
16453
|
-
/* useNarrowBoundOnly */ true);
|
16606
|
+
specializedSrcType = (0, typeUtils_1.applySolvedTypeVars)(srcType, srcTypeVarContext, { useNarrowBoundOnly: true });
|
16454
16607
|
if ((0, typeUtils_1.requiresSpecialization)(specializedSrcType)) {
|
16455
16608
|
reverseMatchingFailed = !assignType(specializedSrcType, specializedDestType,
|
16456
16609
|
/* diag */ undefined, srcTypeVarContext, destTypeVarContext, (flags ^ 2 /* ReverseTypeVarMatching */) |
|
@@ -16475,8 +16628,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
16475
16628
|
if ((0, types_1.isTypeVar)(specializedSrcType) &&
|
16476
16629
|
specializedSrcType.details.isSynthesizedSelf &&
|
16477
16630
|
specializedSrcType.details.boundType) {
|
16478
|
-
specializedSrcType = (0, typeUtils_1.applySolvedTypeVars)(specializedSrcType.details.boundType, new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(specializedSrcType)),
|
16479
|
-
/* unknownIfNotFound */ true);
|
16631
|
+
specializedSrcType = (0, typeUtils_1.applySolvedTypeVars)(specializedSrcType.details.boundType, new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(specializedSrcType)), { unknownIfNotFound: true });
|
16480
16632
|
}
|
16481
16633
|
}
|
16482
16634
|
if (!assignType(specializedSrcType, specializedDestType, diag === null || diag === void 0 ? void 0 : diag.createAddendum(), srcTypeVarContext, destTypeVarContext, flags, recursionCount)) {
|
@@ -17161,9 +17313,23 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
17161
17313
|
// Verify that the positional param count matches exactly or that the override
|
17162
17314
|
// adds only params that preserve the original signature.
|
17163
17315
|
let foundParamCountMismatch = false;
|
17164
|
-
if (overrideParamDetails.positionParamCount < baseParamDetails.positionParamCount
|
17165
|
-
overrideParamDetails.argsIndex === undefined) {
|
17166
|
-
|
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
|
+
}
|
17167
17333
|
}
|
17168
17334
|
else if (overrideParamDetails.positionParamCount > baseParamDetails.positionParamCount) {
|
17169
17335
|
// Verify that all of the override parameters that extend the
|