Index: dart/sdk/lib/_internal/compiler/implementation/elements/elements.dart |
diff --git a/dart/sdk/lib/_internal/compiler/implementation/elements/elements.dart b/dart/sdk/lib/_internal/compiler/implementation/elements/elements.dart |
index f03c982a2b942bf88a16a1ad6900ca66275194d7..0142891d1732839ff2b55f92b7712deefdc9ce48 100644 |
--- a/dart/sdk/lib/_internal/compiler/implementation/elements/elements.dart |
+++ b/dart/sdk/lib/_internal/compiler/implementation/elements/elements.dart |
@@ -1101,10 +1101,14 @@ class FunctionElement extends Element { |
FunctionElement origin = null; |
/** |
- * If this is an interface constructor, [defaultImplementation] will |
- * changed by the resolver to point to the default |
- * implementation. Otherwise, [:defaultImplementation === this:]. |
+ * If this is a redirecting factory, [defaultImplementation] will be |
+ * changed by the resolver to point to the redirection target. If |
+ * this is an interface constructor, [defaultImplementation] will |
Johnni Winther
2012/11/07 08:15:39
will => will be
ahe
2012/11/07 14:22:16
Done.
|
+ * changed by the resolver to point to the default implementation. |
+ * Otherwise, [:defaultImplementation === this:]. |
*/ |
+ // TODO(ahe): Rename this field to redirectionTarget and remove |
+ // mention of interface constructors above. |
FunctionElement defaultImplementation; |
FunctionElement(SourceString name, |
@@ -1141,6 +1145,24 @@ class FunctionElement extends Element { |
bool get isPatched => patch != null; |
bool get isPatch => origin != null; |
+ FunctionExpression get redirectionTarget { |
+ if (this == defaultImplementation) return this; |
+ Element target = defaultImplementation; |
+ Set<Element> seen = new Set<Element>(); |
+ seen.add(target); |
+ while (target != target.defaultImplementation) { |
+ target = target.defaultImplementation; |
+ if (seen.contains(target)) { |
+ // TODO(ahe): This is expedient for now, but it should be |
+ // checked by the resolver. Keeping http://dartbug.com/3970 |
+ // open to track this. |
+ throw new SpannableAssertionFailure( |
+ target, 'redirecting factory leads to cycle'); |
+ } |
+ } |
+ return target; |
+ } |
+ |
/** |
* Applies a patch function to this function. The patch function's body |
* is used as replacement when parsing this function's body. |