| Index: pkg/analyzer/lib/src/generated/resolver.dart
|
| diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
|
| index f825cdf91f3b2f285e57989e901b1e00d15ff256..8065c3e073eb9e8b811320859f53b56f831654c0 100644
|
| --- a/pkg/analyzer/lib/src/generated/resolver.dart
|
| +++ b/pkg/analyzer/lib/src/generated/resolver.dart
|
| @@ -7486,6 +7486,10 @@ class ResolverVisitor extends ScopedVisitor {
|
| * The abstract class `ScopedVisitor` maintains name and label scopes as an AST structure is
|
| * being visited.
|
| */
|
| +/**
|
| + * The abstract class `ScopedVisitor` maintains name and label scopes as an AST structure is
|
| + * being visited.
|
| + */
|
| abstract class ScopedVisitor extends UnifyingAstVisitor<Object> {
|
| /**
|
| * The element for the library containing the compilation unit being visited.
|
| @@ -8366,16 +8370,30 @@ class TypeNameResolver {
|
| final DartType dynamicType;
|
| final DartType undefinedType;
|
| final LibraryElement definingLibrary;
|
| - final ErrorReporter errorReporter;
|
| + final Source source;
|
| + final AnalysisErrorListener errorListener;
|
|
|
| Scope nameScope;
|
|
|
| TypeNameResolver(this.typeSystem, TypeProvider typeProvider,
|
| - this.definingLibrary, this.errorReporter)
|
| + this.definingLibrary, this.source, this.errorListener)
|
| : dynamicType = typeProvider.dynamicType,
|
| undefinedType = typeProvider.undefinedType;
|
|
|
| /**
|
| + * Report an error with the given error code and arguments.
|
| + *
|
| + * @param errorCode the error code of the error to be reported
|
| + * @param node the node specifying the location of the error
|
| + * @param arguments the arguments to the error, used to compose the error message
|
| + */
|
| + void reportErrorForNode(ErrorCode errorCode, AstNode node,
|
| + [List<Object> arguments]) {
|
| + errorListener.onError(new AnalysisError(
|
| + source, node.offset, node.length, errorCode, arguments));
|
| + }
|
| +
|
| + /**
|
| * Resolve the given [TypeName] - set its element and static type. Only the
|
| * given [node] is resolved, all its children must be already resolved.
|
| *
|
| @@ -8434,14 +8452,14 @@ class TypeNameResolver {
|
| grandParent.isConst) {
|
| // If, if this is a const expression, then generate a
|
| // CompileTimeErrorCode.CONST_WITH_NON_TYPE error.
|
| - errorReporter.reportErrorForNode(
|
| + reportErrorForNode(
|
| CompileTimeErrorCode.CONST_WITH_NON_TYPE,
|
| prefixedIdentifier.identifier,
|
| [prefixedIdentifier.identifier.name]);
|
| } else {
|
| // Else, if this expression is a new expression, report a
|
| // NEW_WITH_NON_TYPE warning.
|
| - errorReporter.reportErrorForNode(
|
| + reportErrorForNode(
|
| StaticWarningCode.NEW_WITH_NON_TYPE,
|
| prefixedIdentifier.identifier,
|
| [prefixedIdentifier.identifier.name]);
|
| @@ -8474,18 +8492,16 @@ class TypeNameResolver {
|
| node.parent.parent as InstanceCreationExpression;
|
| if (creation.isConst) {
|
| if (element == null) {
|
| - errorReporter.reportErrorForNode(
|
| + reportErrorForNode(
|
| CompileTimeErrorCode.UNDEFINED_CLASS, typeNameSimple, [typeName]);
|
| } else {
|
| - errorReporter.reportErrorForNode(
|
| - CompileTimeErrorCode.CONST_WITH_NON_TYPE,
|
| - typeNameSimple,
|
| - [typeName]);
|
| + reportErrorForNode(CompileTimeErrorCode.CONST_WITH_NON_TYPE,
|
| + typeNameSimple, [typeName]);
|
| }
|
| elementValid = false;
|
| } else {
|
| if (element != null) {
|
| - errorReporter.reportErrorForNode(
|
| + reportErrorForNode(
|
| StaticWarningCode.NEW_WITH_NON_TYPE, typeNameSimple, [typeName]);
|
| elementValid = false;
|
| }
|
| @@ -8501,26 +8517,20 @@ class TypeNameResolver {
|
| SimpleIdentifier typeNameSimple = _getTypeSimpleIdentifier(typeName);
|
| RedirectingConstructorKind redirectingConstructorKind;
|
| if (_isBuiltInIdentifier(node) && _isTypeAnnotation(node)) {
|
| - errorReporter.reportErrorForNode(
|
| - CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE,
|
| - typeName,
|
| - [typeName.name]);
|
| + reportErrorForNode(CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE,
|
| + typeName, [typeName.name]);
|
| } else if (typeNameSimple.name == "boolean") {
|
| - errorReporter.reportErrorForNode(
|
| + reportErrorForNode(
|
| StaticWarningCode.UNDEFINED_CLASS_BOOLEAN, typeNameSimple, []);
|
| } else if (_isTypeNameInCatchClause(node)) {
|
| - errorReporter.reportErrorForNode(
|
| - StaticWarningCode.NON_TYPE_IN_CATCH_CLAUSE,
|
| - typeName,
|
| + reportErrorForNode(StaticWarningCode.NON_TYPE_IN_CATCH_CLAUSE, typeName,
|
| [typeName.name]);
|
| } else if (_isTypeNameInAsExpression(node)) {
|
| - errorReporter.reportErrorForNode(
|
| + reportErrorForNode(
|
| StaticWarningCode.CAST_TO_NON_TYPE, typeName, [typeName.name]);
|
| } else if (_isTypeNameInIsExpression(node)) {
|
| - errorReporter.reportErrorForNode(
|
| - StaticWarningCode.TYPE_TEST_WITH_UNDEFINED_NAME,
|
| - typeName,
|
| - [typeName.name]);
|
| + reportErrorForNode(StaticWarningCode.TYPE_TEST_WITH_UNDEFINED_NAME,
|
| + typeName, [typeName.name]);
|
| } else if ((redirectingConstructorKind =
|
| _getRedirectingConstructorKind(node)) !=
|
| null) {
|
| @@ -8528,14 +8538,12 @@ class TypeNameResolver {
|
| (redirectingConstructorKind == RedirectingConstructorKind.CONST
|
| ? CompileTimeErrorCode.REDIRECT_TO_NON_CLASS
|
| : StaticWarningCode.REDIRECT_TO_NON_CLASS);
|
| - errorReporter.reportErrorForNode(errorCode, typeName, [typeName.name]);
|
| + reportErrorForNode(errorCode, typeName, [typeName.name]);
|
| } else if (_isTypeNameInTypeArgumentList(node)) {
|
| - errorReporter.reportErrorForNode(
|
| - StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT,
|
| - typeName,
|
| - [typeName.name]);
|
| + reportErrorForNode(StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT,
|
| + typeName, [typeName.name]);
|
| } else {
|
| - errorReporter.reportErrorForNode(
|
| + reportErrorForNode(
|
| StaticWarningCode.UNDEFINED_CLASS, typeName, [typeName.name]);
|
| }
|
| elementValid = false;
|
| @@ -8573,17 +8581,13 @@ class TypeNameResolver {
|
| // The name does not represent a type.
|
| RedirectingConstructorKind redirectingConstructorKind;
|
| if (_isTypeNameInCatchClause(node)) {
|
| - errorReporter.reportErrorForNode(
|
| - StaticWarningCode.NON_TYPE_IN_CATCH_CLAUSE,
|
| - typeName,
|
| + reportErrorForNode(StaticWarningCode.NON_TYPE_IN_CATCH_CLAUSE, typeName,
|
| [typeName.name]);
|
| } else if (_isTypeNameInAsExpression(node)) {
|
| - errorReporter.reportErrorForNode(
|
| + reportErrorForNode(
|
| StaticWarningCode.CAST_TO_NON_TYPE, typeName, [typeName.name]);
|
| } else if (_isTypeNameInIsExpression(node)) {
|
| - errorReporter.reportErrorForNode(
|
| - StaticWarningCode.TYPE_TEST_WITH_NON_TYPE,
|
| - typeName,
|
| + reportErrorForNode(StaticWarningCode.TYPE_TEST_WITH_NON_TYPE, typeName,
|
| [typeName.name]);
|
| } else if ((redirectingConstructorKind =
|
| _getRedirectingConstructorKind(node)) !=
|
| @@ -8592,12 +8596,10 @@ class TypeNameResolver {
|
| (redirectingConstructorKind == RedirectingConstructorKind.CONST
|
| ? CompileTimeErrorCode.REDIRECT_TO_NON_CLASS
|
| : StaticWarningCode.REDIRECT_TO_NON_CLASS);
|
| - errorReporter.reportErrorForNode(errorCode, typeName, [typeName.name]);
|
| + reportErrorForNode(errorCode, typeName, [typeName.name]);
|
| } else if (_isTypeNameInTypeArgumentList(node)) {
|
| - errorReporter.reportErrorForNode(
|
| - StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT,
|
| - typeName,
|
| - [typeName.name]);
|
| + reportErrorForNode(StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT,
|
| + typeName, [typeName.name]);
|
| } else {
|
| AstNode parent = typeName.parent;
|
| while (parent is TypeName) {
|
| @@ -8609,7 +8611,7 @@ class TypeNameResolver {
|
| parent is ClassTypeAlias) {
|
| // Ignored. The error will be reported elsewhere.
|
| } else {
|
| - errorReporter.reportErrorForNode(
|
| + reportErrorForNode(
|
| StaticWarningCode.NOT_A_TYPE, typeName, [typeName.name]);
|
| }
|
| }
|
| @@ -8633,9 +8635,7 @@ class TypeNameResolver {
|
| typeArguments[i] = argumentType;
|
| }
|
| } else {
|
| - errorReporter.reportErrorForNode(
|
| - _getInvalidTypeParametersErrorCode(node),
|
| - node,
|
| + reportErrorForNode(_getInvalidTypeParametersErrorCode(node), node,
|
| [typeName.name, parameterCount, argumentCount]);
|
| for (int i = 0; i < parameterCount; i++) {
|
| typeArguments[i] = dynamicType;
|
| @@ -9085,6 +9085,70 @@ class TypeOverrideManager_TypeOverrideScope {
|
| }
|
|
|
| /**
|
| + * This class resolves bounds of type parameters of classes, class and function
|
| + * type aliases.
|
| + */
|
| +class TypeParameterBoundsResolver {
|
| + final TypeProvider typeProvider;
|
| + final LibraryElement library;
|
| + final Source source;
|
| + final AnalysisErrorListener errorListener;
|
| +
|
| + Scope libraryScope = null;
|
| + TypeNameResolver typeNameResolver = null;
|
| +
|
| + TypeParameterBoundsResolver(
|
| + this.typeProvider, this.library, this.source, this.errorListener);
|
| +
|
| + /**
|
| + * Resolve bounds of type parameters of classes, class and function type
|
| + * aliases.
|
| + */
|
| + void resolveTypeBounds(CompilationUnit unit) {
|
| + for (CompilationUnitMember unitMember in unit.declarations) {
|
| + if (unitMember is ClassDeclaration) {
|
| + _resolveTypeParameters(unitMember.typeParameters,
|
| + () => new TypeParameterScope(libraryScope, unitMember.element));
|
| + } else if (unitMember is ClassTypeAlias) {
|
| + _resolveTypeParameters(unitMember.typeParameters,
|
| + () => new TypeParameterScope(libraryScope, unitMember.element));
|
| + } else if (unitMember is FunctionTypeAlias) {
|
| + _resolveTypeParameters(unitMember.typeParameters,
|
| + () => new FunctionTypeScope(libraryScope, unitMember.element));
|
| + }
|
| + }
|
| + }
|
| +
|
| + void _resolveTypeName(TypeName typeName) {
|
| + typeName.typeArguments?.arguments?.forEach(_resolveTypeName);
|
| + typeNameResolver.resolveTypeName(typeName);
|
| + // TODO(scheglov) report error when don't apply type bounds for type bounds
|
| + }
|
| +
|
| + void _resolveTypeParameters(
|
| + TypeParameterList typeParameters, Scope createTypeParametersScope()) {
|
| + if (typeParameters != null) {
|
| + Scope typeParametersScope = null;
|
| + for (TypeParameter typeParameter in typeParameters.typeParameters) {
|
| + TypeName bound = typeParameter.bound;
|
| + if (bound != null) {
|
| + libraryScope ??= new LibraryScope(library, errorListener);
|
| + typeParametersScope ??= createTypeParametersScope();
|
| + typeNameResolver ??= new TypeNameResolver(new TypeSystemImpl(),
|
| + typeProvider, library, source, errorListener);
|
| + typeNameResolver.nameScope = typeParametersScope;
|
| + _resolveTypeName(bound);
|
| + Element typeParameterElement = typeParameter.name.staticElement;
|
| + if (typeParameterElement is TypeParameterElementImpl) {
|
| + typeParameterElement.bound = bound.type;
|
| + }
|
| + }
|
| + }
|
| + }
|
| + }
|
| +}
|
| +
|
| +/**
|
| * Instances of the class `TypePromotionManager` manage the ability to promote types of local
|
| * variables and formal parameters from their declared types based on control flow.
|
| */
|
| @@ -9705,7 +9769,7 @@ class TypeResolverVisitor extends ScopedVisitor {
|
| _strongMode = definingLibrary.context.analysisOptions.strongMode;
|
| _typeSystem = TypeSystem.create(definingLibrary.context);
|
| _typeNameResolver = new TypeNameResolver(
|
| - _typeSystem, typeProvider, definingLibrary, errorReporter);
|
| + _typeSystem, typeProvider, definingLibrary, source, errorListener);
|
| }
|
|
|
| @override
|
| @@ -10047,12 +10111,20 @@ class TypeResolverVisitor extends ScopedVisitor {
|
| @override
|
| Object visitTypeParameter(TypeParameter node) {
|
| super.visitTypeParameter(node);
|
| - TypeName bound = node.bound;
|
| - if (bound != null) {
|
| - TypeParameterElementImpl typeParameter =
|
| - node.name.staticElement as TypeParameterElementImpl;
|
| - if (typeParameter != null) {
|
| - typeParameter.bound = bound.type;
|
| + AstNode parent2 = node.parent?.parent;
|
| + if (parent2 is ClassDeclaration ||
|
| + parent2 is ClassTypeAlias ||
|
| + parent2 is FunctionTypeAlias) {
|
| + // Bounds of parameters of classes and function type aliases are
|
| + // already resolved.
|
| + } else {
|
| + TypeName bound = node.bound;
|
| + if (bound != null) {
|
| + TypeParameterElementImpl typeParameter =
|
| + node.name.staticElement as TypeParameterElementImpl;
|
| + if (typeParameter != null) {
|
| + typeParameter.bound = bound.type;
|
| + }
|
| }
|
| }
|
| return null;
|
|
|