mirror of
https://github.com/dart-lang/sdk
synced 2024-09-06 00:59:09 +00:00
Stop using 'Element.type' in ErrorVerifier.
Change-Id: I8313bccb7bf302fd80fa2da1e5256e1e40998fa8 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/119041 Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
This commit is contained in:
parent
1707aff921
commit
402951b399
|
@ -9,6 +9,7 @@ import 'package:analyzer/dart/ast/ast.dart';
|
|||
import 'package:analyzer/dart/ast/token.dart';
|
||||
import 'package:analyzer/dart/ast/visitor.dart';
|
||||
import 'package:analyzer/dart/element/element.dart';
|
||||
import 'package:analyzer/dart/element/nullability_suffix.dart';
|
||||
import 'package:analyzer/dart/element/type.dart';
|
||||
import 'package:analyzer/dart/element/visitor.dart';
|
||||
import 'package:analyzer/error/error.dart';
|
||||
|
@ -1378,7 +1379,6 @@ class ErrorVerifier extends RecursiveAstVisitor<void> {
|
|||
void visitTypeParameter(TypeParameter node) {
|
||||
_checkForBuiltInIdentifierAsName(node.name,
|
||||
CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME);
|
||||
_checkForTypeParameterSupertypeOfItsBound(node);
|
||||
_checkForTypeAnnotationDeferredClass(node.bound);
|
||||
_checkForImplicitDynamicType(node.bound);
|
||||
_checkForGenericFunctionType(node.bound);
|
||||
|
@ -1389,6 +1389,7 @@ class ErrorVerifier extends RecursiveAstVisitor<void> {
|
|||
@override
|
||||
void visitTypeParameterList(TypeParameterList node) {
|
||||
_duplicateDefinitionVerifier.checkTypeParameters(node);
|
||||
_checkForTypeParameterBoundRecursion(node.typeParameters);
|
||||
super.visitTypeParameterList(node);
|
||||
}
|
||||
|
||||
|
@ -3114,20 +3115,23 @@ class ErrorVerifier extends RecursiveAstVisitor<void> {
|
|||
if (_enclosingFunction.isAsynchronous) {
|
||||
if (_enclosingFunction.isGenerator) {
|
||||
_checkForIllegalReturnTypeCode(
|
||||
returnType,
|
||||
_typeProvider.streamDynamicType,
|
||||
StaticTypeWarningCode.ILLEGAL_ASYNC_GENERATOR_RETURN_TYPE);
|
||||
returnType,
|
||||
_typeProvider.streamElement,
|
||||
StaticTypeWarningCode.ILLEGAL_ASYNC_GENERATOR_RETURN_TYPE,
|
||||
);
|
||||
} else {
|
||||
_checkForIllegalReturnTypeCode(
|
||||
returnType,
|
||||
_typeProvider.futureDynamicType,
|
||||
StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE);
|
||||
returnType,
|
||||
_typeProvider.futureElement,
|
||||
StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE,
|
||||
);
|
||||
}
|
||||
} else if (_enclosingFunction.isGenerator) {
|
||||
_checkForIllegalReturnTypeCode(
|
||||
returnType,
|
||||
_typeProvider.iterableDynamicType,
|
||||
StaticTypeWarningCode.ILLEGAL_SYNC_GENERATOR_RETURN_TYPE);
|
||||
returnType,
|
||||
_typeProvider.iterableElement,
|
||||
StaticTypeWarningCode.ILLEGAL_SYNC_GENERATOR_RETURN_TYPE,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3139,7 +3143,7 @@ class ErrorVerifier extends RecursiveAstVisitor<void> {
|
|||
* and if not report [errorCode].
|
||||
*/
|
||||
void _checkForIllegalReturnTypeCode(TypeAnnotation returnTypeName,
|
||||
DartType expectedType, StaticTypeWarningCode errorCode) {
|
||||
ClassElement expectedElement, StaticTypeWarningCode errorCode) {
|
||||
DartType returnType = _enclosingFunction.returnType;
|
||||
//
|
||||
// When checking an async/sync*/async* method, we know the exact type
|
||||
|
@ -3159,8 +3163,10 @@ class ErrorVerifier extends RecursiveAstVisitor<void> {
|
|||
//
|
||||
// Similar logic applies for sync* and async*.
|
||||
//
|
||||
InterfaceType genericType = (expectedType.element as ClassElement).type;
|
||||
DartType lowerBound = genericType.instantiate([BottomTypeImpl.instance]);
|
||||
var lowerBound = expectedElement.instantiate(
|
||||
typeArguments: [BottomTypeImpl.instance],
|
||||
nullabilitySuffix: NullabilitySuffix.star,
|
||||
);
|
||||
if (!_typeSystem.isSubtypeOf(lowerBound, returnType)) {
|
||||
_errorReporter.reportErrorForNode(errorCode, returnTypeName);
|
||||
}
|
||||
|
@ -4931,6 +4937,44 @@ class ErrorVerifier extends RecursiveAstVisitor<void> {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that none of the type [parameters] references itself in its bound.
|
||||
*
|
||||
* See [StaticTypeWarningCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND].
|
||||
*/
|
||||
void _checkForTypeParameterBoundRecursion(List<TypeParameter> parameters) {
|
||||
Map<TypeParameterElement, TypeParameter> elementToNode;
|
||||
for (var parameter in parameters) {
|
||||
if (parameter.bound != null) {
|
||||
if (elementToNode == null) {
|
||||
elementToNode = {};
|
||||
for (var parameter in parameters) {
|
||||
elementToNode[parameter.declaredElement] = parameter;
|
||||
}
|
||||
}
|
||||
|
||||
TypeParameter current = parameter;
|
||||
for (var step = 0; current != null; step++) {
|
||||
var bound = current.bound;
|
||||
if (bound is TypeName) {
|
||||
current = elementToNode[bound.name.staticElement];
|
||||
} else {
|
||||
current = null;
|
||||
}
|
||||
if (step == parameters.length) {
|
||||
var element = parameter.declaredElement;
|
||||
_errorReporter.reportErrorForNode(
|
||||
StaticTypeWarningCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND,
|
||||
parameter,
|
||||
[element.displayName, element.bound.displayName],
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _checkForTypeParameterReferencedByStatic(SimpleIdentifier identifier) {
|
||||
if (_isInStaticMethod || _isInStaticVariableDeclaration) {
|
||||
var element = identifier.staticElement;
|
||||
|
@ -4945,29 +4989,6 @@ class ErrorVerifier extends RecursiveAstVisitor<void> {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the given type [parameter] is a supertype of its bound.
|
||||
*
|
||||
* See [StaticTypeWarningCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND].
|
||||
*/
|
||||
void _checkForTypeParameterSupertypeOfItsBound(TypeParameter parameter) {
|
||||
TypeParameterElement element = parameter.declaredElement;
|
||||
// prepare bound
|
||||
DartType bound = element.bound;
|
||||
if (bound == null) {
|
||||
return;
|
||||
}
|
||||
// OK, type parameter is not supertype of its bound
|
||||
if (!_typeSystem.isSubtypeOf(bound, element.type)) {
|
||||
return;
|
||||
}
|
||||
|
||||
_errorReporter.reportErrorForNode(
|
||||
StaticTypeWarningCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND,
|
||||
parameter,
|
||||
[element.displayName, bound.displayName]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that if the given generative [constructor] has neither an explicit
|
||||
* super constructor invocation nor a redirecting constructor invocation, that
|
||||
|
|
|
@ -1063,7 +1063,7 @@ void main() { }
|
|||
]);
|
||||
}
|
||||
|
||||
test_typeParameterSupertypeOfItsBound() async {
|
||||
test_typeParameterSupertypeOfItsBound_1of1() async {
|
||||
await assertErrorsInCode(r'''
|
||||
class A<T extends T> {
|
||||
}
|
||||
|
@ -1072,6 +1072,17 @@ class A<T extends T> {
|
|||
]);
|
||||
}
|
||||
|
||||
test_typeParameterSupertypeOfItsBound_2of3() async {
|
||||
await assertErrorsInCode(r'''
|
||||
class A<T1 extends T3, T2, T3 extends T1> {
|
||||
}
|
||||
''', [
|
||||
error(StaticTypeWarningCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND, 8, 13),
|
||||
error(
|
||||
StaticTypeWarningCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND, 27, 13),
|
||||
]);
|
||||
}
|
||||
|
||||
test_typePromotion_booleanAnd_useInRight_accessedInClosureRight_mutated() async {
|
||||
await assertErrorsInCode(r'''
|
||||
callMe(f()) { f(); }
|
||||
|
|
Loading…
Reference in a new issue