8000 Simplified recursion check in TypeVar transform logic. · sourcegraph/scip-python@98de6ee · GitHub
[go: up one dir, main page]

Skip to content

Commit 98de6ee

Browse files
committed
Simplified recursion check in TypeVar transform logic.
1 parent b54a5c8 commit 98de6ee

File tree

1 file changed

+27
-35
lines changed

1 file changed

+27
-35
lines changed

packages/pyright-internal/src/analyzer/typeUtils.ts

Lines changed: 27 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2443,14 +2443,15 @@ export function convertParamSpecValueToType(paramSpecEntry: ParamSpecValue, omit
24432443
// it to be replaced with something else.
24442444
class TypeVarTransformer {
24452445
private _isTransformingTypeArg = false;
2446+
private _pendingTypeVarTransformations = new Set<string>();
24462447

2447-
apply(type: Type, recursionSet = new Set<string>(), recursionCount = 0): Type {
2448+
apply(type: Type, recursionCount = 0): Type {
24482449
if (recursionCount > maxTypeRecursionCount) {
24492450
return type;
24502451
}
24512452
recursionCount++;
24522453

2453-
type = this._transformGenericTypeAlias(type, recursionSet, recursionCount);
2454+
type = this._transformGenericTypeAlias(type, recursionCount);
24542455

24552456
// Shortcut the operation if possible.
24562457
if (!requiresSpecialization(type)) {
@@ -2476,7 +2477,7 @@ class TypeVarTransformer {
24762477

24772478
let requiresUpdate = false;
24782479
const typeArgs = type.typeAliasInfo.typeArguments.map((typeArg) => {
2479-
const replacementType = this.apply(typeArg, recursionSet, recursionCount);
2480+
const replacementType = this.apply(typeArg, recursionCount);
24802481
if (replacementType !== typeArg) {
24812482
requiresUpdate = true;
24822483
}
@@ -2500,15 +2501,16 @@ class TypeVarTransformer {
25002501
let replacementType: Type = type;
25012502

25022503
// Recursively transform the results, but ensure that we don't replace the
2503-
// same type variable recursively by setting it in the recursionSet.
2504+
// same type variable recursively by setting it in the
2505+
// _pendingTypeVarTransformations set.
25042506
const typeVarName = TypeVarType.getNameWithScope(type);
2505-
if (!recursionSet.has(typeVarName)) {
2507+
if (!this._pendingTypeVarTransformations.has(typeVarName)) {
25062508
replacementType = this.transformTypeVar(type);
25072509

25082510
if (!this._isTransformingTypeArg) {
2509-
recursionSet.add(typeVarName);
2510-
replacementType = this.apply(replacementType, recursionSet, recursionCount);
2511-
recursionSet.delete(typeVarName);
2511+
this._pendingTypeVarTransformations.add(typeVarName);
2512+
replacementType = this.apply(replacementType, recursionCount);
2513+
this._pendingTypeVarTransformations.delete(typeVarName);
25122514
}
25132515

25142516
// If we're transforming a variadic type variable that was in a union,
@@ -2523,7 +2525,7 @@ class TypeVarTransformer {
25232525

25242526
if (isUnion(type)) {
25252527
const newUnionType = mapSubtypes(type, (subtype) => {
2526-
let transformedType = this.apply(subtype, recursionSet, recursionCount);
2528+
let transformedType = this.apply(subtype, recursionCount);
25272529

25282530
// If we're transforming a variadic type variable within a union,
25292531
// combine the individual types within the variadic type variable.
@@ -2547,11 +2549,11 @@ class TypeVarTransformer {
25472549
}
25482550

25492551
if (isClass(type)) {
2550-
return this._transformTypeVarsInClassType(type, recursionSet, recursionCount);
2552+
return this._transformTypeVarsInClassType(type, recursionCount);
25512553
}
25522554

25532555
if (isFunction(type)) {
2554-
return this._transformTypeVarsInFunctionType(type, recursionSet, recursionCount);
2556+
return this._transformTypeVarsInFunctionType(type, recursionCount);
25552557
}
25562558

25572559
if (isOverloadedFunction(type)) {
@@ -2560,7 +2562,7 @@ class TypeVarTransformer {
25602562
// Specialize each of the functions in the overload.
25612563
const newOverloads: FunctionType[] = [];
25622564
type.overloads.forEach((entry) => {
2563-
const replacementType = this._transformTypeVarsInFunctionType(entry, recursionSet, recursionCount);
2565+
const replacementType = this._transformTypeVarsInFunctionType(entry, recursionCount);
25642566
newOverloads.push(replacementType);
25652567
if (replacementType !== entry) {
25662568
requiresUpdate = true;
@@ -2590,14 +2592,14 @@ class TypeVarTransformer {
25902592
return type;
25912593
}
25922594

2593-
private _transformGenericTypeAlias(type: Type, recursionSet: Set<string>, recursionCount: number) {
2595+
private _transformGenericTypeAlias(type: Type, recursionCount: number) {
25942596
if (!type.typeAliasInfo || !type.typeAliasInfo.typeParameters || !type.typeAliasInfo.typeArguments) {
25952597
return type;
25962598
}
25972599

25982600
let requiresUpdate = false;
25992601
const newTypeArgs = type.typeAliasInfo.typeArguments.map((typeArg) => {
2600-
const updatedType = this.apply(typeArg, recursionSet, recursionCount);
2602+
const updatedType = this.apply(typeArg, recursionCount);
26012603
if (type !== updatedType) {
26022604
requiresUpdate = true;
26032605
}
@@ -2616,11 +2618,7 @@ class TypeVarTransformer {
26162618
: type;
26172619
}
26182620

2619-
private _transformTypeVarsInClassType(
2620-
classType: ClassType,
2621-
recursionSet: Set<string>,
2622-
recursionCount: number
2623-
): ClassType {
2621+
private _transformTypeVarsInClassType(classType: ClassType, recursionCount: number): ClassType {
26242622
// Handle the common case where the class has no type parameters.
26252623
if (ClassType.getTypeParameters(classType).length === 0 && !ClassType.isSpecialBuiltIn(classType)) {
26262624
return classType;
@@ -2651,7 +2649,7 @@ class TypeVarTransformer {
26512649
return transformParamSpec(oldTypeArgType);
26522650
}
26532651

2654-
let newTypeArgType = this.apply(oldTypeArgType, recursionSet, recursionCount);
2652+
let newTypeArgType = this.apply(oldTypeArgType, recursionCount);
26552653
if (newTypeArgType !== oldTypeArgType) {
26562654
specializationNeeded = true;
26572655

@@ -2678,14 +2676,14 @@ class TypeVarTransformer {
26782676
}
26792677
} else {
26802678
const typeParamName = TypeVarType.getNameWithScope(typeParam);
2681-
if (!recursionSet.has(typeParamName)) {
2679+
if (!this._pendingTypeVarTransformations.has(typeParamName)) {
26822680
replacementType = this.transformTypeVar(typeParam);
26832681

26842682
if (replacementType !== typeParam) {
26852683
if (!this._isTransformingTypeArg) {
2686-
recursionSet.add(typeParamName);
2687-
replacementType = this.apply(replacementType, recursionSet, recursionCount);
2688-
recursionSet.delete(typeParamName);
2684+
this._pendingTypeVarTransformations.add(typeParamName);
2685+
replacementType = this.apply(replacementType, recursionCount);
2686+
this._pendingTypeVarTransformations.delete(typeParamName);
26892687
}
26902688

26912689
specializationNeeded = true;
@@ -2701,7 +2699,7 @@ class TypeVarTransformer {
27012699
if (classType.tupleTypeArguments) {
27022700
newVariadicTypeArgs = [];
27032701
classType.tupleTypeArguments.forEach((oldTypeArgType) => {
2704-
const newTypeArgType = this.apply(oldTypeArgType.type, recursionSet, recursionCount);
2702+
const newTypeArgType = this.apply(oldTypeArgType.type, recursionCount);
27052703

27062704
if (newTypeArgType !== oldTypeArgType.type) {
27072705
specializationNeeded = true;
@@ -2742,11 +2740,7 @@ class TypeVarTransformer {
27422740
);
27432741
}
27442742

2745-
private _transformTypeVarsInFunctionType(
2746-
sourceType: FunctionType,
2747-
recursionSet: Set<string>,
2748-
recursionCount: number
2749-
): FunctionType {
2743+
private _transformTypeVarsInFunctionType(sourceType: FunctionType, recursionCount: number): FunctionType {
27502744
let functionType = sourceType;
27512745

27522746
// Handle functions with a parameter specification in a special manner.
@@ -2758,9 +2752,7 @@ class TypeVarTransformer {
27582752
}
27592753

27602754
const declaredReturnType = FunctionType.getSpecializedReturnType(functionType);
2761-
const specializedReturnType = declaredReturnType
2762-
? this.apply(declaredReturnType, recursionSet, recursionCount)
2763-
: undefined;
2755+
const specializedReturnType = declaredReturnType ? this.apply(declaredReturnType, recursionCount) : undefined;
27642756
let typesRequiredSpecialization = declaredReturnType !== specializedReturnType;
27652757

27662758
const specializedParameters: SpecializedFunctionTypes = {
@@ -2808,7 +2800,7 @@ class TypeVarTransformer {
28082800

28092801
for (let i = 0; i < functionType.details.parameters.length; i++) {
28102802
const paramType = FunctionType.getEffectiveParameterType(functionType, i);
2811-
const specializedType = this.apply(paramType, recursionSet, recursionCount);
2803+
const specializedType = this.apply(paramType, recursionCount);
28122804
specializedParameters.parameterTypes.push(specializedType);
28132805
if (
28142806
variadicParamIndex === undefined &&
@@ -2833,7 +2825,7 @@ class TypeVarTransformer {
28332825

28342826
let specializedInferredReturnType: Type | undefined;
28352827
if (functionType.inferredReturnType) {
2836-
specializedInferredReturnType = this.apply(functionType.inferredReturnType, recursionSet, recursionCount);
2828+
specializedInferredReturnType = this.apply(functionType.inferredReturnType, recursionCount);
28372829
}
28382830

28392831
// If there was no unpacked variadic type variable, we're done.

0 commit comments

Comments
 (0)
0