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

Unified Diff: compiler/java/com/google/dart/compiler/resolver/Resolver.java

Issue 8747016: Fix for resolving interface constructors in factory, issue 521. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Tweaks for error messages. Created 9 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: compiler/java/com/google/dart/compiler/resolver/Resolver.java
diff --git a/compiler/java/com/google/dart/compiler/resolver/Resolver.java b/compiler/java/com/google/dart/compiler/resolver/Resolver.java
index 17ed6ccae8f5c430e7aedd83910cd73a4d853997..e921e06aeffc90bd64b8682f900278f2b1022301 100644
--- a/compiler/java/com/google/dart/compiler/resolver/Resolver.java
+++ b/compiler/java/com/google/dart/compiler/resolver/Resolver.java
@@ -65,6 +65,7 @@ import com.google.dart.compiler.type.InterfaceType;
import com.google.dart.compiler.type.InterfaceType.Member;
import com.google.dart.compiler.type.Type;
import com.google.dart.compiler.type.TypeVariable;
+import com.google.dart.compiler.util.StringUtils;
import java.util.EnumSet;
import java.util.Iterator;
@@ -884,22 +885,14 @@ public class Resolver {
switch (ElementKind.of(element)) {
case CLASS:
- // Check for default constructor or implicit default constructor
+ // Check for default constructor.
ClassElement classElement = (ClassElement) element;
element = Elements.lookupConstructor(classElement, "");
- if (element == null) {
- // Check that the class needs an implicit ctor and no extra args are passed
- if (Elements.needsImplicitDefaultConstructor(classElement) && x.getArgs().isEmpty()) {
- InterfaceType defaultClass = classElement.getDefaultClass();
- if (defaultClass != null) {
- classElement = defaultClass.getElement();
- element = Elements.lookupConstructor(classElement, "");
- }
-
- if (element == null) {
- return recordElement(x, element);
- }
- }
+ // If no default constructor, may be use implicit default constructor.
+ if (element == null
+ && x.getArgs().isEmpty()
+ && Elements.needsImplicitDefaultConstructor(classElement)) {
+ element = new SyntheticDefaultConstructorElement(null, classElement, typeProvider);
}
break;
case TYPE_VARIABLE:
@@ -909,28 +902,81 @@ public class Resolver {
break;
}
- // If there is a default implementation, lookup the constructor in the
- // default class.
+ // If there is a default implementation, lookup the constructor in the default class.
ConstructorElement constructor = checkIsConstructor(x, element);
if (constructor != null
&& constructor.getConstructorType().getDefaultClass() != null) {
+ element = null;
+ // Prepare elements and names for classes.
ClassElement originalClass = constructor.getConstructorType();
- ClassElement defaultClass =
- constructor.getConstructorType().getDefaultClass().getElement();
- element = Elements.lookupConstructor(defaultClass, originalClass, constructor.getName());
+ ClassElement defaultClass = originalClass.getDefaultClass().getElement();
+ String originalClassName = originalClass.getName();
+ String defaultClassName = defaultClass.getName();
+ // Prepare "qualifier.name" for original constructor.
+ String rawOriginalMethodName = Elements.getRawMethodName(constructor);
+ int originalDotIndex = rawOriginalMethodName.indexOf('.');
+ String originalQualifier = StringUtils.substringBefore(rawOriginalMethodName, ".");
+ String originalName = StringUtils.substringAfter(rawOriginalMethodName, ".");
+ // Separate checks for cases when factory implements interface and not.
+ boolean factoryImplementsInterface = Elements.implementsType(defaultClass, originalClass);
+ if (factoryImplementsInterface) {
+ for (ConstructorElement defaultConstructor : defaultClass.getConstructors()) {
+ String rawDefaultMethodName = Elements.getRawMethodName(defaultConstructor);
+ // kI == nI and kF == nF
+ if (rawOriginalMethodName.equals(originalClassName)
+ && rawDefaultMethodName.equals(defaultClassName)) {
+ element = defaultConstructor;
+ break;
+ }
+ // kI == nI.name and kF == nF.name
+ if (originalDotIndex != -1) {
+ int defaultDotIndex = rawDefaultMethodName.indexOf('.');
+ if (defaultDotIndex != -1) {
+ String defaultQualifier = StringUtils.substringBefore(rawDefaultMethodName, ".");
+ String defaultName = StringUtils.substringAfter(rawDefaultMethodName, ".");
+ if (defaultQualifier.equals(defaultClassName)
+ && originalQualifier.equals(originalClassName) &&
+ defaultName.equals(originalName)) {
+ element = defaultConstructor;
+ break;
+ }
+ }
+ }
+ }
+ } else {
+ for (ConstructorElement defaultConstructor : defaultClass.getConstructors()) {
+ String rawDefaultMethodName = Elements.getRawMethodName(defaultConstructor);
+ if (rawDefaultMethodName.equals(rawOriginalMethodName)) {
+ element = defaultConstructor;
+ break;
+ }
+ }
+ }
+ // If constructor not found, try implicit default constructor of the default class.
+ if (element == null
+ && x.getArgs().isEmpty()
+ && Elements.needsImplicitDefaultConstructor(defaultClass)) {
+ element = new SyntheticDefaultConstructorElement(null, defaultClass, typeProvider);
+ }
+ // If factory constructor not resolved, report error with specific message for each case.
if (element == null) {
- // If the constructor hasn't been found, try the constructor of the default class.
- // TODO(ngeoffray): check earlier if the default class implements the interface.
- element = Elements.lookupConstructor(defaultClass, constructor.getName());
- if (element == null && Elements.needsImplicitDefaultConstructor(defaultClass)) {
- /*
- * Record the element and prevent checkIsConstructor from reporting errors below
- * since we know that w don't have an element.
- */
- return recordElement(x, element);
+ String expectedFactoryConstructorName;
+ if (factoryImplementsInterface) {
+ if (originalDotIndex == -1) {
+ expectedFactoryConstructorName = defaultClassName;
+ } else {
+ expectedFactoryConstructorName = defaultClassName + "." + originalName;
+ }
+ } else {
+ expectedFactoryConstructorName = rawOriginalMethodName;
}
+ onError(
+ x.getConstructor(),
+ ResolverErrorCode.NEW_EXPRESSION_FACTORY_CONSTRUCTOR,
+ expectedFactoryConstructorName,
+ defaultClassName);
+ return null;
}
-
// Will check that element is not null.
constructor = checkIsConstructor(x, element);
}

Powered by Google App Engine
This is Rietveld 408576698