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

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

Issue 10983089: Issue 3968. Report error if cycle in redirecting factory constructors (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 3 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: 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 34802eb95eca9acb82fe2b9656be864a27eb51ac..7e1d1edc1a6d0142ce52ffd60a8344cf848f1bac 100644
--- a/compiler/java/com/google/dart/compiler/resolver/Resolver.java
+++ b/compiler/java/com/google/dart/compiler/resolver/Resolver.java
@@ -234,9 +234,39 @@ public class Resolver {
for (DartNode node : unit.getTopLevelNodes()) {
node.accept(this);
}
+ checkRedirectingFactoryConstructorsCycle(unit);
return null;
}
+ private void checkRedirectingFactoryConstructorsCycle(DartUnit unit) {
+ unit.accept(new ASTVisitor<Void>() {
+ @Override
+ public Void visitMethodDefinition(DartMethodDefinition node) {
+ MethodNodeElement element = node.getElement();
+ if (ElementKind.of(element) == ElementKind.CONSTRUCTOR) {
+ ConstructorElement constructor = (ConstructorElement) element;
+ if (hasRedirectingFactoryConstructorCycle(constructor)) {
+ onError(constructor.getNameLocation(),
+ ResolverErrorCode.REDIRECTION_CONSTRUCTOR_CYCLE);
+ }
+ }
+ return super.visitMethodDefinition(node);
+ }
+ });
+ }
+
+ private boolean hasRedirectingFactoryConstructorCycle(ConstructorElement element) {
+ Set<ConstructorElement> constructors = Sets.newHashSet();
+ while (element != null) {
+ if (constructors.contains(element)) {
+ return true;
+ }
+ constructors.add(element);
+ element = element.getRedirectingFactoryConstructor();
+ }
+ return false;
+ }
+
@Override
public Element visitFunctionTypeAlias(DartFunctionTypeAlias alias) {
alias.getMetadata().accept(this);
@@ -699,12 +729,14 @@ public class Resolver {
TypeErrorCode.NO_SUCH_TYPE, ResolverErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS);
switch (TypeKind.of(rcType)) {
case INTERFACE:
+ ConstructorElement targetConstructor = null;
Element element = recordType(rcTypeName, rcType);
DartIdentifier rcName = node.getRedirectedConstructorName();
if (rcName != null) {
element = ((ClassElement) element).lookupConstructor(rcName.getName());
switch (ElementKind.of(element)) {
case CONSTRUCTOR:
+ targetConstructor = (ConstructorElement) element;
recordElement(rcName, element);
if (member.getModifiers().isConstant() && !element.getModifiers().isConstant()) {
onError(rcName,
@@ -712,7 +744,11 @@ public class Resolver {
}
break;
}
+ } else {
+ targetConstructor = ((ClassElement) element).lookupConstructor(element.getName());
}
+ Elements.setRedirectingFactoryConstructor(((ConstructorElement) member),
+ targetConstructor);
break;
default:
onError(rcTypeName, ResolverErrorCode.REDIRECTION_CONSTRUCTOR_TARGET_TYPE);

Powered by Google App Engine
This is Rietveld 408576698