| 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 70a3b2de4962370fcb7abfc4963c0522de4533d3..eea55b77aa95dc5e3e97a87c4ff2b25260dd5a2c 100644
|
| --- a/dart/sdk/lib/_internal/compiler/implementation/elements/elements.dart
|
| +++ b/dart/sdk/lib/_internal/compiler/implementation/elements/elements.dart
|
| @@ -425,6 +425,8 @@ class ErroneousFunctionElement extends ErroneousElement
|
| requiredParameterCount(compiler) => unsupported();
|
| optionalParameterCount(compiler) => unsupported();
|
| parameterCount(copmiler) => unsupported();
|
| +
|
| + get redirectionTarget => this;
|
| }
|
|
|
| /**
|
| @@ -1141,10 +1143,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 be
|
| + * 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,
|
| @@ -1181,6 +1187,24 @@ class FunctionElement extends Element {
|
| bool get isPatched => patch != null;
|
| bool get isPatch => origin != null;
|
|
|
| + FunctionElement get redirectionTarget {
|
| + if (this == defaultImplementation) return this;
|
| + Element target = defaultImplementation;
|
| + Set<Element> seen = new Set<Element>();
|
| + seen.add(target);
|
| + while (!target.isErroneous() && 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.
|
|
|