Skip to content

Commit e4bb5b6

Browse files
chloestefantsovaCommit Queue
authored and
Commit Queue
committed
[cfe] Use exhaustive switch in findTypeArgumentsIssues
This will allow to detect unhandled types statically. The opportunity for the improvement was spotted while working on https://dart-review.googlesource.com/c/sdk/+/312264 Change-Id: Ie39f48833be4d0f9f65a14e58f42843cc49c8fa5 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/330424 Reviewed-by: Johnni Winther <[email protected]> Commit-Queue: Chloe Stefantsova <[email protected]>
1 parent c658b46 commit e4bb5b6

File tree

1 file changed

+55
-65
lines changed

1 file changed

+55
-65
lines changed

pkg/kernel/lib/src/bounds_checks.dart

Lines changed: 55 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -336,68 +336,67 @@ List<TypeArgumentIssue> findTypeArgumentIssues(DartType type,
336336
{required bool allowSuperBounded,
337337
required bool isNonNullableByDefault,
338338
required bool areGenericArgumentsAllowed}) {
339-
List<TypeParameter> variables = const <TypeParameter>[];
340-
List<DartType> arguments = const <DartType>[];
341-
List<TypeArgumentIssue> typedefRhsResult = const <TypeArgumentIssue>[];
342-
343-
if (type is InterfaceType) {
344-
variables = type.classNode.typeParameters;
345-
arguments = type.typeArguments;
346-
} else if (type is TypedefType) {
347-
variables = type.typedefNode.typeParameters;
348-
arguments = type.typeArguments;
349-
} else if (type is ExtensionType) {
350-
variables = type.extensionTypeDeclaration.typeParameters;
351-
arguments = type.typeArguments;
352-
// Extension types are never allowed to be super-bounded.
353-
allowSuperBounded = false;
354-
} else if (type is FunctionType) {
355-
List<TypeArgumentIssue> result = <TypeArgumentIssue>[];
356-
357-
for (DartType formal in type.positionalParameters) {
358-
result.addAll(findTypeArgumentIssues(
359-
formal, typeEnvironment, subtypeCheckMode,
360-
allowSuperBounded: true,
361-
isNonNullableByDefault: isNonNullableByDefault,
362-
areGenericArgumentsAllowed: areGenericArgumentsAllowed));
363-
}
364-
365-
for (NamedType named in type.namedParameters) {
366-
result.addAll(findTypeArgumentIssues(
367-
named.type, typeEnvironment, subtypeCheckMode,
368-
allowSuperBounded: true,
369-
isNonNullableByDefault: isNonNullableByDefault,
370-
areGenericArgumentsAllowed: areGenericArgumentsAllowed));
371-
}
372-
373-
result.addAll(findTypeArgumentIssues(
374-
type.returnType, typeEnvironment, subtypeCheckMode,
375-
allowSuperBounded: true,
376-
isNonNullableByDefault: isNonNullableByDefault,
377-
areGenericArgumentsAllowed: areGenericArgumentsAllowed));
378-
379-
return result;
380-
} else if (type is FutureOrType) {
381-
variables = typeEnvironment.coreTypes.futureClass.typeParameters;
382-
arguments = <DartType>[type.typeArgument];
383-
} else {
384-
assert(type is DynamicType ||
385-
type is VoidType ||
386-
type is IntersectionType ||
387-
type is TypeParameterType ||
388-
type is NeverType ||
389-
type is NullType);
390-
return const <TypeArgumentIssue>[];
339+
List<TypeParameter> variables;
340+
List<DartType> arguments;
341+
342+
switch (type) {
343+
case InterfaceType(:var classNode, :var typeArguments):
344+
variables = classNode.typeParameters;
345+
arguments = typeArguments;
346+
case TypedefType(:var typedefNode, :var typeArguments):
347+
variables = typedefNode.typeParameters;
348+
arguments = typeArguments;
349+
case ExtensionType(:var extensionTypeDeclaration, :var typeArguments):
350+
variables = extensionTypeDeclaration.typeParameters;
351+
arguments = typeArguments;
352+
// Extension types are never allowed to be super-bounded.
353+
allowSuperBounded = false;
354+
case FunctionType(
355+
:var positionalParameters,
356+
:var namedParameters,
357+
:var returnType
358+
):
359+
return <TypeArgumentIssue>[
360+
for (DartType formal in positionalParameters)
361+
...findTypeArgumentIssues(formal, typeEnvironment, subtypeCheckMode,
362+
allowSuperBounded: true,
363+
isNonNullableByDefault: isNonNullableByDefault,
364+
areGenericArgumentsAllowed: areGenericArgumentsAllowed),
365+
for (NamedType named in namedParameters)
366+
...findTypeArgumentIssues(
367+
named.type, typeEnvironment, subtypeCheckMode,
368+
allowSuperBounded: true,
369+
isNonNullableByDefault: isNonNullableByDefault,
370+
areGenericArgumentsAllowed: areGenericArgumentsAllowed),
371+
...findTypeArgumentIssues(returnType, typeEnvironment, subtypeCheckMode,
372+
allowSuperBounded: true,
373+
isNonNullableByDefault: isNonNullableByDefault,
374+
areGenericArgumentsAllowed: areGenericArgumentsAllowed)
375+
];
376+
case FutureOrType(:var typeArgument):
377+
variables = typeEnvironment.coreTypes.futureClass.typeParameters;
378+
arguments = <DartType>[typeArgument];
379+
case DynamicType():
380+
case VoidType():
381+
case IntersectionType():
382+
case TypeParameterType():
383+
case StructuralParameterType():
384+
case NeverType():
385+
case NullType():
386+
case RecordType():
387+
return const <TypeArgumentIssue>[];
388+
case AuxiliaryType():
389+
throw new StateError("AuxiliaryType");
390+
case InvalidType():
391+
// Assuming the error is reported elsewhere.
392+
throw const <TypeArgumentIssue>[];
391393
}
392394

393395
if (variables.isEmpty) {
394-
return typedefRhsResult.isNotEmpty
395-
? typedefRhsResult
396-
: const <TypeArgumentIssue>[];
396+
return const <TypeArgumentIssue>[];
397397
}
398398

399399
List<TypeArgumentIssue> result = <TypeArgumentIssue>[];
400-
List<TypeArgumentIssue> argumentsResult = <TypeArgumentIssue>[];
401400

402401
Substitution substitution = Substitution.fromPairs(variables, arguments);
403402
for (int i = 0; i < arguments.length; ++i) {
@@ -419,8 +418,6 @@ List<TypeArgumentIssue> findTypeArgumentIssues(DartType type,
419418
// reported already at the time of the creation of InvalidType.
420419
}
421420
}
422-
result.addAll(argumentsResult);
423-
result.addAll(typedefRhsResult);
424421

425422
// [type] is regular-bounded.
426423
if (result.isEmpty) return const <TypeArgumentIssue>[];
@@ -460,13 +457,6 @@ List<TypeArgumentIssue> findTypeArgumentIssues(DartType type,
460457
isCorrectSuperBounded = false;
461458
}
462459
}
463-
if (argumentsResult.isNotEmpty) {
464-
isCorrectSuperBounded = false;
465-
}
466-
if (typedefRhsResult.isNotEmpty) {
467-
isCorrectSuperBounded = false;
468-
}
469-
470460
// The inverted type is regular-bounded, which means that [type] is
471461
// well-bounded.
472462
if (isCorrectSuperBounded) return const <TypeArgumentIssue>[];

0 commit comments

Comments
 (0)