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

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

Issue 724133003: Improve error reporting when a mixin application is invalid. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 1 month 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 28804fa33aa41240e038bce318811838220429c7..7fec21b6c68e4139873a685d3b3a2e6efbd8849b 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -5692,13 +5692,47 @@ class ImplicitConstructorBuilder extends ScopedVisitor {
ImplicitConstructorBuilder.con2(ResolvableLibrary library, Source source, TypeProvider typeProvider) : super.con4(library, source, typeProvider);
@override
- Object visitClassDeclaration(ClassDeclaration node) => null;
+ Object visitClassDeclaration(ClassDeclaration node) {
+ ClassElementImpl classElement = node.element;
+ classElement.mixinErrorsReported = false;
+ if (node.extendsClause != null && node.withClause != null) {
+ // We don't need to build any implicitly constructors for the mixin
+ // application (since there isn't an explicit element for it), but we
+ // need to verify that they _could_ be built.
+ InterfaceType superclassType = null;
+ TypeName superclassName = node.extendsClause.superclass;
+ DartType type = superclassName.type;
+ if (type is InterfaceType) {
+ superclassType = type;
+ } else {
+ superclassType = typeProvider.objectType;
+ }
+ ClassElement superclassElement = classElement.supertype.element;
+ if (superclassElement != null) {
+ bool constructorFound = false;
+ void callback(ConstructorElement explicitConstructor,
+ List<DartType> parameterTypes,
+ List<DartType> argumentTypes) {
+ constructorFound = true;
+ }
+ if (_findForwardedConstructors(
+ classElement, superclassName, superclassType, callback) &&
+ !constructorFound) {
+ reportErrorForNode(CompileTimeErrorCode.MIXIN_HAS_NO_CONSTRUCTORS,
+ node.withClause, [superclassType.element.name]);
+ classElement.mixinErrorsReported = true;
+ }
+ }
+ }
+ return null;
+ }
@override
Object visitClassTypeAlias(ClassTypeAlias node) {
super.visitClassTypeAlias(node);
InterfaceType superclassType = null;
- DartType type = node.superclass.type;
+ TypeName superclassName = node.superclass;
+ DartType type = superclassName.type;
if (type is InterfaceType) {
superclassType = type;
} else {
@@ -5706,33 +5740,67 @@ class ImplicitConstructorBuilder extends ScopedVisitor {
}
ClassElementImpl classElement = node.element as ClassElementImpl;
if (classElement != null) {
- ClassElement superclassElement = superclassType.element;
- if (superclassElement != null) {
- List<ConstructorElement> constructors = superclassElement.constructors;
- int count = constructors.length;
- if (count > 0) {
- List<DartType> parameterTypes = TypeParameterTypeImpl.getTypes(superclassType.typeParameters);
- List<DartType> argumentTypes = _getArgumentTypes(node.superclass.typeArguments, parameterTypes);
- InterfaceType classType = classElement.type;
- List<ConstructorElement> implicitConstructors = new List<ConstructorElement>();
- for (int i = 0; i < count; i++) {
- ConstructorElement explicitConstructor = constructors[i];
- if (!explicitConstructor.isFactory &&
- classElement.isSuperConstructorAccessible(explicitConstructor)) {
- implicitConstructors.add(_createImplicitContructor(classType, explicitConstructor, parameterTypes, argumentTypes));
- }
- }
+ if (superclassType.element != null) {
+ List<ConstructorElement> implicitConstructors =
+ new List<ConstructorElement>();
+ void callback(ConstructorElement explicitConstructor,
+ List<DartType> parameterTypes,
+ List<DartType> argumentTypes) {
+ implicitConstructors.add(_createImplicitContructor(
+ classElement.type,
+ explicitConstructor,
+ parameterTypes,
+ argumentTypes));
+ }
+ if (_findForwardedConstructors(
+ classElement, superclassName, superclassType, callback)) {
if (implicitConstructors.isEmpty) {
reportErrorForNode(CompileTimeErrorCode.MIXIN_HAS_NO_CONSTRUCTORS,
- node, [superclassElement.name]);
+ node, [superclassType.element.name]);
+ } else {
+ classElement.constructors = implicitConstructors;
}
- classElement.constructors = implicitConstructors;
}
}
}
return null;
}
+ /**
+ * Find all the constructors that should be forwarded from the superclass
+ * named [superclassName], having type [superclassType], to the class or
+ * mixin application [classElement], and pass information about them to
+ * [callback].
+ *
+ * Return true if some constructors were considered. (A false return value
+ * can only happen if the supeclass is a built-in type, in which case it
+ * can't be used as a mixin anyway).
+ */
+ bool _findForwardedConstructors(
+ ClassElementImpl classElement,
+ TypeName superclassName,
+ InterfaceType superclassType,
+ void callback(ConstructorElement explicitConstructor,
+ List<DartType> parameterTypes,
+ List<DartType> argumentTypes)) {
+ ClassElement superclassElement = superclassType.element;
+ List<ConstructorElement> constructors = superclassElement.constructors;
+ int count = constructors.length;
+ if (count == 0) {
+ return false;
+ }
+ List<DartType> parameterTypes = TypeParameterTypeImpl.getTypes(superclassType.typeParameters);
+ List<DartType> argumentTypes = _getArgumentTypes(superclassName.typeArguments, parameterTypes);
+ for (int i = 0; i < count; i++) {
+ ConstructorElement explicitConstructor = constructors[i];
+ if (!explicitConstructor.isFactory &&
+ classElement.isSuperConstructorAccessible(explicitConstructor)) {
+ callback(explicitConstructor, parameterTypes, argumentTypes);
+ }
+ }
+ return true;
+ }
+
@override
Object visitEnumDeclaration(EnumDeclaration node) => null;

Powered by Google App Engine
This is Rietveld 408576698