| Index: pkg/analyzer/lib/src/generated/constant.dart | 
| diff --git a/pkg/analyzer/lib/src/generated/constant.dart b/pkg/analyzer/lib/src/generated/constant.dart | 
| index b15ebc6151b44caa58c8a2cc5cf870a1047fddd2..a09d7adfd91e3238f03be3d1ce43a48ec65f060a 100644 | 
| --- a/pkg/analyzer/lib/src/generated/constant.dart | 
| +++ b/pkg/analyzer/lib/src/generated/constant.dart | 
| @@ -23,6 +23,11 @@ import 'utilities_collection.dart'; | 
| import 'utilities_dart.dart' show ParameterKind; | 
|  | 
| /** | 
| + * Callback used by [ReferenceFinder] to report that a dependency was found. | 
| + */ | 
| +typedef void ReferenceFinderCallback(Element dependency); | 
| + | 
| +/** | 
| * The state of an object representing a boolean value. | 
| */ | 
| class BoolState extends InstanceState { | 
| @@ -186,7 +191,7 @@ class ConstantAstCloner extends AstCloner { | 
| } | 
|  | 
| /** | 
| - * Helper class encapsulating the methods for evaluating constant instance | 
| + * Helper class encapsulating the methods for evaluating constants and | 
| * constant instance creation expressions. | 
| */ | 
| class ConstantEvaluationEngine { | 
| @@ -303,6 +308,74 @@ class ConstantEvaluationEngine { | 
| } | 
|  | 
| /** | 
| +   * Determine which constant elements need to have their values computed | 
| +   * prior to computing the value of [element], and report them using | 
| +   * [callback]. | 
| +   */ | 
| +  void computeDependencies(Element element, ReferenceFinderCallback callback) { | 
| +    ReferenceFinder referenceFinder = new ReferenceFinder(callback); | 
| +    if (element is ParameterElement) { | 
| +      if (element.initializer != null) { | 
| +        Expression defaultValue = | 
| +            (element as ConstVariableElement).constantInitializer; | 
| +        if (defaultValue != null) { | 
| +          defaultValue.accept(referenceFinder); | 
| +        } | 
| +      } | 
| +    } else if (element is PotentiallyConstVariableElement) { | 
| +      element.constantInitializer.accept(referenceFinder); | 
| +    } else if (element is ConstructorElementImpl) { | 
| +      element.isCycleFree = false; | 
| +      ConstructorElement redirectedConstructor = | 
| +          getConstRedirectedConstructor(element); | 
| +      if (redirectedConstructor != null) { | 
| +        ConstructorElement redirectedConstructorBase = | 
| +            ConstantEvaluationEngine._getConstructorBase(redirectedConstructor); | 
| +        callback(redirectedConstructorBase); | 
| +        return; | 
| +      } | 
| +      bool superInvocationFound = false; | 
| +      List<ConstructorInitializer> initializers = element.constantInitializers; | 
| +      for (ConstructorInitializer initializer in initializers) { | 
| +        if (initializer is SuperConstructorInvocation) { | 
| +          superInvocationFound = true; | 
| +        } | 
| +        initializer.accept(referenceFinder); | 
| +      } | 
| +      if (!superInvocationFound) { | 
| +        // No explicit superconstructor invocation found, so we need to | 
| +        // manually insert a reference to the implicit superconstructor. | 
| +        InterfaceType superclass = | 
| +            (element.returnType as InterfaceType).superclass; | 
| +        if (superclass != null && !superclass.isObject) { | 
| +          ConstructorElement unnamedConstructor = ConstantEvaluationEngine | 
| +              ._getConstructorBase(superclass.element.unnamedConstructor); | 
| +          if (unnamedConstructor != null) { | 
| +            callback(unnamedConstructor); | 
| +          } | 
| +        } | 
| +      } | 
| +      for (FieldElement field in element.enclosingElement.fields) { | 
| +        // Note: non-static const isn't allowed but we handle it anyway so that | 
| +        // we won't be confused by incorrect code. | 
| +        if ((field.isFinal || field.isConst) && | 
| +            !field.isStatic && | 
| +            field.initializer != null) { | 
| +          callback(field); | 
| +        } | 
| +      } | 
| +      for (ParameterElement parameterElement in element.parameters) { | 
| +        callback(parameterElement); | 
| +      } | 
| +    } else { | 
| +      // Should not happen. | 
| +      assert(false); | 
| +      AnalysisEngine.instance.logger.logError( | 
| +          "Constant value computer trying to compute the value of a node of type ${element.runtimeType}"); | 
| +    } | 
| +  } | 
| + | 
| +  /** | 
| * Evaluate a call to fromEnvironment() on the bool, int, or String class. The | 
| * [environmentValue] is the value fetched from the environment. The | 
| * [builtInDefaultValue] is the value that should be used as the default if no | 
| @@ -1005,73 +1078,9 @@ class ConstantValueComputer { | 
| _annotations = _constantFinder.annotations; | 
| for (Element element in _constantsToCompute) { | 
| referenceGraph.addNode(element); | 
| -      if (element is ParameterElement) { | 
| -        if (element.initializer != null) { | 
| -          Expression defaultValue = | 
| -              (element as ConstVariableElement).constantInitializer; | 
| -          if (defaultValue != null) { | 
| -            ReferenceFinder parameterReferenceFinder = | 
| -                new ReferenceFinder(element, referenceGraph); | 
| -            defaultValue.accept(parameterReferenceFinder); | 
| -          } | 
| -        } | 
| -      } else if (element is PotentiallyConstVariableElement) { | 
| -        ReferenceFinder referenceFinder = | 
| -            new ReferenceFinder(element, referenceGraph); | 
| -        element.constantInitializer.accept(referenceFinder); | 
| -      } else if (element is ConstructorElementImpl) { | 
| -        element.isCycleFree = false; | 
| -        ConstructorElement redirectedConstructor = | 
| -            evaluationEngine.getConstRedirectedConstructor(element); | 
| -        if (redirectedConstructor != null) { | 
| -          ConstructorElement redirectedConstructorBase = | 
| -              ConstantEvaluationEngine | 
| -                  ._getConstructorBase(redirectedConstructor); | 
| -          referenceGraph.addEdge(element, redirectedConstructorBase); | 
| -          continue; | 
| -        } | 
| -        ReferenceFinder referenceFinder = | 
| -            new ReferenceFinder(element, referenceGraph); | 
| -        bool superInvocationFound = false; | 
| -        List<ConstructorInitializer> initializers = | 
| -            element.constantInitializers; | 
| -        for (ConstructorInitializer initializer in initializers) { | 
| -          if (initializer is SuperConstructorInvocation) { | 
| -            superInvocationFound = true; | 
| -          } | 
| -          initializer.accept(referenceFinder); | 
| -        } | 
| -        if (!superInvocationFound) { | 
| -          // No explicit superconstructor invocation found, so we need to | 
| -          // manually insert a reference to the implicit superconstructor. | 
| -          InterfaceType superclass = | 
| -              (element.returnType as InterfaceType).superclass; | 
| -          if (superclass != null && !superclass.isObject) { | 
| -            ConstructorElement unnamedConstructor = ConstantEvaluationEngine | 
| -                ._getConstructorBase(superclass.element.unnamedConstructor); | 
| -            if (unnamedConstructor != null) { | 
| -              referenceGraph.addEdge(element, unnamedConstructor); | 
| -            } | 
| -          } | 
| -        } | 
| -        for (FieldElement field in element.enclosingElement.fields) { | 
| -          // Note: non-static const isn't allowed but we handle it anyway so that | 
| -          // we won't be confused by incorrect code. | 
| -          if ((field.isFinal || field.isConst) && | 
| -              !field.isStatic && | 
| -              field.initializer != null) { | 
| -            referenceGraph.addEdge(element, field); | 
| -          } | 
| -        } | 
| -        for (ParameterElement parameterElement in element.parameters) { | 
| -          referenceGraph.addEdge(element, parameterElement); | 
| -        } | 
| -      } else { | 
| -        // Should not happen. | 
| -        assert(false); | 
| -        AnalysisEngine.instance.logger.logError( | 
| -            "Constant value computer trying to compute the value of a node of type ${element.runtimeType}"); | 
| -      } | 
| +      evaluationEngine.computeDependencies(element, (Element dependency) { | 
| +        referenceGraph.addEdge(element, dependency); | 
| +      }); | 
| } | 
| List<List<Element>> topologicalSort = | 
| referenceGraph.computeTopologicalSort(); | 
| @@ -4865,25 +4874,17 @@ class NumState extends InstanceState { | 
| */ | 
| class ReferenceFinder extends RecursiveAstVisitor<Object> { | 
| /** | 
| -   * The element representing the construct that will be visited. | 
| -   */ | 
| -  final Element _source; | 
| - | 
| -  /** | 
| -   * A graph in which the nodes are the constant variables and the edges are | 
| -   * from each variable to the other constant variables that are referenced in | 
| -   * the head's initializer. | 
| +   * The callback which should be used to report any dependencies that were | 
| +   * found. | 
| */ | 
| -  final DirectedGraph<Element> _referenceGraph; | 
| +  final ReferenceFinderCallback _callback; | 
|  | 
| /** | 
| * Initialize a newly created reference finder to find references from a given | 
| * variable to other variables and to add those references to the given graph. | 
| -   * The [source] is the element representing the variable whose initializer | 
| -   * will be visited. The [referenceGraph] is a graph recording which variables | 
| -   * (heads) reference which other variables (tails) in their initializers. | 
| +   * The [_callback] will be invoked for every dependency found. | 
| */ | 
| -  ReferenceFinder(this._source, this._referenceGraph); | 
| +  ReferenceFinder(this._callback); | 
|  | 
| @override | 
| Object visitInstanceCreationExpression(InstanceCreationExpression node) { | 
| @@ -4891,7 +4892,7 @@ class ReferenceFinder extends RecursiveAstVisitor<Object> { | 
| ConstructorElement constructor = | 
| ConstantEvaluationEngine._getConstructorBase(node.staticElement); | 
| if (constructor != null) { | 
| -        _referenceGraph.addEdge(_source, constructor); | 
| +        _callback(constructor); | 
| } | 
| } | 
| return super.visitInstanceCreationExpression(node); | 
| @@ -4904,7 +4905,7 @@ class ReferenceFinder extends RecursiveAstVisitor<Object> { | 
| ConstructorElement target = | 
| ConstantEvaluationEngine._getConstructorBase(node.staticElement); | 
| if (target != null && target.isConst) { | 
| -      _referenceGraph.addEdge(_source, target); | 
| +      _callback(target); | 
| } | 
| return null; | 
| } | 
| @@ -4917,7 +4918,7 @@ class ReferenceFinder extends RecursiveAstVisitor<Object> { | 
| } | 
| if (element is VariableElement) { | 
| if (element.isConst) { | 
| -        _referenceGraph.addEdge(_source, element); | 
| +        _callback(element); | 
| } | 
| } | 
| return null; | 
| @@ -4929,7 +4930,7 @@ class ReferenceFinder extends RecursiveAstVisitor<Object> { | 
| ConstructorElement constructor = | 
| ConstantEvaluationEngine._getConstructorBase(node.staticElement); | 
| if (constructor != null && constructor.isConst) { | 
| -      _referenceGraph.addEdge(_source, constructor); | 
| +      _callback(constructor); | 
| } | 
| return null; | 
| } | 
|  |