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

Unified Diff: editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/constant/ConstantVisitor.java

Issue 261403004: In constant evaluation, properly handle redirecting factory constructors. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 7 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: 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();

Powered by Google App Engine
This is Rietveld 408576698