Index: editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/constant/ConstantVisitor.java |
diff --git a/editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/constant/ConstantVisitor.java b/editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/constant/ConstantVisitor.java |
index a7b4c79e5a0189ac23625722dcfc312bf12a701a..4eeca3ac9ad07f7018492e5a4ef0b430b938eb06 100644 |
--- a/editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/constant/ConstantVisitor.java |
+++ b/editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/constant/ConstantVisitor.java |
@@ -79,6 +79,7 @@ import com.google.dart.engine.utilities.dart.ParameterKind; |
import java.util.ArrayList; |
import java.util.HashMap; |
+import java.util.HashSet; |
/** |
* Instances of the class {@code ConstantVisitor} evaluate constant expressions to produce their |
@@ -279,15 +280,39 @@ public class ConstantVisitor extends UnifyingAstVisitor<EvaluationResultImpl> { |
argumentValues[i] = valueOf(argument); |
} |
} |
+ HashSet<ConstructorElement> constructorsVisited = new HashSet<ConstructorElement>(); |
InterfaceType definingClass = (InterfaceType) constructor.getReturnType(); |
- if (definingClass.getElement().getLibrary().isDartCore()) { |
- String className = definingClass.getName(); |
- if (className.equals("Symbol") && argumentCount == 1) { |
- String argumentValue = argumentValues[0].getStringValue(); |
- if (argumentValue != null) { |
- return valid(definingClass, new SymbolState(argumentValue)); |
+ while (constructor.isFactory()) { |
+ if (definingClass.getElement().getLibrary().isDartCore()) { |
+ String className = definingClass.getName(); |
+ if (className.equals("Symbol") && argumentCount == 1) { |
+ String argumentValue = argumentValues[0].getStringValue(); |
+ if (argumentValue != null) { |
+ return valid(definingClass, new SymbolState(argumentValue)); |
+ } |
} |
} |
+ constructorsVisited.add(constructor); |
+ ConstructorElement redirectedConstructor = constructor.getRedirectedConstructor(); |
+ if (redirectedConstructor == null) { |
+ // This can happen if constructor is an external factory constructor. Since there is no |
+ // constructor to delegate to, we can't evaluate the constant. |
Brian Wilkerson
2014/05/06 21:44:32
That's sort of true (if you add "currently"). Actu
Paul Berry
2014/05/07 17:21:43
Ok, I added the word "currently", and the followin
|
+ return error(node, null); |
+ } |
+ if (!redirectedConstructor.isConst()) { |
+ // Delegating to a non-const constructor--this is not allowed (and |
+ // is checked elsewhere--see [ErrorVerifier.checkForRedirectToNonConstConstructor()]). |
+ // So if we encounter it just error out. |
+ return error(node, null); |
+ } |
+ if (constructorsVisited.contains(redirectedConstructor)) { |
+ // Cycle in redirecting factory constructors--this is not allowed |
+ // and is checked elsewhere--see [ErrorVerifier.checkForRecursiveFactoryRedirect()]). |
+ // So if we encounter it just error out. |
+ return error(node, null); |
+ } |
+ constructor = redirectedConstructor; |
+ definingClass = (InterfaceType) constructor.getReturnType(); |
} |
HashMap<String, DartObjectImpl> fieldMap = new HashMap<String, DartObjectImpl>(); |
ParameterElement[] parameters = constructor.getParameters(); |