Did more code cleanup in the assignment statement evaluation code path.

This commit is contained in:
Eric Traut 2024-07-01 20:50:20 -07:00
parent 3da465b321
commit 2947be68bf

View File

@ -16147,14 +16147,13 @@ export function createTypeEvaluator(
let isSpeculativeTypeAlias = false; let isSpeculativeTypeAlias = false;
if (isDeclaredTypeAlias(node.leftExpression)) { if (isDeclaredTypeAlias(node.leftExpression)) {
flags |= flags =
EvaluatorFlags.ExpectingInstantiableType | EvaluatorFlags.ExpectingInstantiableType |
EvaluatorFlags.ExpectingTypeAnnotation | EvaluatorFlags.ExpectingTypeAnnotation |
EvaluatorFlags.EvaluateStringLiteralAsType | EvaluatorFlags.EvaluateStringLiteralAsType |
EvaluatorFlags.DisallowParamSpec | EvaluatorFlags.DisallowParamSpec |
EvaluatorFlags.DisallowTypeVarTuple | EvaluatorFlags.DisallowTypeVarTuple |
EvaluatorFlags.DisallowClassVar; EvaluatorFlags.DisallowClassVar;
flags &= ~EvaluatorFlags.DoNotSpecialize;
typeAliasNameNode = (node.leftExpression as TypeAnnotationNode).valueExpression as NameNode; typeAliasNameNode = (node.leftExpression as TypeAnnotationNode).valueExpression as NameNode;
@ -16174,60 +16173,56 @@ export function createTypeEvaluator(
if (symbolWithScope) { if (symbolWithScope) {
const decls = symbolWithScope.symbol.getDeclarations(); const decls = symbolWithScope.symbol.getDeclarations();
if (decls.length === 1 && isPossibleTypeAliasOrTypedDict(decls[0])) {
if (decls.length === 1) {
if (isPossibleTypeAliasDeclaration(decls[0])) {
typeAliasNameNode = node.leftExpression; typeAliasNameNode = node.leftExpression;
isSpeculativeTypeAlias = true; isSpeculativeTypeAlias = true;
} else if (isPossibleTypeDictFactoryCall(decls[0])) {
// Handle calls to TypedDict factory functions like type
// aliases to support recursive field type definitions.
typeAliasNameNode = node.leftExpression;
}
} }
} }
} }
// Synthesize a type variable that represents the type alias while we're // Synthesize a type variable that represents the type alias while we're
// evaluating it. This allows us to handle recursive definitions. // evaluating it. This allows us to handle recursive definitions.
let typeAliasTypeVar: TypeVarType | undefined; let typeAliasPlaceholder: TypeVarType | undefined;
if (typeAliasNameNode) { if (typeAliasNameNode) {
typeAliasTypeVar = synthesizeTypeAliasPlaceholder(typeAliasNameNode); typeAliasPlaceholder = synthesizeTypeAliasPlaceholder(typeAliasNameNode);
// Write the type to the type cache to support recursive type alias definitions. // Write the type to the type cache to support recursive type alias definitions.
writeTypeCache(node, { type: typeAliasTypeVar }, /* flags */ undefined); writeTypeCache(node, { type: typeAliasPlaceholder }, /* flags */ undefined);
writeTypeCache(node.leftExpression, { type: typeAliasTypeVar }, /* flags */ undefined); writeTypeCache(node.leftExpression, { type: typeAliasPlaceholder }, /* flags */ undefined);
if (node.leftExpression.nodeType === ParseNodeType.TypeAnnotation) { if (node.leftExpression.nodeType === ParseNodeType.TypeAnnotation) {
writeTypeCache( writeTypeCache(
node.leftExpression.valueExpression, node.leftExpression.valueExpression,
{ type: typeAliasTypeVar }, { type: typeAliasPlaceholder },
/* flags */ undefined /* flags */ undefined
); );
} }
} }
const srcTypeResult = getTypeOfExpression(node.rightExpression, flags, makeInferenceContext(declaredType)); const srcTypeResult = getTypeOfExpression(node.rightExpression, flags, makeInferenceContext(declaredType));
let srcType = srcTypeResult.type;
rightHandType = srcTypeResult.type;
expectedTypeDiagAddendum = srcTypeResult.expectedTypeDiagAddendum; expectedTypeDiagAddendum = srcTypeResult.expectedTypeDiagAddendum;
if (srcTypeResult.isIncomplete) { if (srcTypeResult.isIncomplete) {
isIncomplete = true; isIncomplete = true;
} }
// If the RHS is a constant boolean expression, assign it a literal type.
const constExprValue = evaluateStaticBoolExpression(
node.rightExpression,
fileInfo.executionEnvironment,
fileInfo.definedConstants
);
if (constExprValue !== undefined) {
const boolType = getBuiltInObject(node, 'bool');
if (isClassInstance(boolType)) {
srcType = ClassType.cloneWithLiteral(boolType, constExprValue);
}
}
// If this is an enum, transform the type as required.
rightHandType = srcType;
if (typeAliasNameNode) {
// If this was a speculative type alias, it becomes a real type alias // If this was a speculative type alias, it becomes a real type alias
// only if the evaluated type is an instantiable type. // only if the evaluated type is an instantiable type.
if (!isSpeculativeTypeAlias || isLegalImplicitTypeAliasType(rightHandType)) { if (isSpeculativeTypeAlias && !isLegalImplicitTypeAliasType(rightHandType)) {
typeAliasNameNode = undefined;
}
if (typeAliasNameNode) {
assert(typeAliasPlaceholder !== undefined);
// If this is a type alias, record its name based on the assignment target. // If this is a type alias, record its name based on the assignment target.
rightHandType = transformTypeForTypeAlias( rightHandType = transformTypeForTypeAlias(
rightHandType, rightHandType,
@ -16237,8 +16232,7 @@ export function createTypeEvaluator(
/* isPep695TypeVarType */ false /* isPep695TypeVarType */ false
); );
assert(typeAliasTypeVar !== undefined); if (isTypeAliasRecursive(typeAliasPlaceholder, rightHandType)) {
if (isTypeAliasRecursive(typeAliasTypeVar, rightHandType)) {
addDiagnostic( addDiagnostic(
DiagnosticRule.reportGeneralTypeIssues, DiagnosticRule.reportGeneralTypeIssues,
LocMessage.typeAliasIsRecursiveDirect().format({ LocMessage.typeAliasIsRecursiveDirect().format({
@ -16252,11 +16246,24 @@ export function createTypeEvaluator(
// Set the resulting type to the boundType of the original type alias // Set the resulting type to the boundType of the original type alias
// to support recursive type aliases. // to support recursive type aliases.
typeAliasTypeVar.details.boundType = rightHandType; typeAliasPlaceholder.details.boundType = rightHandType;
// Record the type parameters within the recursive type alias so it // Record the type parameters within the recursive type alias so it
// can be specialized. // can be specialized.
typeAliasTypeVar.details.recursiveTypeParameters = rightHandType.typeAliasInfo?.typeParameters; typeAliasPlaceholder.details.recursiveTypeParameters = rightHandType.typeAliasInfo?.typeParameters;
} else {
// If the RHS is a constant boolean expression, assign it a literal type.
const constExprValue = evaluateStaticBoolExpression(
node.rightExpression,
fileInfo.executionEnvironment,
fileInfo.definedConstants
);
if (constExprValue !== undefined) {
const boolType = getBuiltInObject(node, 'bool');
if (isClassInstance(boolType)) {
rightHandType = ClassType.cloneWithLiteral(boolType, constExprValue);
}
} }
} }
} }