Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(565)

Unified Diff: pkg/analyzer/lib/src/generated/resolver.dart

Issue 1927323002: Implement stable resolution of generic types without type arguments to their bounds. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Merge and regenerate the task graph. Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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;
« no previous file with comments | « pkg/analyzer/lib/src/generated/incremental_resolver.dart ('k') | pkg/analyzer/lib/src/plugin/engine_plugin.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698