Chromium Code Reviews| 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(); |