| Index: sdk/lib/_internal/compiler/implementation/resolution/members.dart
 | 
| diff --git a/sdk/lib/_internal/compiler/implementation/resolution/members.dart b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
 | 
| deleted file mode 100644
 | 
| index 937d308a4afbc195fa6be76d78d86e5b2586eeb7..0000000000000000000000000000000000000000
 | 
| --- a/sdk/lib/_internal/compiler/implementation/resolution/members.dart
 | 
| +++ /dev/null
 | 
| @@ -1,5054 +0,0 @@
 | 
| -// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 | 
| -// for details. All rights reserved. Use of this source code is governed by a
 | 
| -// BSD-style license that can be found in the LICENSE file.
 | 
| -
 | 
| -part of resolution;
 | 
| -
 | 
| -abstract class TreeElements {
 | 
| -  AnalyzableElement get analyzedElement;
 | 
| -  Iterable<Node> get superUses;
 | 
| -
 | 
| -  /// Iterables of the dependencies that this [TreeElement] records of
 | 
| -  /// [analyzedElement].
 | 
| -  Iterable<Element> get allElements;
 | 
| -  void forEachConstantNode(f(Node n, ConstantExpression c));
 | 
| -
 | 
| -  /// A set of additional dependencies.  See [registerDependency] below.
 | 
| -  Iterable<Element> get otherDependencies;
 | 
| -
 | 
| -  Element operator[](Node node);
 | 
| -
 | 
| -  // TODO(johnniwinther): Investigate whether [Node] could be a [Send].
 | 
| -  Selector getSelector(Node node);
 | 
| -  Selector getGetterSelectorInComplexSendSet(SendSet node);
 | 
| -  Selector getOperatorSelectorInComplexSendSet(SendSet node);
 | 
| -  DartType getType(Node node);
 | 
| -  void setSelector(Node node, Selector selector);
 | 
| -  void setGetterSelectorInComplexSendSet(SendSet node, Selector selector);
 | 
| -  void setOperatorSelectorInComplexSendSet(SendSet node, Selector selector);
 | 
| -
 | 
| -  /// Returns the for-in loop variable for [node].
 | 
| -  Element getForInVariable(ForIn node);
 | 
| -  Selector getIteratorSelector(ForIn node);
 | 
| -  Selector getMoveNextSelector(ForIn node);
 | 
| -  Selector getCurrentSelector(ForIn node);
 | 
| -  void setIteratorSelector(ForIn node, Selector selector);
 | 
| -  void setMoveNextSelector(ForIn node, Selector selector);
 | 
| -  void setCurrentSelector(ForIn node, Selector selector);
 | 
| -  void setConstant(Node node, ConstantExpression constant);
 | 
| -  ConstantExpression getConstant(Node node);
 | 
| -  bool isAssert(Send send);
 | 
| -
 | 
| -  /// Returns the [FunctionElement] defined by [node].
 | 
| -  FunctionElement getFunctionDefinition(FunctionExpression node);
 | 
| -
 | 
| -  /// Returns target constructor for the redirecting factory body [node].
 | 
| -  ConstructorElement getRedirectingTargetConstructor(
 | 
| -      RedirectingFactoryBody node);
 | 
| -
 | 
| -  /**
 | 
| -   * Returns [:true:] if [node] is a type literal.
 | 
| -   *
 | 
| -   * Resolution marks this by setting the type on the node to be the
 | 
| -   * type that the literal refers to.
 | 
| -   */
 | 
| -  bool isTypeLiteral(Send node);
 | 
| -
 | 
| -  /// Returns the type that the type literal [node] refers to.
 | 
| -  DartType getTypeLiteralType(Send node);
 | 
| -
 | 
| -  /// Register additional dependencies required by [analyzedElement].
 | 
| -  /// For example, elements that are used by a backend.
 | 
| -  void registerDependency(Element element);
 | 
| -
 | 
| -  /// Returns a list of nodes that potentially mutate [element] anywhere in its
 | 
| -  /// scope.
 | 
| -  List<Node> getPotentialMutations(VariableElement element);
 | 
| -
 | 
| -  /// Returns a list of nodes that potentially mutate [element] in [node].
 | 
| -  List<Node> getPotentialMutationsIn(Node node, VariableElement element);
 | 
| -
 | 
| -  /// Returns a list of nodes that potentially mutate [element] in a closure.
 | 
| -  List<Node> getPotentialMutationsInClosure(VariableElement element);
 | 
| -
 | 
| -  /// Returns a list of nodes that access [element] within a closure in [node].
 | 
| -  List<Node> getAccessesByClosureIn(Node node, VariableElement element);
 | 
| -
 | 
| -  /// Returns the jump target defined by [node].
 | 
| -  JumpTarget getTargetDefinition(Node node);
 | 
| -
 | 
| -  /// Returns the jump target of the [node].
 | 
| -  JumpTarget getTargetOf(GotoStatement node);
 | 
| -
 | 
| -  /// Returns the label defined by [node].
 | 
| -  LabelDefinition getLabelDefinition(Label node);
 | 
| -
 | 
| -  /// Returns the label that [node] targets.
 | 
| -  LabelDefinition getTargetLabel(GotoStatement node);
 | 
| -}
 | 
| -
 | 
| -class TreeElementMapping implements TreeElements {
 | 
| -  final AnalyzableElement analyzedElement;
 | 
| -  Map<Spannable, Selector> _selectors;
 | 
| -  Map<Node, DartType> _types;
 | 
| -  Setlet<Node> _superUses;
 | 
| -  Setlet<Element> _otherDependencies;
 | 
| -  Map<Node, ConstantExpression> _constants;
 | 
| -  Map<VariableElement, List<Node>> _potentiallyMutated;
 | 
| -  Map<Node, Map<VariableElement, List<Node>>> _potentiallyMutatedIn;
 | 
| -  Map<VariableElement, List<Node>> _potentiallyMutatedInClosure;
 | 
| -  Map<Node, Map<VariableElement, List<Node>>> _accessedByClosureIn;
 | 
| -  Setlet<Element> _elements;
 | 
| -  Setlet<Send> _asserts;
 | 
| -
 | 
| -  /// Map from nodes to the targets they define.
 | 
| -  Map<Node, JumpTarget> _definedTargets;
 | 
| -
 | 
| -  /// Map from goto statements to their targets.
 | 
| -  Map<GotoStatement, JumpTarget> _usedTargets;
 | 
| -
 | 
| -  /// Map from labels to their label definition.
 | 
| -  Map<Label, LabelDefinition> _definedLabels;
 | 
| -
 | 
| -  /// Map from labeled goto statements to the labels they target.
 | 
| -  Map<GotoStatement, LabelDefinition> _targetLabels;
 | 
| -
 | 
| -  final int hashCode = ++_hashCodeCounter;
 | 
| -  static int _hashCodeCounter = 0;
 | 
| -
 | 
| -  TreeElementMapping(this.analyzedElement);
 | 
| -
 | 
| -  operator []=(Node node, Element element) {
 | 
| -    assert(invariant(node, () {
 | 
| -      FunctionExpression functionExpression = node.asFunctionExpression();
 | 
| -      if (functionExpression != null) {
 | 
| -        return !functionExpression.modifiers.isExternal;
 | 
| -      }
 | 
| -      return true;
 | 
| -    }));
 | 
| -    // TODO(johnniwinther): Simplify this invariant to use only declarations in
 | 
| -    // [TreeElements].
 | 
| -    assert(invariant(node, () {
 | 
| -      if (!element.isErroneous && analyzedElement != null && element.isPatch) {
 | 
| -        return analyzedElement.implementationLibrary.isPatch;
 | 
| -      }
 | 
| -      return true;
 | 
| -    }));
 | 
| -    // TODO(ahe): Investigate why the invariant below doesn't hold.
 | 
| -    // assert(invariant(node,
 | 
| -    //                  getTreeElement(node) == element ||
 | 
| -    //                  getTreeElement(node) == null,
 | 
| -    //                  message: '${getTreeElement(node)}; $element'));
 | 
| -
 | 
| -    if (_elements == null) {
 | 
| -      _elements = new Setlet<Element>();
 | 
| -    }
 | 
| -    _elements.add(element);
 | 
| -    setTreeElement(node, element);
 | 
| -  }
 | 
| -
 | 
| -  operator [](Node node) => getTreeElement(node);
 | 
| -
 | 
| -  void setType(Node node, DartType type) {
 | 
| -    if (_types == null) {
 | 
| -      _types = new Maplet<Node, DartType>();
 | 
| -    }
 | 
| -    _types[node] = type;
 | 
| -  }
 | 
| -
 | 
| -  DartType getType(Node node) => _types != null ? _types[node] : null;
 | 
| -
 | 
| -  Iterable<Node> get superUses {
 | 
| -    return _superUses != null ? _superUses : const <Node>[];
 | 
| -  }
 | 
| -
 | 
| -  void addSuperUse(Node node) {
 | 
| -    if (_superUses == null) {
 | 
| -      _superUses = new Setlet<Node>();
 | 
| -    }
 | 
| -    _superUses.add(node);
 | 
| -  }
 | 
| -
 | 
| -  Selector _getSelector(Spannable node) {
 | 
| -    return _selectors != null ? _selectors[node] : null;
 | 
| -  }
 | 
| -
 | 
| -  void _setSelector(Spannable node, Selector selector) {
 | 
| -    if (_selectors == null) {
 | 
| -      _selectors = new Maplet<Spannable, Selector>();
 | 
| -    }
 | 
| -    _selectors[node] = selector;
 | 
| -  }
 | 
| -
 | 
| -  void setSelector(Node node, Selector selector) {
 | 
| -    _setSelector(node, selector);
 | 
| -  }
 | 
| -
 | 
| -  Selector getSelector(Node node) => _getSelector(node);
 | 
| -
 | 
| -  int getSelectorCount() => _selectors == null ? 0 : _selectors.length;
 | 
| -
 | 
| -  void setGetterSelectorInComplexSendSet(SendSet node, Selector selector) {
 | 
| -    _setSelector(node.selector, selector);
 | 
| -  }
 | 
| -
 | 
| -  Selector getGetterSelectorInComplexSendSet(SendSet node) {
 | 
| -    return _getSelector(node.selector);
 | 
| -  }
 | 
| -
 | 
| -  void setOperatorSelectorInComplexSendSet(SendSet node, Selector selector) {
 | 
| -    _setSelector(node.assignmentOperator, selector);
 | 
| -  }
 | 
| -
 | 
| -  Selector getOperatorSelectorInComplexSendSet(SendSet node) {
 | 
| -    return _getSelector(node.assignmentOperator);
 | 
| -  }
 | 
| -
 | 
| -  // The following methods set selectors on the "for in" node. Since
 | 
| -  // we're using three selectors, we need to use children of the node,
 | 
| -  // and we arbitrarily choose which ones.
 | 
| -
 | 
| -  void setIteratorSelector(ForIn node, Selector selector) {
 | 
| -    _setSelector(node, selector);
 | 
| -  }
 | 
| -
 | 
| -  Selector getIteratorSelector(ForIn node) {
 | 
| -    return _getSelector(node);
 | 
| -  }
 | 
| -
 | 
| -  void setMoveNextSelector(ForIn node, Selector selector) {
 | 
| -    _setSelector(node.forToken, selector);
 | 
| -  }
 | 
| -
 | 
| -  Selector getMoveNextSelector(ForIn node) {
 | 
| -    return _getSelector(node.forToken);
 | 
| -  }
 | 
| -
 | 
| -  void setCurrentSelector(ForIn node, Selector selector) {
 | 
| -    _setSelector(node.inToken, selector);
 | 
| -  }
 | 
| -
 | 
| -  Selector getCurrentSelector(ForIn node) {
 | 
| -    return _getSelector(node.inToken);
 | 
| -  }
 | 
| -
 | 
| -  Element getForInVariable(ForIn node) {
 | 
| -    return this[node];
 | 
| -  }
 | 
| -
 | 
| -  void setConstant(Node node, ConstantExpression constant) {
 | 
| -    if (_constants == null) {
 | 
| -      _constants = new Maplet<Node, ConstantExpression>();
 | 
| -    }
 | 
| -    _constants[node] = constant;
 | 
| -  }
 | 
| -
 | 
| -  ConstantExpression getConstant(Node node) {
 | 
| -    return _constants != null ? _constants[node] : null;
 | 
| -  }
 | 
| -
 | 
| -  bool isTypeLiteral(Send node) {
 | 
| -    return getType(node) != null;
 | 
| -  }
 | 
| -
 | 
| -  DartType getTypeLiteralType(Send node) {
 | 
| -    return getType(node);
 | 
| -  }
 | 
| -
 | 
| -  void registerDependency(Element element) {
 | 
| -    if (element == null) return;
 | 
| -    if (_otherDependencies == null) {
 | 
| -      _otherDependencies = new Setlet<Element>();
 | 
| -    }
 | 
| -    _otherDependencies.add(element.implementation);
 | 
| -  }
 | 
| -
 | 
| -  Iterable<Element> get otherDependencies {
 | 
| -    return _otherDependencies != null ? _otherDependencies : const <Element>[];
 | 
| -  }
 | 
| -
 | 
| -  List<Node> getPotentialMutations(VariableElement element) {
 | 
| -    if (_potentiallyMutated == null) return const <Node>[];
 | 
| -    List<Node> mutations = _potentiallyMutated[element];
 | 
| -    if (mutations == null) return const <Node>[];
 | 
| -    return mutations;
 | 
| -  }
 | 
| -
 | 
| -  void registerPotentialMutation(VariableElement element, Node mutationNode) {
 | 
| -    if (_potentiallyMutated == null) {
 | 
| -      _potentiallyMutated = new Maplet<VariableElement, List<Node>>();
 | 
| -    }
 | 
| -    _potentiallyMutated.putIfAbsent(element, () => <Node>[]).add(mutationNode);
 | 
| -  }
 | 
| -
 | 
| -  List<Node> getPotentialMutationsIn(Node node, VariableElement element) {
 | 
| -    if (_potentiallyMutatedIn == null) return const <Node>[];
 | 
| -    Map<VariableElement, List<Node>> mutationsIn = _potentiallyMutatedIn[node];
 | 
| -    if (mutationsIn == null) return const <Node>[];
 | 
| -    List<Node> mutations = mutationsIn[element];
 | 
| -    if (mutations == null) return const <Node>[];
 | 
| -    return mutations;
 | 
| -  }
 | 
| -
 | 
| -  void registerPotentialMutationIn(Node contextNode, VariableElement element,
 | 
| -                                    Node mutationNode) {
 | 
| -    if (_potentiallyMutatedIn == null) {
 | 
| -      _potentiallyMutatedIn =
 | 
| -          new Maplet<Node, Map<VariableElement, List<Node>>>();
 | 
| -    }
 | 
| -    Map<VariableElement, List<Node>> mutationMap =
 | 
| -        _potentiallyMutatedIn.putIfAbsent(contextNode,
 | 
| -          () => new Maplet<VariableElement, List<Node>>());
 | 
| -    mutationMap.putIfAbsent(element, () => <Node>[]).add(mutationNode);
 | 
| -  }
 | 
| -
 | 
| -  List<Node> getPotentialMutationsInClosure(VariableElement element) {
 | 
| -    if (_potentiallyMutatedInClosure == null) return const <Node>[];
 | 
| -    List<Node> mutations = _potentiallyMutatedInClosure[element];
 | 
| -    if (mutations == null) return const <Node>[];
 | 
| -    return mutations;
 | 
| -  }
 | 
| -
 | 
| -  void registerPotentialMutationInClosure(VariableElement element,
 | 
| -                                          Node mutationNode) {
 | 
| -    if (_potentiallyMutatedInClosure == null) {
 | 
| -      _potentiallyMutatedInClosure = new Maplet<VariableElement, List<Node>>();
 | 
| -    }
 | 
| -    _potentiallyMutatedInClosure.putIfAbsent(
 | 
| -        element, () => <Node>[]).add(mutationNode);
 | 
| -  }
 | 
| -
 | 
| -  List<Node> getAccessesByClosureIn(Node node, VariableElement element) {
 | 
| -    if (_accessedByClosureIn == null) return const <Node>[];
 | 
| -    Map<VariableElement, List<Node>> accessesIn = _accessedByClosureIn[node];
 | 
| -    if (accessesIn == null) return const <Node>[];
 | 
| -    List<Node> accesses = accessesIn[element];
 | 
| -    if (accesses == null) return const <Node>[];
 | 
| -    return accesses;
 | 
| -  }
 | 
| -
 | 
| -  void setAccessedByClosureIn(Node contextNode, VariableElement element,
 | 
| -                              Node accessNode) {
 | 
| -    if (_accessedByClosureIn == null) {
 | 
| -      _accessedByClosureIn = new Map<Node, Map<VariableElement, List<Node>>>();
 | 
| -    }
 | 
| -    Map<VariableElement, List<Node>> accessMap =
 | 
| -        _accessedByClosureIn.putIfAbsent(contextNode,
 | 
| -          () => new Maplet<VariableElement, List<Node>>());
 | 
| -    accessMap.putIfAbsent(element, () => <Node>[]).add(accessNode);
 | 
| -  }
 | 
| -
 | 
| -  String toString() => 'TreeElementMapping($analyzedElement)';
 | 
| -
 | 
| -  Iterable<Element> get allElements {
 | 
| -    return _elements != null ? _elements : const <Element>[];
 | 
| -  }
 | 
| -
 | 
| -  void forEachConstantNode(f(Node n, ConstantExpression c)) {
 | 
| -    if (_constants != null) {
 | 
| -      _constants.forEach(f);
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  void setAssert(Send node) {
 | 
| -    if (_asserts == null) {
 | 
| -      _asserts = new Setlet<Send>();
 | 
| -    }
 | 
| -    _asserts.add(node);
 | 
| -  }
 | 
| -
 | 
| -  bool isAssert(Send node) {
 | 
| -    return _asserts != null && _asserts.contains(node);
 | 
| -  }
 | 
| -
 | 
| -  FunctionElement getFunctionDefinition(FunctionExpression node) {
 | 
| -    return this[node];
 | 
| -  }
 | 
| -
 | 
| -  ConstructorElement getRedirectingTargetConstructor(
 | 
| -      RedirectingFactoryBody node) {
 | 
| -    return this[node];
 | 
| -  }
 | 
| -
 | 
| -  void defineTarget(Node node, JumpTarget target) {
 | 
| -    if (_definedTargets == null) {
 | 
| -      _definedTargets = new Maplet<Node, JumpTarget>();
 | 
| -    }
 | 
| -    _definedTargets[node] = target;
 | 
| -  }
 | 
| -
 | 
| -  void undefineTarget(Node node) {
 | 
| -    if (_definedTargets != null) {
 | 
| -      _definedTargets.remove(node);
 | 
| -      if (_definedTargets.isEmpty) {
 | 
| -        _definedTargets = null;
 | 
| -      }
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  JumpTarget getTargetDefinition(Node node) {
 | 
| -    return _definedTargets != null ? _definedTargets[node] : null;
 | 
| -  }
 | 
| -
 | 
| -  void registerTargetOf(GotoStatement node, JumpTarget target) {
 | 
| -    if (_usedTargets == null) {
 | 
| -      _usedTargets = new Maplet<GotoStatement, JumpTarget>();
 | 
| -    }
 | 
| -    _usedTargets[node] = target;
 | 
| -  }
 | 
| -
 | 
| -  JumpTarget getTargetOf(GotoStatement node) {
 | 
| -    return _usedTargets != null ? _usedTargets[node] : null;
 | 
| -  }
 | 
| -
 | 
| -  void defineLabel(Label label, LabelDefinition target) {
 | 
| -    if (_definedLabels == null) {
 | 
| -      _definedLabels = new Maplet<Label, LabelDefinition>();
 | 
| -    }
 | 
| -    _definedLabels[label] = target;
 | 
| -  }
 | 
| -
 | 
| -  void undefineLabel(Label label) {
 | 
| -    if (_definedLabels != null) {
 | 
| -      _definedLabels.remove(label);
 | 
| -      if (_definedLabels.isEmpty) {
 | 
| -        _definedLabels = null;
 | 
| -      }
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  LabelDefinition getLabelDefinition(Label label) {
 | 
| -    return _definedLabels != null ? _definedLabels[label] : null;
 | 
| -  }
 | 
| -
 | 
| -  void registerTargetLabel(GotoStatement node, LabelDefinition label) {
 | 
| -    assert(node.target != null);
 | 
| -    if (_targetLabels == null) {
 | 
| -      _targetLabels = new Maplet<GotoStatement, LabelDefinition>();
 | 
| -    }
 | 
| -    _targetLabels[node] = label;
 | 
| -  }
 | 
| -
 | 
| -  LabelDefinition getTargetLabel(GotoStatement node) {
 | 
| -    assert(node.target != null);
 | 
| -    return _targetLabels != null ? _targetLabels[node] : null;
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -class ResolverTask extends CompilerTask {
 | 
| -  final ConstantCompiler constantCompiler;
 | 
| -
 | 
| -  ResolverTask(Compiler compiler, this.constantCompiler) : super(compiler);
 | 
| -
 | 
| -  String get name => 'Resolver';
 | 
| -
 | 
| -  TreeElements resolve(Element element) {
 | 
| -    return measure(() {
 | 
| -      if (Elements.isErroneousElement(element)) return null;
 | 
| -
 | 
| -      processMetadata([result]) {
 | 
| -        for (MetadataAnnotation metadata in element.metadata) {
 | 
| -          metadata.ensureResolved(compiler);
 | 
| -        }
 | 
| -        return result;
 | 
| -      }
 | 
| -
 | 
| -      ElementKind kind = element.kind;
 | 
| -      if (identical(kind, ElementKind.GENERATIVE_CONSTRUCTOR) ||
 | 
| -          identical(kind, ElementKind.FUNCTION) ||
 | 
| -          identical(kind, ElementKind.GETTER) ||
 | 
| -          identical(kind, ElementKind.SETTER)) {
 | 
| -        return processMetadata(resolveMethodElement(element));
 | 
| -      }
 | 
| -
 | 
| -      if (identical(kind, ElementKind.FIELD)) {
 | 
| -        return processMetadata(resolveField(element));
 | 
| -      }
 | 
| -      if (element.isClass) {
 | 
| -        ClassElement cls = element;
 | 
| -        cls.ensureResolved(compiler);
 | 
| -        return processMetadata();
 | 
| -      } else if (element.isTypedef) {
 | 
| -        TypedefElement typdef = element;
 | 
| -        return processMetadata(resolveTypedef(typdef));
 | 
| -      }
 | 
| -
 | 
| -      compiler.unimplemented(element, "resolve($element)");
 | 
| -    });
 | 
| -  }
 | 
| -
 | 
| -  void resolveRedirectingConstructor(InitializerResolver resolver,
 | 
| -                                     Node node,
 | 
| -                                     FunctionElement constructor,
 | 
| -                                     FunctionElement redirection) {
 | 
| -    assert(invariant(node, constructor.isImplementation,
 | 
| -        message: 'Redirecting constructors must be resolved on implementation '
 | 
| -                 'elements.'));
 | 
| -    Setlet<FunctionElement> seen = new Setlet<FunctionElement>();
 | 
| -    seen.add(constructor);
 | 
| -    while (redirection != null) {
 | 
| -      // Ensure that we follow redirections through implementation elements.
 | 
| -      redirection = redirection.implementation;
 | 
| -      if (seen.contains(redirection)) {
 | 
| -        resolver.visitor.error(node, MessageKind.REDIRECTING_CONSTRUCTOR_CYCLE);
 | 
| -        return;
 | 
| -      }
 | 
| -      seen.add(redirection);
 | 
| -      redirection = resolver.visitor.resolveConstructorRedirection(redirection);
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  void checkMatchingPatchParameters(FunctionElement origin,
 | 
| -                                    Link<Element> originParameters,
 | 
| -                                    Link<Element> patchParameters) {
 | 
| -    while (!originParameters.isEmpty) {
 | 
| -      ParameterElementX originParameter = originParameters.head;
 | 
| -      ParameterElementX patchParameter = patchParameters.head;
 | 
| -      // TODO(johnniwinther): Remove the conditional patching when we never
 | 
| -      // resolve the same method twice.
 | 
| -      if (!originParameter.isPatched) {
 | 
| -        originParameter.applyPatch(patchParameter);
 | 
| -      } else {
 | 
| -        assert(invariant(origin, originParameter.patch == patchParameter,
 | 
| -               message: "Inconsistent repatch of $originParameter."));
 | 
| -      }
 | 
| -      DartType originParameterType = originParameter.computeType(compiler);
 | 
| -      DartType patchParameterType = patchParameter.computeType(compiler);
 | 
| -      if (originParameterType != patchParameterType) {
 | 
| -        compiler.reportError(
 | 
| -            originParameter.parseNode(compiler),
 | 
| -            MessageKind.PATCH_PARAMETER_TYPE_MISMATCH,
 | 
| -            {'methodName': origin.name,
 | 
| -             'parameterName': originParameter.name,
 | 
| -             'originParameterType': originParameterType,
 | 
| -             'patchParameterType': patchParameterType});
 | 
| -        compiler.reportInfo(patchParameter,
 | 
| -            MessageKind.PATCH_POINT_TO_PARAMETER,
 | 
| -            {'parameterName': patchParameter.name});
 | 
| -      } else {
 | 
| -        // Hack: Use unparser to test parameter equality. This only works
 | 
| -        // because we are restricting patch uses and the approach cannot be used
 | 
| -        // elsewhere.
 | 
| -
 | 
| -        // The node contains the type, so there is a potential overlap.
 | 
| -        // Therefore we only check the text if the types are identical.
 | 
| -        String originParameterText =
 | 
| -            originParameter.parseNode(compiler).toString();
 | 
| -        String patchParameterText =
 | 
| -            patchParameter.parseNode(compiler).toString();
 | 
| -        if (originParameterText != patchParameterText
 | 
| -            // We special case the list constructor because of the
 | 
| -            // optional parameter.
 | 
| -            && origin != compiler.unnamedListConstructor) {
 | 
| -          compiler.reportError(
 | 
| -              originParameter.parseNode(compiler),
 | 
| -              MessageKind.PATCH_PARAMETER_MISMATCH,
 | 
| -              {'methodName': origin.name,
 | 
| -               'originParameter': originParameterText,
 | 
| -               'patchParameter': patchParameterText});
 | 
| -          compiler.reportInfo(patchParameter,
 | 
| -              MessageKind.PATCH_POINT_TO_PARAMETER,
 | 
| -              {'parameterName': patchParameter.name});
 | 
| -        }
 | 
| -      }
 | 
| -
 | 
| -      originParameters = originParameters.tail;
 | 
| -      patchParameters = patchParameters.tail;
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  void checkMatchingPatchSignatures(FunctionElement origin,
 | 
| -                                    FunctionElement patch) {
 | 
| -    // TODO(johnniwinther): Show both origin and patch locations on errors.
 | 
| -    FunctionExpression originTree = origin.node;
 | 
| -    FunctionSignature originSignature = origin.functionSignature;
 | 
| -    FunctionExpression patchTree = patch.node;
 | 
| -    FunctionSignature patchSignature = patch.functionSignature;
 | 
| -
 | 
| -    if (originSignature.type.returnType != patchSignature.type.returnType) {
 | 
| -      compiler.withCurrentElement(patch, () {
 | 
| -        Node errorNode =
 | 
| -            patchTree.returnType != null ? patchTree.returnType : patchTree;
 | 
| -        error(errorNode, MessageKind.PATCH_RETURN_TYPE_MISMATCH,
 | 
| -              {'methodName': origin.name,
 | 
| -               'originReturnType': originSignature.type.returnType,
 | 
| -               'patchReturnType': patchSignature.type.returnType});
 | 
| -      });
 | 
| -    }
 | 
| -    if (originSignature.requiredParameterCount !=
 | 
| -        patchSignature.requiredParameterCount) {
 | 
| -      compiler.withCurrentElement(patch, () {
 | 
| -        error(patchTree,
 | 
| -              MessageKind.PATCH_REQUIRED_PARAMETER_COUNT_MISMATCH,
 | 
| -              {'methodName': origin.name,
 | 
| -               'originParameterCount': originSignature.requiredParameterCount,
 | 
| -               'patchParameterCount': patchSignature.requiredParameterCount});
 | 
| -      });
 | 
| -    } else {
 | 
| -      checkMatchingPatchParameters(origin,
 | 
| -                                   originSignature.requiredParameters,
 | 
| -                                   patchSignature.requiredParameters);
 | 
| -    }
 | 
| -    if (originSignature.optionalParameterCount != 0 &&
 | 
| -        patchSignature.optionalParameterCount != 0) {
 | 
| -      if (originSignature.optionalParametersAreNamed !=
 | 
| -          patchSignature.optionalParametersAreNamed) {
 | 
| -        compiler.withCurrentElement(patch, () {
 | 
| -          error(patchTree,
 | 
| -                MessageKind.PATCH_OPTIONAL_PARAMETER_NAMED_MISMATCH,
 | 
| -                {'methodName': origin.name});
 | 
| -        });
 | 
| -      }
 | 
| -    }
 | 
| -    if (originSignature.optionalParameterCount !=
 | 
| -        patchSignature.optionalParameterCount) {
 | 
| -      compiler.withCurrentElement(patch, () {
 | 
| -        error(patchTree,
 | 
| -              MessageKind.PATCH_OPTIONAL_PARAMETER_COUNT_MISMATCH,
 | 
| -              {'methodName': origin.name,
 | 
| -               'originParameterCount': originSignature.optionalParameterCount,
 | 
| -               'patchParameterCount': patchSignature.optionalParameterCount});
 | 
| -      });
 | 
| -    } else {
 | 
| -      checkMatchingPatchParameters(origin,
 | 
| -                                   originSignature.optionalParameters,
 | 
| -                                   patchSignature.optionalParameters);
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  static void processAsyncMarker(Compiler compiler,
 | 
| -                                 BaseFunctionElementX element) {
 | 
| -    FunctionExpression functionExpression = element.node;
 | 
| -    AsyncModifier asyncModifier = functionExpression.asyncModifier;
 | 
| -    if (asyncModifier != null) {
 | 
| -      if (!compiler.enableAsyncAwait) {
 | 
| -        compiler.reportError(asyncModifier,
 | 
| -            MessageKind.EXPERIMENTAL_ASYNC_AWAIT,
 | 
| -            {'modifier': element.asyncMarker});
 | 
| -      } else if (!compiler.analyzeOnly) {
 | 
| -        compiler.reportError(asyncModifier,
 | 
| -            MessageKind.EXPERIMENTAL_ASYNC_AWAIT,
 | 
| -            {'modifier': element.asyncMarker});
 | 
| -      }
 | 
| -
 | 
| -      if (asyncModifier.isAsynchronous) {
 | 
| -        element.asyncMarker = asyncModifier.isYielding
 | 
| -            ? AsyncMarker.ASYNC_STAR : AsyncMarker.ASYNC;
 | 
| -      } else {
 | 
| -        element.asyncMarker = AsyncMarker.SYNC_STAR;
 | 
| -      }
 | 
| -      if (element.isAbstract) {
 | 
| -        compiler.reportError(asyncModifier,
 | 
| -            MessageKind.ASYNC_MODIFIER_ON_ABSTRACT_METHOD,
 | 
| -            {'modifier': element.asyncMarker});
 | 
| -      } else if (element.isConstructor) {
 | 
| -        compiler.reportError(asyncModifier,
 | 
| -            MessageKind.ASYNC_MODIFIER_ON_CONSTRUCTOR,
 | 
| -            {'modifier': element.asyncMarker});
 | 
| -      } else if (functionExpression.body.asReturn() != null &&
 | 
| -                 element.asyncMarker.isYielding) {
 | 
| -        compiler.reportError(asyncModifier,
 | 
| -            MessageKind.YIELDING_MODIFIER_ON_ARROW_BODY,
 | 
| -            {'modifier': element.asyncMarker});
 | 
| -      }
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  TreeElements resolveMethodElement(FunctionElementX element) {
 | 
| -    assert(invariant(element, element.isDeclaration));
 | 
| -    return compiler.withCurrentElement(element, () {
 | 
| -      bool isConstructor =
 | 
| -          identical(element.kind, ElementKind.GENERATIVE_CONSTRUCTOR);
 | 
| -      if (compiler.enqueuer.resolution.hasBeenResolved(element)) {
 | 
| -        // TODO(karlklose): Remove the check for [isConstructor]. [elememts]
 | 
| -        // should never be non-null, not even for constructors.
 | 
| -        assert(invariant(element, element.isConstructor,
 | 
| -            message: 'Non-constructor element $element '
 | 
| -                     'has already been analyzed.'));
 | 
| -        return element.resolvedAst.elements;
 | 
| -      }
 | 
| -      if (element.isSynthesized) {
 | 
| -        if (isConstructor) {
 | 
| -          ResolutionRegistry registry =
 | 
| -              new ResolutionRegistry(compiler, element);
 | 
| -          ConstructorElement constructor = element.asFunctionElement();
 | 
| -          ConstructorElement target = constructor.definingConstructor;
 | 
| -          // Ensure the signature of the synthesized element is
 | 
| -          // resolved. This is the only place where the resolver is
 | 
| -          // seeing this element.
 | 
| -          element.computeSignature(compiler);
 | 
| -          if (!target.isErroneous) {
 | 
| -            registry.registerStaticUse(target);
 | 
| -            registry.registerImplicitSuperCall(target);
 | 
| -          }
 | 
| -          return registry.mapping;
 | 
| -        } else {
 | 
| -          assert(element.isDeferredLoaderGetter);
 | 
| -          return _ensureTreeElements(element);
 | 
| -        }
 | 
| -      }
 | 
| -      element.parseNode(compiler);
 | 
| -      element.computeType(compiler);
 | 
| -      processAsyncMarker(compiler, element);
 | 
| -      if (element.isPatched) {
 | 
| -        FunctionElementX patch = element.patch;
 | 
| -        compiler.withCurrentElement(patch, () {
 | 
| -          patch.parseNode(compiler);
 | 
| -          patch.computeType(compiler);
 | 
| -        });
 | 
| -        checkMatchingPatchSignatures(element, patch);
 | 
| -        element = patch;
 | 
| -        processAsyncMarker(compiler, element);
 | 
| -      }
 | 
| -      return compiler.withCurrentElement(element, () {
 | 
| -        FunctionExpression tree = element.node;
 | 
| -        if (tree.modifiers.isExternal) {
 | 
| -          error(tree, MessageKind.PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION);
 | 
| -          return null;
 | 
| -        }
 | 
| -        if (isConstructor || element.isFactoryConstructor) {
 | 
| -          if (tree.returnType != null) {
 | 
| -            error(tree, MessageKind.CONSTRUCTOR_WITH_RETURN_TYPE);
 | 
| -          }
 | 
| -          if (element.modifiers.isConst &&
 | 
| -              tree.hasBody() &&
 | 
| -              !tree.isRedirectingFactory) {
 | 
| -            compiler.reportError(tree, MessageKind.CONST_CONSTRUCTOR_HAS_BODY);
 | 
| -          }
 | 
| -        }
 | 
| -
 | 
| -        ResolverVisitor visitor = visitorFor(element);
 | 
| -        ResolutionRegistry registry = visitor.registry;
 | 
| -        registry.defineFunction(tree, element);
 | 
| -        visitor.setupFunction(tree, element);
 | 
| -
 | 
| -        if (isConstructor && !element.isForwardingConstructor) {
 | 
| -          // Even if there is no initializer list we still have to do the
 | 
| -          // resolution in case there is an implicit super constructor call.
 | 
| -          InitializerResolver resolver = new InitializerResolver(visitor);
 | 
| -          FunctionElement redirection =
 | 
| -              resolver.resolveInitializers(element, tree);
 | 
| -          if (redirection != null) {
 | 
| -            resolveRedirectingConstructor(resolver, tree, element, redirection);
 | 
| -          }
 | 
| -        } else if (element.isForwardingConstructor) {
 | 
| -          // Initializers will be checked on the original constructor.
 | 
| -        } else if (tree.initializers != null) {
 | 
| -          error(tree, MessageKind.FUNCTION_WITH_INITIALIZER);
 | 
| -        }
 | 
| -
 | 
| -        if (!compiler.analyzeSignaturesOnly || tree.isRedirectingFactory) {
 | 
| -          // We need to analyze the redirecting factory bodies to ensure that
 | 
| -          // we can analyze compile-time constants.
 | 
| -          visitor.visit(tree.body);
 | 
| -        }
 | 
| -
 | 
| -        // Get the resolution tree and check that the resolved
 | 
| -        // function doesn't use 'super' if it is mixed into another
 | 
| -        // class. This is the part of the 'super' mixin check that
 | 
| -        // happens when a function is resolved after the mixin
 | 
| -        // application has been performed.
 | 
| -        TreeElements resolutionTree = registry.mapping;
 | 
| -        ClassElement enclosingClass = element.enclosingClass;
 | 
| -        if (enclosingClass != null) {
 | 
| -          // TODO(johnniwinther): Find another way to obtain mixin uses.
 | 
| -          Iterable<MixinApplicationElement> mixinUses =
 | 
| -              compiler.world.allMixinUsesOf(enclosingClass);
 | 
| -          ClassElement mixin = enclosingClass;
 | 
| -          for (MixinApplicationElement mixinApplication in mixinUses) {
 | 
| -            checkMixinSuperUses(resolutionTree, mixinApplication, mixin);
 | 
| -          }
 | 
| -        }
 | 
| -        return resolutionTree;
 | 
| -      });
 | 
| -    });
 | 
| -  }
 | 
| -
 | 
| -  /// Creates a [ResolverVisitor] for resolving an AST in context of [element].
 | 
| -  /// If [useEnclosingScope] is `true` then the initial scope of the visitor
 | 
| -  /// does not include inner scope of [element].
 | 
| -  ///
 | 
| -  /// This method should only be used by this library (or tests of
 | 
| -  /// this library).
 | 
| -  ResolverVisitor visitorFor(Element element, {bool useEnclosingScope: false}) {
 | 
| -    return new ResolverVisitor(compiler, element,
 | 
| -        new ResolutionRegistry(compiler, element),
 | 
| -        useEnclosingScope: useEnclosingScope);
 | 
| -  }
 | 
| -
 | 
| -  TreeElements resolveField(FieldElementX element) {
 | 
| -    VariableDefinitions tree = element.parseNode(compiler);
 | 
| -    if(element.modifiers.isStatic && element.isTopLevel) {
 | 
| -      error(element.modifiers.getStatic(),
 | 
| -            MessageKind.TOP_LEVEL_VARIABLE_DECLARED_STATIC);
 | 
| -    }
 | 
| -    ResolverVisitor visitor = visitorFor(element);
 | 
| -    ResolutionRegistry registry = visitor.registry;
 | 
| -    // TODO(johnniwinther): Maybe remove this when placeholderCollector migrates
 | 
| -    // to the backend ast.
 | 
| -    registry.defineElement(tree.definitions.nodes.head, element);
 | 
| -    // TODO(johnniwinther): Share the resolved type between all variables
 | 
| -    // declared in the same declaration.
 | 
| -    if (tree.type != null) {
 | 
| -      element.variables.type = visitor.resolveTypeAnnotation(tree.type);
 | 
| -    } else {
 | 
| -      element.variables.type = const DynamicType();
 | 
| -    }
 | 
| -
 | 
| -    Expression initializer = element.initializer;
 | 
| -    Modifiers modifiers = element.modifiers;
 | 
| -    if (initializer != null) {
 | 
| -      // TODO(johnniwinther): Avoid analyzing initializers if
 | 
| -      // [Compiler.analyzeSignaturesOnly] is set.
 | 
| -      visitor.visit(initializer);
 | 
| -    } else if (modifiers.isConst) {
 | 
| -      compiler.reportError(element, MessageKind.CONST_WITHOUT_INITIALIZER);
 | 
| -    } else if (modifiers.isFinal && !element.isInstanceMember) {
 | 
| -      compiler.reportError(element, MessageKind.FINAL_WITHOUT_INITIALIZER);
 | 
| -    } else {
 | 
| -      registry.registerInstantiatedClass(compiler.nullClass);
 | 
| -    }
 | 
| -
 | 
| -    if (Elements.isStaticOrTopLevelField(element)) {
 | 
| -      visitor.addDeferredAction(element, () {
 | 
| -        if (element.modifiers.isConst) {
 | 
| -          constantCompiler.compileConstant(element);
 | 
| -        } else {
 | 
| -          constantCompiler.compileVariable(element);
 | 
| -        }
 | 
| -      });
 | 
| -      if (initializer != null) {
 | 
| -        if (!element.modifiers.isConst) {
 | 
| -          // TODO(johnniwinther): Determine the const-ness eagerly to avoid
 | 
| -          // unnecessary registrations.
 | 
| -          registry.registerLazyField();
 | 
| -        }
 | 
| -      }
 | 
| -    }
 | 
| -
 | 
| -    // Perform various checks as side effect of "computing" the type.
 | 
| -    element.computeType(compiler);
 | 
| -
 | 
| -    return registry.mapping;
 | 
| -  }
 | 
| -
 | 
| -  DartType resolveTypeAnnotation(Element element, TypeAnnotation annotation) {
 | 
| -    DartType type = resolveReturnType(element, annotation);
 | 
| -    if (type.isVoid) {
 | 
| -      error(annotation, MessageKind.VOID_NOT_ALLOWED);
 | 
| -    }
 | 
| -    return type;
 | 
| -  }
 | 
| -
 | 
| -  DartType resolveReturnType(Element element, TypeAnnotation annotation) {
 | 
| -    if (annotation == null) return const DynamicType();
 | 
| -    DartType result = visitorFor(element).resolveTypeAnnotation(annotation);
 | 
| -    if (result == null) {
 | 
| -      // TODO(karklose): warning.
 | 
| -      return const DynamicType();
 | 
| -    }
 | 
| -    return result;
 | 
| -  }
 | 
| -
 | 
| -  void resolveRedirectionChain(ConstructorElementX constructor,
 | 
| -                               Spannable node) {
 | 
| -    ConstructorElementX target = constructor;
 | 
| -    InterfaceType targetType;
 | 
| -    List<Element> seen = new List<Element>();
 | 
| -    // Follow the chain of redirections and check for cycles.
 | 
| -    while (target.isRedirectingFactory) {
 | 
| -      if (target.internalEffectiveTarget != null) {
 | 
| -        // We found a constructor that already has been processed.
 | 
| -        targetType = target.effectiveTargetType;
 | 
| -        assert(invariant(target, targetType != null,
 | 
| -            message: 'Redirection target type has not been computed for '
 | 
| -                     '$target'));
 | 
| -        target = target.internalEffectiveTarget;
 | 
| -        break;
 | 
| -      }
 | 
| -
 | 
| -      Element nextTarget = target.immediateRedirectionTarget;
 | 
| -      if (seen.contains(nextTarget)) {
 | 
| -        error(node, MessageKind.CYCLIC_REDIRECTING_FACTORY);
 | 
| -        break;
 | 
| -      }
 | 
| -      seen.add(target);
 | 
| -      target = nextTarget;
 | 
| -    }
 | 
| -
 | 
| -    if (targetType == null) {
 | 
| -      assert(!target.isRedirectingFactory);
 | 
| -      targetType = target.enclosingClass.thisType;
 | 
| -    }
 | 
| -
 | 
| -    // [target] is now the actual target of the redirections.  Run through
 | 
| -    // the constructors again and set their [redirectionTarget], so that we
 | 
| -    // do not have to run the loop for these constructors again. Furthermore,
 | 
| -    // compute [redirectionTargetType] for each factory by computing the
 | 
| -    // substitution of the target type with respect to the factory type.
 | 
| -    while (!seen.isEmpty) {
 | 
| -      ConstructorElementX factory = seen.removeLast();
 | 
| -
 | 
| -      // [factory] must already be analyzed but the [TreeElements] might not
 | 
| -      // have been stored in the enqueuer cache yet.
 | 
| -      // TODO(johnniwinther): Store [TreeElements] in the cache before
 | 
| -      // resolution of the element.
 | 
| -      TreeElements treeElements = factory.treeElements;
 | 
| -      assert(invariant(node, treeElements != null,
 | 
| -          message: 'No TreeElements cached for $factory.'));
 | 
| -      FunctionExpression functionNode = factory.parseNode(compiler);
 | 
| -      RedirectingFactoryBody redirectionNode = functionNode.body;
 | 
| -      InterfaceType factoryType = treeElements.getType(redirectionNode);
 | 
| -
 | 
| -      targetType = targetType.substByContext(factoryType);
 | 
| -      factory.effectiveTarget = target;
 | 
| -      factory.effectiveTargetType = targetType;
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  /**
 | 
| -   * Load and resolve the supertypes of [cls].
 | 
| -   *
 | 
| -   * Warning: do not call this method directly. It should only be
 | 
| -   * called by [resolveClass] and [ClassSupertypeResolver].
 | 
| -   */
 | 
| -  void loadSupertypes(BaseClassElementX cls, Spannable from) {
 | 
| -    compiler.withCurrentElement(cls, () => measure(() {
 | 
| -      if (cls.supertypeLoadState == STATE_DONE) return;
 | 
| -      if (cls.supertypeLoadState == STATE_STARTED) {
 | 
| -        compiler.reportError(from, MessageKind.CYCLIC_CLASS_HIERARCHY,
 | 
| -                                 {'className': cls.name});
 | 
| -        cls.supertypeLoadState = STATE_DONE;
 | 
| -        cls.hasIncompleteHierarchy = true;
 | 
| -        cls.allSupertypesAndSelf =
 | 
| -            compiler.objectClass.allSupertypesAndSelf.extendClass(
 | 
| -                cls.computeType(compiler));
 | 
| -        cls.supertype = cls.allSupertypes.head;
 | 
| -        assert(invariant(from, cls.supertype != null,
 | 
| -            message: 'Missing supertype on cyclic class $cls.'));
 | 
| -        cls.interfaces = const Link<DartType>();
 | 
| -        return;
 | 
| -      }
 | 
| -      cls.supertypeLoadState = STATE_STARTED;
 | 
| -      compiler.withCurrentElement(cls, () {
 | 
| -        // TODO(ahe): Cache the node in cls.
 | 
| -        cls.parseNode(compiler).accept(
 | 
| -            new ClassSupertypeResolver(compiler, cls));
 | 
| -        if (cls.supertypeLoadState != STATE_DONE) {
 | 
| -          cls.supertypeLoadState = STATE_DONE;
 | 
| -        }
 | 
| -      });
 | 
| -    }));
 | 
| -  }
 | 
| -
 | 
| -  // TODO(johnniwinther): Remove this queue when resolution has been split into
 | 
| -  // syntax and semantic resolution.
 | 
| -  TypeDeclarationElement currentlyResolvedTypeDeclaration;
 | 
| -  Queue<ClassElement> pendingClassesToBeResolved = new Queue<ClassElement>();
 | 
| -  Queue<ClassElement> pendingClassesToBePostProcessed =
 | 
| -      new Queue<ClassElement>();
 | 
| -
 | 
| -  /// Resolve [element] using [resolveTypeDeclaration].
 | 
| -  ///
 | 
| -  /// This methods ensure that class declarations encountered through type
 | 
| -  /// annotations during the resolution of [element] are resolved after
 | 
| -  /// [element] has been resolved.
 | 
| -  // TODO(johnniwinther): Encapsulate this functionality in a
 | 
| -  // 'TypeDeclarationResolver'.
 | 
| -  _resolveTypeDeclaration(TypeDeclarationElement element,
 | 
| -                          resolveTypeDeclaration()) {
 | 
| -    return compiler.withCurrentElement(element, () {
 | 
| -      return measure(() {
 | 
| -        TypeDeclarationElement previousResolvedTypeDeclaration =
 | 
| -            currentlyResolvedTypeDeclaration;
 | 
| -        currentlyResolvedTypeDeclaration = element;
 | 
| -        var result = resolveTypeDeclaration();
 | 
| -        if (previousResolvedTypeDeclaration == null) {
 | 
| -          do {
 | 
| -            while (!pendingClassesToBeResolved.isEmpty) {
 | 
| -              pendingClassesToBeResolved.removeFirst().ensureResolved(compiler);
 | 
| -            }
 | 
| -            while (!pendingClassesToBePostProcessed.isEmpty) {
 | 
| -              _postProcessClassElement(
 | 
| -                  pendingClassesToBePostProcessed.removeFirst());
 | 
| -            }
 | 
| -          } while (!pendingClassesToBeResolved.isEmpty);
 | 
| -          assert(pendingClassesToBeResolved.isEmpty);
 | 
| -          assert(pendingClassesToBePostProcessed.isEmpty);
 | 
| -        }
 | 
| -        currentlyResolvedTypeDeclaration = previousResolvedTypeDeclaration;
 | 
| -        return result;
 | 
| -      });
 | 
| -    });
 | 
| -  }
 | 
| -
 | 
| -  /**
 | 
| -   * Resolve the class [element].
 | 
| -   *
 | 
| -   * Before calling this method, [element] was constructed by the
 | 
| -   * scanner and most fields are null or empty. This method fills in
 | 
| -   * these fields and also ensure that the supertypes of [element] are
 | 
| -   * resolved.
 | 
| -   *
 | 
| -   * Warning: Do not call this method directly. Instead use
 | 
| -   * [:element.ensureResolved(compiler):].
 | 
| -   */
 | 
| -  TreeElements resolveClass(BaseClassElementX element) {
 | 
| -    return _resolveTypeDeclaration(element, () {
 | 
| -      // TODO(johnniwinther): Store the mapping in the resolution enqueuer.
 | 
| -      ResolutionRegistry registry = new ResolutionRegistry(compiler, element);
 | 
| -      resolveClassInternal(element, registry);
 | 
| -      return element.treeElements;
 | 
| -    });
 | 
| -  }
 | 
| -
 | 
| -  void _ensureClassWillBeResolved(ClassElement element) {
 | 
| -    if (currentlyResolvedTypeDeclaration == null) {
 | 
| -      element.ensureResolved(compiler);
 | 
| -    } else {
 | 
| -      pendingClassesToBeResolved.add(element);
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  void resolveClassInternal(BaseClassElementX element,
 | 
| -                            ResolutionRegistry registry) {
 | 
| -    if (!element.isPatch) {
 | 
| -      compiler.withCurrentElement(element, () => measure(() {
 | 
| -        assert(element.resolutionState == STATE_NOT_STARTED);
 | 
| -        element.resolutionState = STATE_STARTED;
 | 
| -        Node tree = element.parseNode(compiler);
 | 
| -        loadSupertypes(element, tree);
 | 
| -
 | 
| -        ClassResolverVisitor visitor =
 | 
| -            new ClassResolverVisitor(compiler, element, registry);
 | 
| -        visitor.visit(tree);
 | 
| -        element.resolutionState = STATE_DONE;
 | 
| -        compiler.onClassResolved(element);
 | 
| -        pendingClassesToBePostProcessed.add(element);
 | 
| -      }));
 | 
| -      if (element.isPatched) {
 | 
| -        // Ensure handling patch after origin.
 | 
| -        element.patch.ensureResolved(compiler);
 | 
| -      }
 | 
| -    } else { // Handle patch classes:
 | 
| -      element.resolutionState = STATE_STARTED;
 | 
| -      // Ensure handling origin before patch.
 | 
| -      element.origin.ensureResolved(compiler);
 | 
| -      // Ensure that the type is computed.
 | 
| -      element.computeType(compiler);
 | 
| -      // Copy class hierarchy from origin.
 | 
| -      element.supertype = element.origin.supertype;
 | 
| -      element.interfaces = element.origin.interfaces;
 | 
| -      element.allSupertypesAndSelf = element.origin.allSupertypesAndSelf;
 | 
| -      // Stepwise assignment to ensure invariant.
 | 
| -      element.supertypeLoadState = STATE_STARTED;
 | 
| -      element.supertypeLoadState = STATE_DONE;
 | 
| -      element.resolutionState = STATE_DONE;
 | 
| -      // TODO(johnniwinther): Check matching type variables and
 | 
| -      // empty extends/implements clauses.
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  void _postProcessClassElement(BaseClassElementX element) {
 | 
| -    for (MetadataAnnotation metadata in element.metadata) {
 | 
| -      metadata.ensureResolved(compiler);
 | 
| -      if (!element.isProxy &&
 | 
| -          metadata.constant.value == compiler.proxyConstant) {
 | 
| -        element.isProxy = true;
 | 
| -      }
 | 
| -    }
 | 
| -
 | 
| -    // Force resolution of metadata on non-instance members since they may be
 | 
| -    // inspected by the backend while emitting. Metadata on instance members is
 | 
| -    // handled as a result of processing instantiated class members in the
 | 
| -    // enqueuer.
 | 
| -    // TODO(ahe): Avoid this eager resolution.
 | 
| -    element.forEachMember((_, Element member) {
 | 
| -      if (!member.isInstanceMember) {
 | 
| -        compiler.withCurrentElement(member, () {
 | 
| -          for (MetadataAnnotation metadata in member.metadata) {
 | 
| -            metadata.ensureResolved(compiler);
 | 
| -          }
 | 
| -        });
 | 
| -      }
 | 
| -    });
 | 
| -
 | 
| -    computeClassMember(element, Compiler.CALL_OPERATOR_NAME);
 | 
| -  }
 | 
| -
 | 
| -  void computeClassMembers(ClassElement element) {
 | 
| -    MembersCreator.computeAllClassMembers(compiler, element);
 | 
| -  }
 | 
| -
 | 
| -  void computeClassMember(ClassElement element, String name) {
 | 
| -    MembersCreator.computeClassMembersByName(compiler, element, name);
 | 
| -  }
 | 
| -
 | 
| -  void checkClass(ClassElement element) {
 | 
| -    computeClassMembers(element);
 | 
| -    if (element.isMixinApplication) {
 | 
| -      checkMixinApplication(element);
 | 
| -    } else {
 | 
| -      checkClassMembers(element);
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  void checkMixinApplication(MixinApplicationElementX mixinApplication) {
 | 
| -    Modifiers modifiers = mixinApplication.modifiers;
 | 
| -    int illegalFlags = modifiers.flags & ~Modifiers.FLAG_ABSTRACT;
 | 
| -    if (illegalFlags != 0) {
 | 
| -      Modifiers illegalModifiers = new Modifiers.withFlags(null, illegalFlags);
 | 
| -      compiler.reportError(
 | 
| -          modifiers,
 | 
| -          MessageKind.ILLEGAL_MIXIN_APPLICATION_MODIFIERS,
 | 
| -          {'modifiers': illegalModifiers});
 | 
| -    }
 | 
| -
 | 
| -    // In case of cyclic mixin applications, the mixin chain will have
 | 
| -    // been cut. If so, we have already reported the error to the
 | 
| -    // user so we just return from here.
 | 
| -    ClassElement mixin = mixinApplication.mixin;
 | 
| -    if (mixin == null) return;
 | 
| -
 | 
| -    // Check that we're not trying to use Object as a mixin.
 | 
| -    if (mixin.superclass == null) {
 | 
| -      compiler.reportError(mixinApplication,
 | 
| -                               MessageKind.ILLEGAL_MIXIN_OBJECT);
 | 
| -      // Avoid reporting additional errors for the Object class.
 | 
| -      return;
 | 
| -    }
 | 
| -
 | 
| -    // Check that the mixed in class has Object as its superclass.
 | 
| -    if (!mixin.superclass.isObject) {
 | 
| -      compiler.reportError(mixin, MessageKind.ILLEGAL_MIXIN_SUPERCLASS);
 | 
| -    }
 | 
| -
 | 
| -    // Check that the mixed in class doesn't have any constructors and
 | 
| -    // make sure we aren't mixing in methods that use 'super'.
 | 
| -    mixin.forEachLocalMember((AstElement member) {
 | 
| -      if (member.isGenerativeConstructor && !member.isSynthesized) {
 | 
| -        compiler.reportError(member, MessageKind.ILLEGAL_MIXIN_CONSTRUCTOR);
 | 
| -      } else {
 | 
| -        // Get the resolution tree and check that the resolved member
 | 
| -        // doesn't use 'super'. This is the part of the 'super' mixin
 | 
| -        // check that happens when a function is resolved before the
 | 
| -        // mixin application has been performed.
 | 
| -        // TODO(johnniwinther): Obtain the [TreeElements] for [member]
 | 
| -        // differently.
 | 
| -        if (compiler.enqueuer.resolution.hasBeenResolved(member)) {
 | 
| -          checkMixinSuperUses(
 | 
| -              member.resolvedAst.elements,
 | 
| -              mixinApplication,
 | 
| -              mixin);
 | 
| -        }
 | 
| -      }
 | 
| -    });
 | 
| -  }
 | 
| -
 | 
| -  void checkMixinSuperUses(TreeElements resolutionTree,
 | 
| -                           MixinApplicationElement mixinApplication,
 | 
| -                           ClassElement mixin) {
 | 
| -    // TODO(johnniwinther): Avoid the use of [TreeElements] here.
 | 
| -    if (resolutionTree == null) return;
 | 
| -    Iterable<Node> superUses = resolutionTree.superUses;
 | 
| -    if (superUses.isEmpty) return;
 | 
| -    compiler.reportError(mixinApplication,
 | 
| -                         MessageKind.ILLEGAL_MIXIN_WITH_SUPER,
 | 
| -                         {'className': mixin.name});
 | 
| -    // Show the user the problematic uses of 'super' in the mixin.
 | 
| -    for (Node use in superUses) {
 | 
| -      compiler.reportInfo(
 | 
| -          use,
 | 
| -          MessageKind.ILLEGAL_MIXIN_SUPER_USE);
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  void checkClassMembers(ClassElement cls) {
 | 
| -    assert(invariant(cls, cls.isDeclaration));
 | 
| -    if (cls.isObject) return;
 | 
| -    // TODO(johnniwinther): Should this be done on the implementation element as
 | 
| -    // well?
 | 
| -    List<Element> constConstructors = <Element>[];
 | 
| -    List<Element> nonFinalInstanceFields = <Element>[];
 | 
| -    cls.forEachMember((holder, member) {
 | 
| -      compiler.withCurrentElement(member, () {
 | 
| -        // Perform various checks as side effect of "computing" the type.
 | 
| -        member.computeType(compiler);
 | 
| -
 | 
| -        // Check modifiers.
 | 
| -        if (member.isFunction && member.modifiers.isFinal) {
 | 
| -          compiler.reportError(
 | 
| -              member, MessageKind.ILLEGAL_FINAL_METHOD_MODIFIER);
 | 
| -        }
 | 
| -        if (member.isConstructor) {
 | 
| -          final mismatchedFlagsBits =
 | 
| -              member.modifiers.flags &
 | 
| -              (Modifiers.FLAG_STATIC | Modifiers.FLAG_ABSTRACT);
 | 
| -          if (mismatchedFlagsBits != 0) {
 | 
| -            final mismatchedFlags =
 | 
| -                new Modifiers.withFlags(null, mismatchedFlagsBits);
 | 
| -            compiler.reportError(
 | 
| -                member,
 | 
| -                MessageKind.ILLEGAL_CONSTRUCTOR_MODIFIERS,
 | 
| -                {'modifiers': mismatchedFlags});
 | 
| -          }
 | 
| -          if (member.modifiers.isConst) {
 | 
| -            constConstructors.add(member);
 | 
| -          }
 | 
| -        }
 | 
| -        if (member.isField) {
 | 
| -          if (member.modifiers.isConst && !member.modifiers.isStatic) {
 | 
| -            compiler.reportError(
 | 
| -                member, MessageKind.ILLEGAL_CONST_FIELD_MODIFIER);
 | 
| -          }
 | 
| -          if (!member.modifiers.isStatic && !member.modifiers.isFinal) {
 | 
| -            nonFinalInstanceFields.add(member);
 | 
| -          }
 | 
| -        }
 | 
| -        checkAbstractField(member);
 | 
| -        checkUserDefinableOperator(member);
 | 
| -      });
 | 
| -    });
 | 
| -    if (!constConstructors.isEmpty && !nonFinalInstanceFields.isEmpty) {
 | 
| -      Spannable span = constConstructors.length > 1
 | 
| -          ? cls : constConstructors[0];
 | 
| -      compiler.reportError(span,
 | 
| -          MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS,
 | 
| -          {'className': cls.name});
 | 
| -      if (constConstructors.length > 1) {
 | 
| -        for (Element constructor in constConstructors) {
 | 
| -          compiler.reportInfo(constructor,
 | 
| -              MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_CONSTRUCTOR);
 | 
| -        }
 | 
| -      }
 | 
| -      for (Element field in nonFinalInstanceFields) {
 | 
| -        compiler.reportInfo(field,
 | 
| -            MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD);
 | 
| -      }
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  void checkAbstractField(Element member) {
 | 
| -    // Only check for getters. The test can only fail if there is both a setter
 | 
| -    // and a getter with the same name, and we only need to check each abstract
 | 
| -    // field once, so we just ignore setters.
 | 
| -    if (!member.isGetter) return;
 | 
| -
 | 
| -    // Find the associated abstract field.
 | 
| -    ClassElement classElement = member.enclosingClass;
 | 
| -    Element lookupElement = classElement.lookupLocalMember(member.name);
 | 
| -    if (lookupElement == null) {
 | 
| -      compiler.internalError(member,
 | 
| -          "No abstract field for accessor");
 | 
| -    } else if (!identical(lookupElement.kind, ElementKind.ABSTRACT_FIELD)) {
 | 
| -      compiler.internalError(member,
 | 
| -          "Inaccessible abstract field for accessor");
 | 
| -    }
 | 
| -    AbstractFieldElement field = lookupElement;
 | 
| -
 | 
| -    FunctionElementX getter = field.getter;
 | 
| -    if (getter == null) return;
 | 
| -    FunctionElementX setter = field.setter;
 | 
| -    if (setter == null) return;
 | 
| -    int getterFlags = getter.modifiers.flags | Modifiers.FLAG_ABSTRACT;
 | 
| -    int setterFlags = setter.modifiers.flags | Modifiers.FLAG_ABSTRACT;
 | 
| -    if (!identical(getterFlags, setterFlags)) {
 | 
| -      final mismatchedFlags =
 | 
| -        new Modifiers.withFlags(null, getterFlags ^ setterFlags);
 | 
| -      compiler.reportError(
 | 
| -          field.getter,
 | 
| -          MessageKind.GETTER_MISMATCH,
 | 
| -          {'modifiers': mismatchedFlags});
 | 
| -      compiler.reportError(
 | 
| -          field.setter,
 | 
| -          MessageKind.SETTER_MISMATCH,
 | 
| -          {'modifiers': mismatchedFlags});
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  void checkUserDefinableOperator(Element member) {
 | 
| -    FunctionElement function = member.asFunctionElement();
 | 
| -    if (function == null) return;
 | 
| -    String value = member.name;
 | 
| -    if (value == null) return;
 | 
| -    if (!(isUserDefinableOperator(value) || identical(value, 'unary-'))) return;
 | 
| -
 | 
| -    bool isMinus = false;
 | 
| -    int requiredParameterCount;
 | 
| -    MessageKind messageKind;
 | 
| -    if (identical(value, 'unary-')) {
 | 
| -      isMinus = true;
 | 
| -      messageKind = MessageKind.MINUS_OPERATOR_BAD_ARITY;
 | 
| -      requiredParameterCount = 0;
 | 
| -    } else if (isMinusOperator(value)) {
 | 
| -      isMinus = true;
 | 
| -      messageKind = MessageKind.MINUS_OPERATOR_BAD_ARITY;
 | 
| -      requiredParameterCount = 1;
 | 
| -    } else if (isUnaryOperator(value)) {
 | 
| -      messageKind = MessageKind.UNARY_OPERATOR_BAD_ARITY;
 | 
| -      requiredParameterCount = 0;
 | 
| -    } else if (isBinaryOperator(value)) {
 | 
| -      messageKind = MessageKind.BINARY_OPERATOR_BAD_ARITY;
 | 
| -      requiredParameterCount = 1;
 | 
| -      if (identical(value, '==')) checkOverrideHashCode(member);
 | 
| -    } else if (isTernaryOperator(value)) {
 | 
| -      messageKind = MessageKind.TERNARY_OPERATOR_BAD_ARITY;
 | 
| -      requiredParameterCount = 2;
 | 
| -    } else {
 | 
| -      compiler.internalError(function,
 | 
| -          'Unexpected user defined operator $value');
 | 
| -    }
 | 
| -    checkArity(function, requiredParameterCount, messageKind, isMinus);
 | 
| -  }
 | 
| -
 | 
| -  void checkOverrideHashCode(FunctionElement operatorEquals) {
 | 
| -    if (operatorEquals.isAbstract) return;
 | 
| -    ClassElement cls = operatorEquals.enclosingClass;
 | 
| -    Element hashCodeImplementation =
 | 
| -        cls.lookupLocalMember('hashCode');
 | 
| -    if (hashCodeImplementation != null) return;
 | 
| -    compiler.reportHint(
 | 
| -        operatorEquals, MessageKind.OVERRIDE_EQUALS_NOT_HASH_CODE,
 | 
| -        {'class': cls.name});
 | 
| -  }
 | 
| -
 | 
| -  void checkArity(FunctionElement function,
 | 
| -                  int requiredParameterCount, MessageKind messageKind,
 | 
| -                  bool isMinus) {
 | 
| -    FunctionExpression node = function.node;
 | 
| -    FunctionSignature signature = function.functionSignature;
 | 
| -    if (signature.requiredParameterCount != requiredParameterCount) {
 | 
| -      Node errorNode = node;
 | 
| -      if (node.parameters != null) {
 | 
| -        if (isMinus ||
 | 
| -            signature.requiredParameterCount < requiredParameterCount) {
 | 
| -          // If there are too few parameters, point to the whole parameter list.
 | 
| -          // For instance
 | 
| -          //
 | 
| -          //     int operator +() {}
 | 
| -          //                   ^^
 | 
| -          //
 | 
| -          //     int operator []=(value) {}
 | 
| -          //                     ^^^^^^^
 | 
| -          //
 | 
| -          // For operator -, always point the whole parameter list, like
 | 
| -          //
 | 
| -          //     int operator -(a, b) {}
 | 
| -          //                   ^^^^^^
 | 
| -          //
 | 
| -          // instead of
 | 
| -          //
 | 
| -          //     int operator -(a, b) {}
 | 
| -          //                       ^
 | 
| -          //
 | 
| -          // since the correction might not be to remove 'b' but instead to
 | 
| -          // remove 'a, b'.
 | 
| -          errorNode = node.parameters;
 | 
| -        } else {
 | 
| -          errorNode = node.parameters.nodes.skip(requiredParameterCount).head;
 | 
| -        }
 | 
| -      }
 | 
| -      compiler.reportError(
 | 
| -          errorNode, messageKind, {'operatorName': function.name});
 | 
| -    }
 | 
| -    if (signature.optionalParameterCount != 0) {
 | 
| -      Node errorNode =
 | 
| -          node.parameters.nodes.skip(signature.requiredParameterCount).head;
 | 
| -      if (signature.optionalParametersAreNamed) {
 | 
| -        compiler.reportError(
 | 
| -            errorNode,
 | 
| -            MessageKind.OPERATOR_NAMED_PARAMETERS,
 | 
| -            {'operatorName': function.name});
 | 
| -      } else {
 | 
| -        compiler.reportError(
 | 
| -            errorNode,
 | 
| -            MessageKind.OPERATOR_OPTIONAL_PARAMETERS,
 | 
| -            {'operatorName': function.name});
 | 
| -      }
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  reportErrorWithContext(Element errorneousElement,
 | 
| -                         MessageKind errorMessage,
 | 
| -                         Element contextElement,
 | 
| -                         MessageKind contextMessage) {
 | 
| -    compiler.reportError(
 | 
| -        errorneousElement,
 | 
| -        errorMessage,
 | 
| -        {'memberName': contextElement.name,
 | 
| -         'className': contextElement.enclosingClass.name});
 | 
| -    compiler.reportInfo(contextElement, contextMessage);
 | 
| -  }
 | 
| -
 | 
| -
 | 
| -  FunctionSignature resolveSignature(FunctionElementX element) {
 | 
| -    MessageKind defaultValuesError = null;
 | 
| -    if (element.isFactoryConstructor) {
 | 
| -      FunctionExpression body = element.parseNode(compiler);
 | 
| -      if (body.isRedirectingFactory) {
 | 
| -        defaultValuesError = MessageKind.REDIRECTING_FACTORY_WITH_DEFAULT;
 | 
| -      }
 | 
| -    }
 | 
| -    return compiler.withCurrentElement(element, () {
 | 
| -      FunctionExpression node =
 | 
| -          compiler.parser.measure(() => element.parseNode(compiler));
 | 
| -      return measure(() => SignatureResolver.analyze(
 | 
| -          compiler, node.parameters, node.returnType, element,
 | 
| -          new ResolutionRegistry(compiler, element),
 | 
| -          defaultValuesError: defaultValuesError,
 | 
| -          createRealParameters: true));
 | 
| -    });
 | 
| -  }
 | 
| -
 | 
| -  TreeElements resolveTypedef(TypedefElementX element) {
 | 
| -    if (element.isResolved) return element.treeElements;
 | 
| -    compiler.world.allTypedefs.add(element);
 | 
| -    return _resolveTypeDeclaration(element, () {
 | 
| -      ResolutionRegistry registry = new ResolutionRegistry(compiler, element);
 | 
| -      return compiler.withCurrentElement(element, () {
 | 
| -        return measure(() {
 | 
| -          assert(element.resolutionState == STATE_NOT_STARTED);
 | 
| -          element.resolutionState = STATE_STARTED;
 | 
| -          Typedef node =
 | 
| -            compiler.parser.measure(() => element.parseNode(compiler));
 | 
| -          TypedefResolverVisitor visitor =
 | 
| -            new TypedefResolverVisitor(compiler, element, registry);
 | 
| -          visitor.visit(node);
 | 
| -          element.resolutionState = STATE_DONE;
 | 
| -          return registry.mapping;
 | 
| -        });
 | 
| -      });
 | 
| -    });
 | 
| -  }
 | 
| -
 | 
| -  void resolveMetadataAnnotation(MetadataAnnotationX annotation) {
 | 
| -    compiler.withCurrentElement(annotation.annotatedElement, () => measure(() {
 | 
| -      assert(annotation.resolutionState == STATE_NOT_STARTED);
 | 
| -      annotation.resolutionState = STATE_STARTED;
 | 
| -
 | 
| -      Node node = annotation.parseNode(compiler);
 | 
| -      Element annotatedElement = annotation.annotatedElement;
 | 
| -      AnalyzableElement context = annotatedElement.analyzableElement;
 | 
| -      ClassElement classElement = annotatedElement.enclosingClass;
 | 
| -      if (classElement != null) {
 | 
| -        // The annotation is resolved in the scope of [classElement].
 | 
| -        classElement.ensureResolved(compiler);
 | 
| -      }
 | 
| -      assert(invariant(node, context != null,
 | 
| -          message: "No context found for metadata annotation "
 | 
| -                   "on $annotatedElement."));
 | 
| -      ResolverVisitor visitor = visitorFor(context, useEnclosingScope: true);
 | 
| -      ResolutionRegistry registry = visitor.registry;
 | 
| -      node.accept(visitor);
 | 
| -      // TODO(johnniwinther): Avoid passing the [TreeElements] to
 | 
| -      // [compileMetadata].
 | 
| -      annotation.constant =
 | 
| -          constantCompiler.compileMetadata(annotation, node, registry.mapping);
 | 
| -      // TODO(johnniwinther): Register the relation between the annotation
 | 
| -      // and the annotated element instead. This will allow the backend to
 | 
| -      // retrieve the backend constant and only register metadata on the
 | 
| -      // elements for which it is needed. (Issue 17732).
 | 
| -      registry.registerMetadataConstant(annotation, annotatedElement);
 | 
| -      annotation.resolutionState = STATE_DONE;
 | 
| -    }));
 | 
| -  }
 | 
| -
 | 
| -  error(Spannable node, MessageKind kind, [arguments = const {}]) {
 | 
| -    // TODO(ahe): Make non-fatal.
 | 
| -    compiler.reportFatalError(node, kind, arguments);
 | 
| -  }
 | 
| -
 | 
| -  Link<MetadataAnnotation> resolveMetadata(Element element,
 | 
| -                                           VariableDefinitions node) {
 | 
| -    LinkBuilder<MetadataAnnotation> metadata =
 | 
| -        new LinkBuilder<MetadataAnnotation>();
 | 
| -    for (Metadata annotation in node.metadata.nodes) {
 | 
| -      ParameterMetadataAnnotation metadataAnnotation =
 | 
| -          new ParameterMetadataAnnotation(annotation);
 | 
| -      metadataAnnotation.annotatedElement = element;
 | 
| -      metadata.addLast(metadataAnnotation.ensureResolved(compiler));
 | 
| -    }
 | 
| -    return metadata.toLink();
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -class InitializerResolver {
 | 
| -  final ResolverVisitor visitor;
 | 
| -  final Map<Element, Node> initialized;
 | 
| -  Link<Node> initializers;
 | 
| -  bool hasSuper;
 | 
| -
 | 
| -  InitializerResolver(this.visitor)
 | 
| -    : initialized = new Map<Element, Node>(), hasSuper = false;
 | 
| -
 | 
| -  ResolutionRegistry get registry => visitor.registry;
 | 
| -
 | 
| -  error(Node node, MessageKind kind, [arguments = const {}]) {
 | 
| -    visitor.error(node, kind, arguments);
 | 
| -  }
 | 
| -
 | 
| -  warning(Node node, MessageKind kind, [arguments = const {}]) {
 | 
| -    visitor.warning(node, kind, arguments);
 | 
| -  }
 | 
| -
 | 
| -  bool isFieldInitializer(SendSet node) {
 | 
| -    if (node.selector.asIdentifier() == null) return false;
 | 
| -    if (node.receiver == null) return true;
 | 
| -    if (node.receiver.asIdentifier() == null) return false;
 | 
| -    return node.receiver.asIdentifier().isThis();
 | 
| -  }
 | 
| -
 | 
| -  reportDuplicateInitializerError(Element field, Node init, Node existing) {
 | 
| -    visitor.compiler.reportError(
 | 
| -        init,
 | 
| -        MessageKind.DUPLICATE_INITIALIZER, {'fieldName': field.name});
 | 
| -    visitor.compiler.reportInfo(
 | 
| -        existing,
 | 
| -        MessageKind.ALREADY_INITIALIZED, {'fieldName': field.name});
 | 
| -  }
 | 
| -
 | 
| -  void checkForDuplicateInitializers(FieldElementX field, Node init) {
 | 
| -    // [field] can be null if it could not be resolved.
 | 
| -    if (field == null) return;
 | 
| -    String name = field.name;
 | 
| -    if (initialized.containsKey(field)) {
 | 
| -      reportDuplicateInitializerError(field, init, initialized[field]);
 | 
| -    } else if (field.isFinal) {
 | 
| -      field.parseNode(visitor.compiler);
 | 
| -      Expression initializer = field.initializer;
 | 
| -      if (initializer != null) {
 | 
| -        reportDuplicateInitializerError(field, init, initializer);
 | 
| -      }
 | 
| -    }
 | 
| -    initialized[field] = init;
 | 
| -  }
 | 
| -
 | 
| -  void resolveFieldInitializer(FunctionElement constructor, SendSet init) {
 | 
| -    // init is of the form [this.]field = value.
 | 
| -    final Node selector = init.selector;
 | 
| -    final String name = selector.asIdentifier().source;
 | 
| -    // Lookup target field.
 | 
| -    Element target;
 | 
| -    if (isFieldInitializer(init)) {
 | 
| -      target = constructor.enclosingClass.lookupLocalMember(name);
 | 
| -      if (target == null) {
 | 
| -        error(selector, MessageKind.CANNOT_RESOLVE, {'name': name});
 | 
| -      } else if (target.kind != ElementKind.FIELD) {
 | 
| -        error(selector, MessageKind.NOT_A_FIELD, {'fieldName': name});
 | 
| -      } else if (!target.isInstanceMember) {
 | 
| -        error(selector, MessageKind.INIT_STATIC_FIELD, {'fieldName': name});
 | 
| -      }
 | 
| -    } else {
 | 
| -      error(init, MessageKind.INVALID_RECEIVER_IN_INITIALIZER);
 | 
| -    }
 | 
| -    registry.useElement(init, target);
 | 
| -    registry.registerStaticUse(target);
 | 
| -    checkForDuplicateInitializers(target, init);
 | 
| -    // Resolve initializing value.
 | 
| -    visitor.visitInStaticContext(init.arguments.head);
 | 
| -  }
 | 
| -
 | 
| -  ClassElement getSuperOrThisLookupTarget(FunctionElement constructor,
 | 
| -                                          bool isSuperCall,
 | 
| -                                          Node diagnosticNode) {
 | 
| -    ClassElement lookupTarget = constructor.enclosingClass;
 | 
| -    if (isSuperCall) {
 | 
| -      // Calculate correct lookup target and constructor name.
 | 
| -      if (identical(lookupTarget, visitor.compiler.objectClass)) {
 | 
| -        error(diagnosticNode, MessageKind.SUPER_INITIALIZER_IN_OBJECT);
 | 
| -      } else {
 | 
| -        return lookupTarget.supertype.element;
 | 
| -      }
 | 
| -    }
 | 
| -    return lookupTarget;
 | 
| -  }
 | 
| -
 | 
| -  Element resolveSuperOrThisForSend(FunctionElement constructor,
 | 
| -                                    FunctionExpression functionNode,
 | 
| -                                    Send call) {
 | 
| -    // Resolve the selector and the arguments.
 | 
| -    ResolverTask resolver = visitor.compiler.resolver;
 | 
| -    visitor.inStaticContext(() {
 | 
| -      visitor.resolveSelector(call, null);
 | 
| -      visitor.resolveArguments(call.argumentsNode);
 | 
| -    });
 | 
| -    Selector selector = registry.getSelector(call);
 | 
| -    bool isSuperCall = Initializers.isSuperConstructorCall(call);
 | 
| -
 | 
| -    ClassElement lookupTarget = getSuperOrThisLookupTarget(constructor,
 | 
| -                                                           isSuperCall,
 | 
| -                                                           call);
 | 
| -    Selector constructorSelector =
 | 
| -        visitor.getRedirectingThisOrSuperConstructorSelector(call);
 | 
| -    FunctionElement calledConstructor =
 | 
| -        lookupTarget.lookupConstructor(constructorSelector);
 | 
| -
 | 
| -    final bool isImplicitSuperCall = false;
 | 
| -    final String className = lookupTarget.name;
 | 
| -    verifyThatConstructorMatchesCall(constructor,
 | 
| -                                     calledConstructor,
 | 
| -                                     selector,
 | 
| -                                     isImplicitSuperCall,
 | 
| -                                     call,
 | 
| -                                     className,
 | 
| -                                     constructorSelector);
 | 
| -
 | 
| -    registry.useElement(call, calledConstructor);
 | 
| -    registry.registerStaticUse(calledConstructor);
 | 
| -    return calledConstructor;
 | 
| -  }
 | 
| -
 | 
| -  void resolveImplicitSuperConstructorSend(FunctionElement constructor,
 | 
| -                                           FunctionExpression functionNode) {
 | 
| -    // If the class has a super resolve the implicit super call.
 | 
| -    ClassElement classElement = constructor.enclosingClass;
 | 
| -    ClassElement superClass = classElement.superclass;
 | 
| -    if (classElement != visitor.compiler.objectClass) {
 | 
| -      assert(superClass != null);
 | 
| -      assert(superClass.resolutionState == STATE_DONE);
 | 
| -      String constructorName = '';
 | 
| -      Selector callToMatch = new Selector.call(
 | 
| -          constructorName,
 | 
| -          classElement.library,
 | 
| -          0);
 | 
| -
 | 
| -      final bool isSuperCall = true;
 | 
| -      ClassElement lookupTarget = getSuperOrThisLookupTarget(constructor,
 | 
| -                                                             isSuperCall,
 | 
| -                                                             functionNode);
 | 
| -      Selector constructorSelector = new Selector.callDefaultConstructor(
 | 
| -          visitor.enclosingElement.library);
 | 
| -      Element calledConstructor = lookupTarget.lookupConstructor(
 | 
| -          constructorSelector);
 | 
| -
 | 
| -      final String className = lookupTarget.name;
 | 
| -      final bool isImplicitSuperCall = true;
 | 
| -      verifyThatConstructorMatchesCall(constructor,
 | 
| -                                       calledConstructor,
 | 
| -                                       callToMatch,
 | 
| -                                       isImplicitSuperCall,
 | 
| -                                       functionNode,
 | 
| -                                       className,
 | 
| -                                       constructorSelector);
 | 
| -      registry.registerImplicitSuperCall(calledConstructor);
 | 
| -      registry.registerStaticUse(calledConstructor);
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  void verifyThatConstructorMatchesCall(
 | 
| -      FunctionElement caller,
 | 
| -      FunctionElement lookedupConstructor,
 | 
| -      Selector call,
 | 
| -      bool isImplicitSuperCall,
 | 
| -      Node diagnosticNode,
 | 
| -      String className,
 | 
| -      Selector constructorSelector) {
 | 
| -    if (lookedupConstructor == null
 | 
| -        || !lookedupConstructor.isGenerativeConstructor) {
 | 
| -      String fullConstructorName = Elements.constructorNameForDiagnostics(
 | 
| -              className,
 | 
| -              constructorSelector.name);
 | 
| -      MessageKind kind = isImplicitSuperCall
 | 
| -          ? MessageKind.CANNOT_RESOLVE_CONSTRUCTOR_FOR_IMPLICIT
 | 
| -          : MessageKind.CANNOT_RESOLVE_CONSTRUCTOR;
 | 
| -      visitor.compiler.reportError(
 | 
| -          diagnosticNode, kind, {'constructorName': fullConstructorName});
 | 
| -    } else {
 | 
| -      lookedupConstructor.computeSignature(visitor.compiler);
 | 
| -      if (!call.applies(lookedupConstructor, visitor.compiler.world)) {
 | 
| -        MessageKind kind = isImplicitSuperCall
 | 
| -                           ? MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT
 | 
| -                           : MessageKind.NO_MATCHING_CONSTRUCTOR;
 | 
| -        visitor.compiler.reportError(diagnosticNode, kind);
 | 
| -      } else if (caller.isConst
 | 
| -                 && !lookedupConstructor.isConst) {
 | 
| -        visitor.compiler.reportError(
 | 
| -            diagnosticNode, MessageKind.CONST_CALLS_NON_CONST);
 | 
| -      }
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  /**
 | 
| -   * Resolve all initializers of this constructor. In the case of a redirecting
 | 
| -   * constructor, the resolved constructor's function element is returned.
 | 
| -   */
 | 
| -  FunctionElement resolveInitializers(FunctionElement constructor,
 | 
| -                                      FunctionExpression functionNode) {
 | 
| -    // Keep track of all "this.param" parameters specified for constructor so
 | 
| -    // that we can ensure that fields are initialized only once.
 | 
| -    FunctionSignature functionParameters = constructor.functionSignature;
 | 
| -    functionParameters.forEachParameter((ParameterElement element) {
 | 
| -      if (element.isInitializingFormal) {
 | 
| -        InitializingFormalElement initializingFormal = element;
 | 
| -        checkForDuplicateInitializers(initializingFormal.fieldElement,
 | 
| -                                      element.initializer);
 | 
| -      }
 | 
| -    });
 | 
| -
 | 
| -    if (functionNode.initializers == null) {
 | 
| -      initializers = const Link<Node>();
 | 
| -    } else {
 | 
| -      initializers = functionNode.initializers.nodes;
 | 
| -    }
 | 
| -    FunctionElement result;
 | 
| -    bool resolvedSuper = false;
 | 
| -    for (Link<Node> link = initializers; !link.isEmpty; link = link.tail) {
 | 
| -      if (link.head.asSendSet() != null) {
 | 
| -        final SendSet init = link.head.asSendSet();
 | 
| -        resolveFieldInitializer(constructor, init);
 | 
| -      } else if (link.head.asSend() != null) {
 | 
| -        final Send call = link.head.asSend();
 | 
| -        if (call.argumentsNode == null) {
 | 
| -          error(link.head, MessageKind.INVALID_INITIALIZER);
 | 
| -          continue;
 | 
| -        }
 | 
| -        if (Initializers.isSuperConstructorCall(call)) {
 | 
| -          if (resolvedSuper) {
 | 
| -            error(call, MessageKind.DUPLICATE_SUPER_INITIALIZER);
 | 
| -          }
 | 
| -          resolveSuperOrThisForSend(constructor, functionNode, call);
 | 
| -          resolvedSuper = true;
 | 
| -        } else if (Initializers.isConstructorRedirect(call)) {
 | 
| -          // Check that there is no body (Language specification 7.5.1).  If the
 | 
| -          // constructor is also const, we already reported an error in
 | 
| -          // [resolveMethodElement].
 | 
| -          if (functionNode.hasBody() && !constructor.isConst) {
 | 
| -            error(functionNode, MessageKind.REDIRECTING_CONSTRUCTOR_HAS_BODY);
 | 
| -          }
 | 
| -          // Check that there are no other initializers.
 | 
| -          if (!initializers.tail.isEmpty) {
 | 
| -            error(call, MessageKind.REDIRECTING_CONSTRUCTOR_HAS_INITIALIZER);
 | 
| -          }
 | 
| -          // Check that there are no field initializing parameters.
 | 
| -          Compiler compiler = visitor.compiler;
 | 
| -          FunctionSignature signature = constructor.functionSignature;
 | 
| -          signature.forEachParameter((ParameterElement parameter) {
 | 
| -            if (parameter.isInitializingFormal) {
 | 
| -              Node node = parameter.node;
 | 
| -              error(node, MessageKind.INITIALIZING_FORMAL_NOT_ALLOWED);
 | 
| -            }
 | 
| -          });
 | 
| -          return resolveSuperOrThisForSend(constructor, functionNode, call);
 | 
| -        } else {
 | 
| -          visitor.error(call, MessageKind.CONSTRUCTOR_CALL_EXPECTED);
 | 
| -          return null;
 | 
| -        }
 | 
| -      } else {
 | 
| -        error(link.head, MessageKind.INVALID_INITIALIZER);
 | 
| -      }
 | 
| -    }
 | 
| -    if (!resolvedSuper) {
 | 
| -      resolveImplicitSuperConstructorSend(constructor, functionNode);
 | 
| -    }
 | 
| -    return null;  // If there was no redirection always return null.
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -class CommonResolverVisitor<R> extends Visitor<R> {
 | 
| -  final Compiler compiler;
 | 
| -
 | 
| -  CommonResolverVisitor(Compiler this.compiler);
 | 
| -
 | 
| -  R visitNode(Node node) {
 | 
| -    internalError(node,
 | 
| -        'internal error: Unhandled node: ${node.getObjectDescription()}');
 | 
| -    return null;
 | 
| -  }
 | 
| -
 | 
| -  R visitEmptyStatement(Node node) => null;
 | 
| -
 | 
| -  /** Convenience method for visiting nodes that may be null. */
 | 
| -  R visit(Node node) => (node == null) ? null : node.accept(this);
 | 
| -
 | 
| -  void error(Spannable node, MessageKind kind, [Map arguments = const {}]) {
 | 
| -    compiler.reportFatalError(node, kind, arguments);
 | 
| -  }
 | 
| -
 | 
| -  void warning(Spannable node, MessageKind kind, [Map arguments = const {}]) {
 | 
| -    compiler.reportWarning(node, kind, arguments);
 | 
| -  }
 | 
| -
 | 
| -  void internalError(Spannable node, message) {
 | 
| -    compiler.internalError(node, message);
 | 
| -  }
 | 
| -
 | 
| -  void addDeferredAction(Element element, DeferredAction action) {
 | 
| -    compiler.enqueuer.resolution.addDeferredAction(element, action);
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -abstract class LabelScope {
 | 
| -  LabelScope get outer;
 | 
| -  LabelDefinition lookup(String label);
 | 
| -}
 | 
| -
 | 
| -class LabeledStatementLabelScope implements LabelScope {
 | 
| -  final LabelScope outer;
 | 
| -  final Map<String, LabelDefinition> labels;
 | 
| -  LabeledStatementLabelScope(this.outer, this.labels);
 | 
| -  LabelDefinition lookup(String labelName) {
 | 
| -    LabelDefinition label = labels[labelName];
 | 
| -    if (label != null) return label;
 | 
| -    return outer.lookup(labelName);
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -class SwitchLabelScope implements LabelScope {
 | 
| -  final LabelScope outer;
 | 
| -  final Map<String, LabelDefinition> caseLabels;
 | 
| -
 | 
| -  SwitchLabelScope(this.outer, this.caseLabels);
 | 
| -
 | 
| -  LabelDefinition lookup(String labelName) {
 | 
| -    LabelDefinition result = caseLabels[labelName];
 | 
| -    if (result != null) return result;
 | 
| -    return outer.lookup(labelName);
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -class EmptyLabelScope implements LabelScope {
 | 
| -  const EmptyLabelScope();
 | 
| -  LabelDefinition lookup(String label) => null;
 | 
| -  LabelScope get outer {
 | 
| -    throw 'internal error: empty label scope has no outer';
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -class StatementScope {
 | 
| -  LabelScope labels;
 | 
| -  Link<JumpTarget> breakTargetStack;
 | 
| -  Link<JumpTarget> continueTargetStack;
 | 
| -  // Used to provide different numbers to statements if one is inside the other.
 | 
| -  // Can be used to make otherwise duplicate labels unique.
 | 
| -  int nestingLevel = 0;
 | 
| -
 | 
| -  StatementScope()
 | 
| -      : labels = const EmptyLabelScope(),
 | 
| -        breakTargetStack = const Link<JumpTarget>(),
 | 
| -        continueTargetStack = const Link<JumpTarget>();
 | 
| -
 | 
| -  LabelDefinition lookupLabel(String label) {
 | 
| -    return labels.lookup(label);
 | 
| -  }
 | 
| -
 | 
| -  JumpTarget currentBreakTarget() =>
 | 
| -    breakTargetStack.isEmpty ? null : breakTargetStack.head;
 | 
| -
 | 
| -  JumpTarget currentContinueTarget() =>
 | 
| -    continueTargetStack.isEmpty ? null : continueTargetStack.head;
 | 
| -
 | 
| -  void enterLabelScope(Map<String, LabelDefinition> elements) {
 | 
| -    labels = new LabeledStatementLabelScope(labels, elements);
 | 
| -    nestingLevel++;
 | 
| -  }
 | 
| -
 | 
| -  void exitLabelScope() {
 | 
| -    nestingLevel--;
 | 
| -    labels = labels.outer;
 | 
| -  }
 | 
| -
 | 
| -  void enterLoop(JumpTarget element) {
 | 
| -    breakTargetStack = breakTargetStack.prepend(element);
 | 
| -    continueTargetStack = continueTargetStack.prepend(element);
 | 
| -    nestingLevel++;
 | 
| -  }
 | 
| -
 | 
| -  void exitLoop() {
 | 
| -    nestingLevel--;
 | 
| -    breakTargetStack = breakTargetStack.tail;
 | 
| -    continueTargetStack = continueTargetStack.tail;
 | 
| -  }
 | 
| -
 | 
| -  void enterSwitch(JumpTarget breakElement,
 | 
| -                   Map<String, LabelDefinition> continueElements) {
 | 
| -    breakTargetStack = breakTargetStack.prepend(breakElement);
 | 
| -    labels = new SwitchLabelScope(labels, continueElements);
 | 
| -    nestingLevel++;
 | 
| -  }
 | 
| -
 | 
| -  void exitSwitch() {
 | 
| -    nestingLevel--;
 | 
| -    breakTargetStack = breakTargetStack.tail;
 | 
| -    labels = labels.outer;
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -class TypeResolver {
 | 
| -  final Compiler compiler;
 | 
| -
 | 
| -  TypeResolver(this.compiler);
 | 
| -
 | 
| -  /// Tries to resolve the type name as an element.
 | 
| -  Element resolveTypeName(Identifier prefixName,
 | 
| -                          Identifier typeName,
 | 
| -                          Scope scope,
 | 
| -                          {bool deferredIsMalformed: true}) {
 | 
| -    Element element;
 | 
| -    bool deferredTypeAnnotation = false;
 | 
| -    if (prefixName != null) {
 | 
| -      Element prefixElement =
 | 
| -          lookupInScope(compiler, prefixName, scope, prefixName.source);
 | 
| -      if (prefixElement != null && prefixElement.isPrefix) {
 | 
| -        // The receiver is a prefix. Lookup in the imported members.
 | 
| -        PrefixElement prefix = prefixElement;
 | 
| -        element = prefix.lookupLocalMember(typeName.source);
 | 
| -        // TODO(17260, sigurdm): The test for DartBackend is there because
 | 
| -        // dart2dart outputs malformed types with prefix.
 | 
| -        if (element != null &&
 | 
| -            prefix.isDeferred &&
 | 
| -            deferredIsMalformed &&
 | 
| -            compiler.backend is! DartBackend) {
 | 
| -          element = new ErroneousElementX(MessageKind.DEFERRED_TYPE_ANNOTATION,
 | 
| -                                          {'node': typeName},
 | 
| -                                          element.name,
 | 
| -                                          element);
 | 
| -        }
 | 
| -      } else {
 | 
| -        // The caller of this method will create the ErroneousElement for
 | 
| -        // the MalformedType.
 | 
| -        element = null;
 | 
| -      }
 | 
| -    } else {
 | 
| -      String stringValue = typeName.source;
 | 
| -      element = lookupInScope(compiler, typeName, scope, typeName.source);
 | 
| -    }
 | 
| -    return element;
 | 
| -  }
 | 
| -
 | 
| -  DartType resolveTypeAnnotation(MappingVisitor visitor, TypeAnnotation node,
 | 
| -                                 {bool malformedIsError: false,
 | 
| -                                  bool deferredIsMalformed: true}) {
 | 
| -    ResolutionRegistry registry = visitor.registry;
 | 
| -
 | 
| -    Identifier typeName;
 | 
| -    DartType type;
 | 
| -
 | 
| -    DartType checkNoTypeArguments(DartType type) {
 | 
| -      List<DartType> arguments = new List<DartType>();
 | 
| -      bool hasTypeArgumentMismatch = resolveTypeArguments(
 | 
| -          visitor, node, const <DartType>[], arguments);
 | 
| -      if (hasTypeArgumentMismatch) {
 | 
| -        return new MalformedType(
 | 
| -            new ErroneousElementX(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH,
 | 
| -                {'type': node}, typeName.source, visitor.enclosingElement),
 | 
| -                type, arguments);
 | 
| -      }
 | 
| -      return type;
 | 
| -    }
 | 
| -
 | 
| -    Identifier prefixName;
 | 
| -    Send send = node.typeName.asSend();
 | 
| -    if (send != null) {
 | 
| -      // The type name is of the form [: prefix . identifier :].
 | 
| -      prefixName = send.receiver.asIdentifier();
 | 
| -      typeName = send.selector.asIdentifier();
 | 
| -    } else {
 | 
| -      typeName = node.typeName.asIdentifier();
 | 
| -      if (identical(typeName.source, 'void')) {
 | 
| -        type = const VoidType();
 | 
| -        checkNoTypeArguments(type);
 | 
| -        registry.useType(node, type);
 | 
| -        return type;
 | 
| -      } else if (identical(typeName.source, 'dynamic')) {
 | 
| -        type = const DynamicType();
 | 
| -        checkNoTypeArguments(type);
 | 
| -        registry.useType(node, type);
 | 
| -        return type;
 | 
| -      }
 | 
| -    }
 | 
| -
 | 
| -    Element element = resolveTypeName(prefixName, typeName, visitor.scope,
 | 
| -                                      deferredIsMalformed: deferredIsMalformed);
 | 
| -
 | 
| -    DartType reportFailureAndCreateType(MessageKind messageKind,
 | 
| -                                        Map messageArguments,
 | 
| -                                        {DartType userProvidedBadType,
 | 
| -                                         Element erroneousElement}) {
 | 
| -      if (malformedIsError) {
 | 
| -        visitor.error(node, messageKind, messageArguments);
 | 
| -      } else {
 | 
| -        registry.registerThrowRuntimeError();
 | 
| -        visitor.warning(node, messageKind, messageArguments);
 | 
| -      }
 | 
| -      if (erroneousElement == null) {
 | 
| -         erroneousElement = new ErroneousElementX(
 | 
| -            messageKind, messageArguments, typeName.source,
 | 
| -            visitor.enclosingElement);
 | 
| -      }
 | 
| -      List<DartType> arguments = <DartType>[];
 | 
| -      resolveTypeArguments(visitor, node, const <DartType>[], arguments);
 | 
| -      return new MalformedType(erroneousElement,
 | 
| -              userProvidedBadType, arguments);
 | 
| -    }
 | 
| -
 | 
| -    // Try to construct the type from the element.
 | 
| -    if (element == null) {
 | 
| -      type = reportFailureAndCreateType(
 | 
| -          MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': node.typeName});
 | 
| -    } else if (element.isAmbiguous) {
 | 
| -      AmbiguousElement ambiguous = element;
 | 
| -      type = reportFailureAndCreateType(
 | 
| -          ambiguous.messageKind, ambiguous.messageArguments);
 | 
| -      ambiguous.diagnose(registry.mapping.analyzedElement, compiler);
 | 
| -    } else if (element.isErroneous) {
 | 
| -      ErroneousElement erroneousElement = element;
 | 
| -      type = reportFailureAndCreateType(
 | 
| -          erroneousElement.messageKind, erroneousElement.messageArguments,
 | 
| -          erroneousElement: erroneousElement);
 | 
| -    } else if (!element.impliesType) {
 | 
| -      type = reportFailureAndCreateType(
 | 
| -          MessageKind.NOT_A_TYPE, {'node': node.typeName});
 | 
| -    } else {
 | 
| -      bool addTypeVariableBoundsCheck = false;
 | 
| -      if (element.isClass) {
 | 
| -        ClassElement cls = element;
 | 
| -        // TODO(johnniwinther): [_ensureClassWillBeResolved] should imply
 | 
| -        // [computeType].
 | 
| -        compiler.resolver._ensureClassWillBeResolved(cls);
 | 
| -        element.computeType(compiler);
 | 
| -        List<DartType> arguments = <DartType>[];
 | 
| -        bool hasTypeArgumentMismatch = resolveTypeArguments(
 | 
| -            visitor, node, cls.typeVariables, arguments);
 | 
| -        if (hasTypeArgumentMismatch) {
 | 
| -          type = new BadInterfaceType(cls.declaration,
 | 
| -              new InterfaceType.forUserProvidedBadType(cls.declaration,
 | 
| -                                                       arguments));
 | 
| -        } else {
 | 
| -          if (arguments.isEmpty) {
 | 
| -            type = cls.rawType;
 | 
| -          } else {
 | 
| -            type = new InterfaceType(cls.declaration, arguments.toList(growable: false));
 | 
| -            addTypeVariableBoundsCheck = true;
 | 
| -          }
 | 
| -        }
 | 
| -      } else if (element.isTypedef) {
 | 
| -        TypedefElement typdef = element;
 | 
| -        // TODO(johnniwinther): [ensureResolved] should imply [computeType].
 | 
| -        typdef.ensureResolved(compiler);
 | 
| -        element.computeType(compiler);
 | 
| -        List<DartType> arguments = <DartType>[];
 | 
| -        bool hasTypeArgumentMismatch = resolveTypeArguments(
 | 
| -            visitor, node, typdef.typeVariables, arguments);
 | 
| -        if (hasTypeArgumentMismatch) {
 | 
| -          type = new BadTypedefType(typdef,
 | 
| -              new TypedefType.forUserProvidedBadType(typdef, arguments));
 | 
| -        } else {
 | 
| -          if (arguments.isEmpty) {
 | 
| -            type = typdef.rawType;
 | 
| -          } else {
 | 
| -            type = new TypedefType(typdef, arguments.toList(growable: false));
 | 
| -            addTypeVariableBoundsCheck = true;
 | 
| -          }
 | 
| -        }
 | 
| -      } else if (element.isTypeVariable) {
 | 
| -        Element outer =
 | 
| -            visitor.enclosingElement.outermostEnclosingMemberOrTopLevel;
 | 
| -        bool isInFactoryConstructor =
 | 
| -            outer != null && outer.isFactoryConstructor;
 | 
| -        if (!outer.isClass &&
 | 
| -            !outer.isTypedef &&
 | 
| -            !isInFactoryConstructor &&
 | 
| -            Elements.isInStaticContext(visitor.enclosingElement)) {
 | 
| -          registry.registerThrowRuntimeError();
 | 
| -          type = reportFailureAndCreateType(
 | 
| -              MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER,
 | 
| -              {'typeVariableName': node},
 | 
| -              userProvidedBadType: element.computeType(compiler));
 | 
| -        } else {
 | 
| -          type = element.computeType(compiler);
 | 
| -        }
 | 
| -        type = checkNoTypeArguments(type);
 | 
| -      } else {
 | 
| -        compiler.internalError(node,
 | 
| -            "Unexpected element kind ${element.kind}.");
 | 
| -      }
 | 
| -      if (addTypeVariableBoundsCheck) {
 | 
| -        registry.registerTypeVariableBoundCheck();
 | 
| -        visitor.addDeferredAction(
 | 
| -            visitor.enclosingElement,
 | 
| -            () => checkTypeVariableBounds(node, type));
 | 
| -      }
 | 
| -    }
 | 
| -    registry.useType(node, type);
 | 
| -    return type;
 | 
| -  }
 | 
| -
 | 
| -  /// Checks the type arguments of [type] against the type variable bounds.
 | 
| -  void checkTypeVariableBounds(TypeAnnotation node, GenericType type) {
 | 
| -    void checkTypeVariableBound(_, DartType typeArgument,
 | 
| -                                   TypeVariableType typeVariable,
 | 
| -                                   DartType bound) {
 | 
| -      if (!compiler.types.isSubtype(typeArgument, bound)) {
 | 
| -        compiler.reportWarning(node,
 | 
| -            MessageKind.INVALID_TYPE_VARIABLE_BOUND,
 | 
| -            {'typeVariable': typeVariable,
 | 
| -             'bound': bound,
 | 
| -             'typeArgument': typeArgument,
 | 
| -             'thisType': type.element.thisType});
 | 
| -      }
 | 
| -    };
 | 
| -
 | 
| -    compiler.types.checkTypeVariableBounds(type, checkTypeVariableBound);
 | 
| -  }
 | 
| -
 | 
| -  /**
 | 
| -   * Resolves the type arguments of [node] and adds these to [arguments].
 | 
| -   *
 | 
| -   * Returns [: true :] if the number of type arguments did not match the
 | 
| -   * number of type variables.
 | 
| -   */
 | 
| -  bool resolveTypeArguments(MappingVisitor visitor,
 | 
| -                            TypeAnnotation node,
 | 
| -                            List<DartType> typeVariables,
 | 
| -                            List<DartType> arguments) {
 | 
| -    if (node.typeArguments == null) {
 | 
| -      return false;
 | 
| -    }
 | 
| -    int expectedVariables = typeVariables.length;
 | 
| -    int index = 0;
 | 
| -    bool typeArgumentCountMismatch = false;
 | 
| -    for (Link<Node> typeArguments = node.typeArguments.nodes;
 | 
| -         !typeArguments.isEmpty;
 | 
| -         typeArguments = typeArguments.tail, index++) {
 | 
| -      if (index > expectedVariables - 1) {
 | 
| -        visitor.warning(
 | 
| -            typeArguments.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT);
 | 
| -        typeArgumentCountMismatch = true;
 | 
| -      }
 | 
| -      DartType argType = resolveTypeAnnotation(visitor, typeArguments.head);
 | 
| -      // TODO(karlklose): rewrite to not modify [arguments].
 | 
| -      arguments.add(argType);
 | 
| -    }
 | 
| -    if (index < expectedVariables) {
 | 
| -      visitor.warning(node.typeArguments,
 | 
| -                      MessageKind.MISSING_TYPE_ARGUMENT);
 | 
| -      typeArgumentCountMismatch = true;
 | 
| -    }
 | 
| -    return typeArgumentCountMismatch;
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -/**
 | 
| - * Common supertype for resolver visitors that record resolutions in a
 | 
| - * [ResolutionRegistry].
 | 
| - */
 | 
| -abstract class MappingVisitor<T> extends CommonResolverVisitor<T> {
 | 
| -  final ResolutionRegistry registry;
 | 
| -  final TypeResolver typeResolver;
 | 
| -  /// The current enclosing element for the visited AST nodes.
 | 
| -  Element get enclosingElement;
 | 
| -  /// The current scope of the visitor.
 | 
| -  Scope get scope;
 | 
| -
 | 
| -  MappingVisitor(Compiler compiler, ResolutionRegistry this.registry)
 | 
| -      : typeResolver = new TypeResolver(compiler),
 | 
| -        super(compiler);
 | 
| -
 | 
| -  AsyncMarker get currentAsyncMarker => AsyncMarker.SYNC;
 | 
| -
 | 
| -  /// Add [element] to the current scope and check for duplicate definitions.
 | 
| -  void addToScope(Element element) {
 | 
| -    Element existing = scope.add(element);
 | 
| -    if (existing != element) {
 | 
| -      reportDuplicateDefinition(element.name, element, existing);
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  void checkLocalDefinitionName(Node node, Element element) {
 | 
| -    if (currentAsyncMarker != AsyncMarker.SYNC) {
 | 
| -      if (element.name == 'yield' ||
 | 
| -          element.name == 'async' ||
 | 
| -          element.name == 'await') {
 | 
| -        compiler.reportError(
 | 
| -            node, MessageKind.ASYNC_KEYWORD_AS_IDENTIFIER,
 | 
| -            {'keyword': element.name,
 | 
| -             'modifier': currentAsyncMarker});
 | 
| -      }
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  /// Register [node] as the definition of [element].
 | 
| -  void defineLocalVariable(Node node, LocalVariableElement element) {
 | 
| -    invariant(node, element != null);
 | 
| -    checkLocalDefinitionName(node, element);
 | 
| -    registry.defineElement(node, element);
 | 
| -  }
 | 
| -
 | 
| -  void reportDuplicateDefinition(String name,
 | 
| -                                 Spannable definition,
 | 
| -                                 Spannable existing) {
 | 
| -    compiler.reportError(definition,
 | 
| -        MessageKind.DUPLICATE_DEFINITION, {'name': name});
 | 
| -    compiler.reportInfo(existing,
 | 
| -        MessageKind.EXISTING_DEFINITION, {'name': name});
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -/**
 | 
| - * Core implementation of resolution.
 | 
| - *
 | 
| - * Do not subclass or instantiate this class outside this library
 | 
| - * except for testing.
 | 
| - */
 | 
| -class ResolverVisitor extends MappingVisitor<ResolutionResult> {
 | 
| -  /**
 | 
| -   * The current enclosing element for the visited AST nodes.
 | 
| -   *
 | 
| -   * This field is updated when nested closures are visited.
 | 
| -   */
 | 
| -  Element enclosingElement;
 | 
| -  bool inInstanceContext;
 | 
| -  bool inCheckContext;
 | 
| -  bool inCatchBlock;
 | 
| -
 | 
| -  Scope scope;
 | 
| -  ClassElement currentClass;
 | 
| -  ExpressionStatement currentExpressionStatement;
 | 
| -  bool sendIsMemberAccess = false;
 | 
| -  StatementScope statementScope;
 | 
| -  int allowedCategory = ElementCategory.VARIABLE | ElementCategory.FUNCTION
 | 
| -      | ElementCategory.IMPLIES_TYPE;
 | 
| -
 | 
| -  /**
 | 
| -   * Record of argument nodes to JS_INTERCEPTOR_CONSTANT for deferred
 | 
| -   * processing.
 | 
| -   */
 | 
| -  Set<Node> argumentsToJsInterceptorConstant = null;
 | 
| -
 | 
| -  /// When visiting the type declaration of the variable in a [ForIn] loop,
 | 
| -  /// the initializer of the variable is implicit and we should not emit an
 | 
| -  /// error when verifying that all final variables are initialized.
 | 
| -  bool allowFinalWithoutInitializer = false;
 | 
| -
 | 
| -  /// The nodes for which variable access and mutation must be registered in
 | 
| -  /// order to determine when the static type of variables types is promoted.
 | 
| -  Link<Node> promotionScope = const Link<Node>();
 | 
| -
 | 
| -  bool isPotentiallyMutableTarget(Element target) {
 | 
| -    if (target == null) return false;
 | 
| -    return (target.isVariable || target.isParameter) &&
 | 
| -      !(target.isFinal || target.isConst);
 | 
| -  }
 | 
| -
 | 
| -  // TODO(ahe): Find a way to share this with runtime implementation.
 | 
| -  static final RegExp symbolValidationPattern =
 | 
| -      new RegExp(r'^(?:[a-zA-Z$][a-zA-Z$0-9_]*\.)*(?:[a-zA-Z$][a-zA-Z$0-9_]*=?|'
 | 
| -                 r'-|'
 | 
| -                 r'unary-|'
 | 
| -                 r'\[\]=|'
 | 
| -                 r'~|'
 | 
| -                 r'==|'
 | 
| -                 r'\[\]|'
 | 
| -                 r'\*|'
 | 
| -                 r'/|'
 | 
| -                 r'%|'
 | 
| -                 r'~/|'
 | 
| -                 r'\+|'
 | 
| -                 r'<<|'
 | 
| -                 r'>>|'
 | 
| -                 r'>=|'
 | 
| -                 r'>|'
 | 
| -                 r'<=|'
 | 
| -                 r'<|'
 | 
| -                 r'&|'
 | 
| -                 r'\^|'
 | 
| -                 r'\|'
 | 
| -                 r')$');
 | 
| -
 | 
| -  ResolverVisitor(Compiler compiler,
 | 
| -                  Element element,
 | 
| -                  ResolutionRegistry registry,
 | 
| -                  {bool useEnclosingScope: false})
 | 
| -    : this.enclosingElement = element,
 | 
| -      // When the element is a field, we are actually resolving its
 | 
| -      // initial value, which should not have access to instance
 | 
| -      // fields.
 | 
| -      inInstanceContext = (element.isInstanceMember && !element.isField)
 | 
| -          || element.isGenerativeConstructor,
 | 
| -      this.currentClass = element.isClassMember ? element.enclosingClass
 | 
| -                                             : null,
 | 
| -      this.statementScope = new StatementScope(),
 | 
| -      scope = useEnclosingScope
 | 
| -          ? Scope.buildEnclosingScope(element) : element.buildScope(),
 | 
| -      // The type annotations on a typedef do not imply type checks.
 | 
| -      // TODO(karlklose): clean this up (dartbug.com/8870).
 | 
| -      inCheckContext = compiler.enableTypeAssertions &&
 | 
| -          !element.isLibrary &&
 | 
| -          !element.isTypedef &&
 | 
| -          !element.enclosingElement.isTypedef,
 | 
| -      inCatchBlock = false,
 | 
| -      super(compiler, registry);
 | 
| -
 | 
| -  AsyncMarker get currentAsyncMarker {
 | 
| -    if (enclosingElement is FunctionElement) {
 | 
| -      FunctionElement function = enclosingElement;
 | 
| -      return function.asyncMarker;
 | 
| -    }
 | 
| -    return AsyncMarker.SYNC;
 | 
| -  }
 | 
| -
 | 
| -  Element reportLookupErrorIfAny(Element result, Node node, String name) {
 | 
| -    if (!Elements.isUnresolved(result)) {
 | 
| -      if (!inInstanceContext && result.isInstanceMember) {
 | 
| -        compiler.reportError(
 | 
| -            node, MessageKind.NO_INSTANCE_AVAILABLE, {'name': name});
 | 
| -        return new ErroneousElementX(MessageKind.NO_INSTANCE_AVAILABLE,
 | 
| -                                     {'name': name},
 | 
| -                                     name, enclosingElement);
 | 
| -      } else if (result.isAmbiguous) {
 | 
| -        AmbiguousElement ambiguous = result;
 | 
| -        compiler.reportError(
 | 
| -            node, ambiguous.messageKind, ambiguous.messageArguments);
 | 
| -        ambiguous.diagnose(enclosingElement, compiler);
 | 
| -        return new ErroneousElementX(ambiguous.messageKind,
 | 
| -                                     ambiguous.messageArguments,
 | 
| -                                     name, enclosingElement);
 | 
| -      }
 | 
| -    }
 | 
| -    return result;
 | 
| -  }
 | 
| -
 | 
| -  // Create, or reuse an already created, target element for a statement.
 | 
| -  JumpTarget getOrDefineTarget(Node statement) {
 | 
| -    JumpTarget element = registry.getTargetDefinition(statement);
 | 
| -    if (element == null) {
 | 
| -      element = new JumpTargetX(statement,
 | 
| -                                   statementScope.nestingLevel,
 | 
| -                                   enclosingElement);
 | 
| -      registry.defineTarget(statement, element);
 | 
| -    }
 | 
| -    return element;
 | 
| -  }
 | 
| -
 | 
| -  doInCheckContext(action()) {
 | 
| -    bool wasInCheckContext = inCheckContext;
 | 
| -    inCheckContext = true;
 | 
| -    var result = action();
 | 
| -    inCheckContext = wasInCheckContext;
 | 
| -    return result;
 | 
| -  }
 | 
| -
 | 
| -  inStaticContext(action()) {
 | 
| -    bool wasInstanceContext = inInstanceContext;
 | 
| -    inInstanceContext = false;
 | 
| -    var result = action();
 | 
| -    inInstanceContext = wasInstanceContext;
 | 
| -    return result;
 | 
| -  }
 | 
| -
 | 
| -  doInPromotionScope(Node node, action()) {
 | 
| -    promotionScope = promotionScope.prepend(node);
 | 
| -    var result = action();
 | 
| -    promotionScope = promotionScope.tail;
 | 
| -    return result;
 | 
| -  }
 | 
| -
 | 
| -  visitInStaticContext(Node node) {
 | 
| -    inStaticContext(() => visit(node));
 | 
| -  }
 | 
| -
 | 
| -  ErroneousElement warnAndCreateErroneousElement(Node node,
 | 
| -                                                 String name,
 | 
| -                                                 MessageKind kind,
 | 
| -                                                 [Map arguments = const {}]) {
 | 
| -    compiler.reportWarning(node, kind, arguments);
 | 
| -    return new ErroneousElementX(kind, arguments, name, enclosingElement);
 | 
| -  }
 | 
| -
 | 
| -  ResolutionResult visitIdentifier(Identifier node) {
 | 
| -    if (node.isThis()) {
 | 
| -      if (!inInstanceContext) {
 | 
| -        error(node, MessageKind.NO_INSTANCE_AVAILABLE, {'name': node});
 | 
| -      }
 | 
| -      return null;
 | 
| -    } else if (node.isSuper()) {
 | 
| -      if (!inInstanceContext) error(node, MessageKind.NO_SUPER_IN_STATIC);
 | 
| -      if ((ElementCategory.SUPER & allowedCategory) == 0) {
 | 
| -        error(node, MessageKind.INVALID_USE_OF_SUPER);
 | 
| -      }
 | 
| -      return null;
 | 
| -    } else {
 | 
| -      String name = node.source;
 | 
| -      Element element = lookupInScope(compiler, node, scope, name);
 | 
| -      if (Elements.isUnresolved(element) && name == 'dynamic') {
 | 
| -        // TODO(johnniwinther): Remove this hack when we can return more complex
 | 
| -        // objects than [Element] from this method.
 | 
| -        element = compiler.typeClass;
 | 
| -        // Set the type to be `dynamic` to mark that this is a type literal.
 | 
| -        registry.setType(node, const DynamicType());
 | 
| -      }
 | 
| -      element = reportLookupErrorIfAny(element, node, node.source);
 | 
| -      if (element == null) {
 | 
| -        if (!inInstanceContext) {
 | 
| -          element = warnAndCreateErroneousElement(
 | 
| -              node, node.source, MessageKind.CANNOT_RESOLVE,
 | 
| -              {'name': node});
 | 
| -          registry.registerThrowNoSuchMethod();
 | 
| -        }
 | 
| -      } else if (element.isErroneous) {
 | 
| -        // Use the erroneous element.
 | 
| -      } else {
 | 
| -        if ((element.kind.category & allowedCategory) == 0) {
 | 
| -          // TODO(ahe): Improve error message. Need UX input.
 | 
| -          error(node, MessageKind.GENERIC,
 | 
| -                {'text': "is not an expression $element"});
 | 
| -        }
 | 
| -      }
 | 
| -      if (!Elements.isUnresolved(element) && element.isClass) {
 | 
| -        ClassElement classElement = element;
 | 
| -        classElement.ensureResolved(compiler);
 | 
| -      }
 | 
| -      return new ElementResult(registry.useElement(node, element));
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  ResolutionResult visitTypeAnnotation(TypeAnnotation node) {
 | 
| -    DartType type = resolveTypeAnnotation(node);
 | 
| -    if (inCheckContext) {
 | 
| -      registry.registerIsCheck(type);
 | 
| -    }
 | 
| -    return new TypeResult(type);
 | 
| -  }
 | 
| -
 | 
| -  bool isNamedConstructor(Send node) => node.receiver != null;
 | 
| -
 | 
| -  Selector getRedirectingThisOrSuperConstructorSelector(Send node) {
 | 
| -    if (isNamedConstructor(node)) {
 | 
| -      String constructorName = node.selector.asIdentifier().source;
 | 
| -      return new Selector.callConstructor(
 | 
| -          constructorName,
 | 
| -          enclosingElement.library);
 | 
| -    } else {
 | 
| -      return new Selector.callDefaultConstructor(
 | 
| -          enclosingElement.library);
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  FunctionElement resolveConstructorRedirection(FunctionElementX constructor) {
 | 
| -    FunctionExpression node = constructor.parseNode(compiler);
 | 
| -
 | 
| -    // A synthetic constructor does not have a node.
 | 
| -    if (node == null) return null;
 | 
| -    if (node.initializers == null) return null;
 | 
| -    Link<Node> initializers = node.initializers.nodes;
 | 
| -    if (!initializers.isEmpty &&
 | 
| -        Initializers.isConstructorRedirect(initializers.head)) {
 | 
| -      Selector selector =
 | 
| -          getRedirectingThisOrSuperConstructorSelector(initializers.head);
 | 
| -      final ClassElement classElement = constructor.enclosingClass;
 | 
| -      return classElement.lookupConstructor(selector);
 | 
| -    }
 | 
| -    return null;
 | 
| -  }
 | 
| -
 | 
| -  void setupFunction(FunctionExpression node, FunctionElement function) {
 | 
| -    Element enclosingElement = function.enclosingElement;
 | 
| -    if (node.modifiers.isStatic &&
 | 
| -        enclosingElement.kind != ElementKind.CLASS) {
 | 
| -      compiler.reportError(node, MessageKind.ILLEGAL_STATIC);
 | 
| -    }
 | 
| -
 | 
| -    scope = new MethodScope(scope, function);
 | 
| -    // Put the parameters in scope.
 | 
| -    FunctionSignature functionParameters = function.functionSignature;
 | 
| -    Link<Node> parameterNodes = (node.parameters == null)
 | 
| -        ? const Link<Node>() : node.parameters.nodes;
 | 
| -    functionParameters.forEachParameter((ParameterElement element) {
 | 
| -      // TODO(karlklose): should be a list of [FormalElement]s, but the actual
 | 
| -      // implementation uses [Element].
 | 
| -      Link<Element> optionals = functionParameters.optionalParameters;
 | 
| -      if (!optionals.isEmpty && element == optionals.head) {
 | 
| -        NodeList nodes = parameterNodes.head;
 | 
| -        parameterNodes = nodes.nodes;
 | 
| -      }
 | 
| -      visit(element.initializer);
 | 
| -      VariableDefinitions variableDefinitions = parameterNodes.head;
 | 
| -      Node parameterNode = variableDefinitions.definitions.nodes.head;
 | 
| -      // Field parameters (this.x) are not visible inside the constructor. The
 | 
| -      // fields they reference are visible, but must be resolved independently.
 | 
| -      if (element.isInitializingFormal) {
 | 
| -        registry.useElement(parameterNode, element);
 | 
| -      } else {
 | 
| -        LocalParameterElement parameterElement = element;
 | 
| -        defineLocalVariable(parameterNode, parameterElement);
 | 
| -        addToScope(parameterElement);
 | 
| -      }
 | 
| -      parameterNodes = parameterNodes.tail;
 | 
| -    });
 | 
| -    addDeferredAction(enclosingElement, () {
 | 
| -      functionParameters.forEachOptionalParameter((Element parameter) {
 | 
| -        compiler.resolver.constantCompiler.compileConstant(parameter);
 | 
| -      });
 | 
| -    });
 | 
| -    if (inCheckContext) {
 | 
| -      functionParameters.forEachParameter((ParameterElement element) {
 | 
| -        registry.registerIsCheck(element.type);
 | 
| -      });
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  visitCascade(Cascade node) {
 | 
| -    visit(node.expression);
 | 
| -  }
 | 
| -
 | 
| -  visitCascadeReceiver(CascadeReceiver node) {
 | 
| -    visit(node.expression);
 | 
| -  }
 | 
| -
 | 
| -  visitClassNode(ClassNode node) {
 | 
| -    internalError(node, "shouldn't be called");
 | 
| -  }
 | 
| -
 | 
| -  visitIn(Node node, Scope nestedScope) {
 | 
| -    Scope oldScope = scope;
 | 
| -    scope = nestedScope;
 | 
| -    ResolutionResult result = visit(node);
 | 
| -    scope = oldScope;
 | 
| -    return result;
 | 
| -  }
 | 
| -
 | 
| -  /**
 | 
| -   * Introduces new default targets for break and continue
 | 
| -   * before visiting the body of the loop
 | 
| -   */
 | 
| -  visitLoopBodyIn(Loop loop, Node body, Scope bodyScope) {
 | 
| -    JumpTarget element = getOrDefineTarget(loop);
 | 
| -    statementScope.enterLoop(element);
 | 
| -    visitIn(body, bodyScope);
 | 
| -    statementScope.exitLoop();
 | 
| -    if (!element.isTarget) {
 | 
| -      registry.undefineTarget(loop);
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  visitBlock(Block node) {
 | 
| -    visitIn(node.statements, new BlockScope(scope));
 | 
| -  }
 | 
| -
 | 
| -  visitDoWhile(DoWhile node) {
 | 
| -    visitLoopBodyIn(node, node.body, new BlockScope(scope));
 | 
| -    visit(node.condition);
 | 
| -  }
 | 
| -
 | 
| -  visitEmptyStatement(EmptyStatement node) { }
 | 
| -
 | 
| -  visitExpressionStatement(ExpressionStatement node) {
 | 
| -    ExpressionStatement oldExpressionStatement = currentExpressionStatement;
 | 
| -    currentExpressionStatement = node;
 | 
| -    visit(node.expression);
 | 
| -    currentExpressionStatement = oldExpressionStatement;
 | 
| -  }
 | 
| -
 | 
| -  visitFor(For node) {
 | 
| -    Scope blockScope = new BlockScope(scope);
 | 
| -    visitIn(node.initializer, blockScope);
 | 
| -    visitIn(node.condition, blockScope);
 | 
| -    visitIn(node.update, blockScope);
 | 
| -    visitLoopBodyIn(node, node.body, blockScope);
 | 
| -  }
 | 
| -
 | 
| -  visitFunctionDeclaration(FunctionDeclaration node) {
 | 
| -    assert(node.function.name != null);
 | 
| -    visitFunctionExpression(node.function, inFunctionDeclaration: true);
 | 
| -  }
 | 
| -
 | 
| -
 | 
| -  /// Process a local function declaration or an anonymous function expression.
 | 
| -  ///
 | 
| -  /// [inFunctionDeclaration] is `true` when the current node is the immediate
 | 
| -  /// child of a function declaration.
 | 
| -  ///
 | 
| -  /// This is used to distinguish local function declarations from anonymous
 | 
| -  /// function expressions.
 | 
| -  visitFunctionExpression(FunctionExpression node,
 | 
| -                          {bool inFunctionDeclaration: false}) {
 | 
| -    bool doAddToScope = inFunctionDeclaration;
 | 
| -    if (!inFunctionDeclaration && node.name != null) {
 | 
| -      compiler.reportError(
 | 
| -          node.name,
 | 
| -          MessageKind.NAMED_FUNCTION_EXPRESSION,
 | 
| -          {'name': node.name});
 | 
| -    }
 | 
| -    visit(node.returnType);
 | 
| -    String name;
 | 
| -    if (node.name == null) {
 | 
| -      name = "";
 | 
| -    } else {
 | 
| -      name = node.name.asIdentifier().source;
 | 
| -    }
 | 
| -    LocalFunctionElementX function = new LocalFunctionElementX(
 | 
| -        name, node, ElementKind.FUNCTION, Modifiers.EMPTY,
 | 
| -        enclosingElement);
 | 
| -    function.functionSignatureCache =
 | 
| -        SignatureResolver.analyze(compiler, node.parameters, node.returnType,
 | 
| -            function, registry, createRealParameters: true);
 | 
| -    ResolverTask.processAsyncMarker(compiler, function);
 | 
| -    checkLocalDefinitionName(node, function);
 | 
| -    registry.defineFunction(node, function);
 | 
| -    if (doAddToScope) {
 | 
| -      addToScope(function);
 | 
| -    }
 | 
| -    Scope oldScope = scope; // The scope is modified by [setupFunction].
 | 
| -    setupFunction(node, function);
 | 
| -
 | 
| -    Element previousEnclosingElement = enclosingElement;
 | 
| -    enclosingElement = function;
 | 
| -    // Run the body in a fresh statement scope.
 | 
| -    StatementScope oldStatementScope = statementScope;
 | 
| -    statementScope = new StatementScope();
 | 
| -    visit(node.body);
 | 
| -    statementScope = oldStatementScope;
 | 
| -
 | 
| -    scope = oldScope;
 | 
| -    enclosingElement = previousEnclosingElement;
 | 
| -
 | 
| -    registry.registerClosure(function);
 | 
| -    registry.registerInstantiatedClass(compiler.functionClass);
 | 
| -  }
 | 
| -
 | 
| -  visitIf(If node) {
 | 
| -    doInPromotionScope(node.condition.expression, () => visit(node.condition));
 | 
| -    doInPromotionScope(node.thenPart,
 | 
| -        () => visitIn(node.thenPart, new BlockScope(scope)));
 | 
| -    visitIn(node.elsePart, new BlockScope(scope));
 | 
| -  }
 | 
| -
 | 
| -  ResolutionResult resolveSend(Send node) {
 | 
| -    Selector selector = resolveSelector(node, null);
 | 
| -    if (node.isSuperCall) registry.registerSuperUse(node);
 | 
| -
 | 
| -    if (node.receiver == null) {
 | 
| -      // If this send is of the form "assert(expr);", then
 | 
| -      // this is an assertion.
 | 
| -      if (selector.isAssert) {
 | 
| -        if (selector.argumentCount != 1) {
 | 
| -          error(node.selector,
 | 
| -                MessageKind.WRONG_NUMBER_OF_ARGUMENTS_FOR_ASSERT,
 | 
| -                {'argumentCount': selector.argumentCount});
 | 
| -        } else if (selector.namedArgumentCount != 0) {
 | 
| -          error(node.selector,
 | 
| -                MessageKind.ASSERT_IS_GIVEN_NAMED_ARGUMENTS,
 | 
| -                {'argumentCount': selector.namedArgumentCount});
 | 
| -        }
 | 
| -        registry.registerAssert(node);
 | 
| -        return const AssertResult();
 | 
| -      }
 | 
| -
 | 
| -      return node.selector.accept(this);
 | 
| -    }
 | 
| -
 | 
| -    var oldCategory = allowedCategory;
 | 
| -    allowedCategory |= ElementCategory.PREFIX | ElementCategory.SUPER;
 | 
| -    ResolutionResult resolvedReceiver = visit(node.receiver);
 | 
| -    allowedCategory = oldCategory;
 | 
| -
 | 
| -    Element target;
 | 
| -    String name = node.selector.asIdentifier().source;
 | 
| -    if (identical(name, 'this')) {
 | 
| -      // TODO(ahe): Why is this using GENERIC?
 | 
| -      error(node.selector, MessageKind.GENERIC,
 | 
| -            {'text': "expected an identifier"});
 | 
| -    } else if (node.isSuperCall) {
 | 
| -      if (node.isOperator) {
 | 
| -        if (isUserDefinableOperator(name)) {
 | 
| -          name = selector.name;
 | 
| -        } else {
 | 
| -          error(node.selector, MessageKind.ILLEGAL_SUPER_SEND, {'name': name});
 | 
| -        }
 | 
| -      }
 | 
| -      if (!inInstanceContext) {
 | 
| -        error(node.receiver, MessageKind.NO_INSTANCE_AVAILABLE, {'name': name});
 | 
| -        return null;
 | 
| -      }
 | 
| -      if (currentClass.supertype == null) {
 | 
| -        // This is just to guard against internal errors, so no need
 | 
| -        // for a real error message.
 | 
| -        error(node.receiver, MessageKind.GENERIC,
 | 
| -              {'text': "Object has no superclass"});
 | 
| -      }
 | 
| -      // TODO(johnniwinther): Ensure correct behavior if currentClass is a
 | 
| -      // patch.
 | 
| -      target = currentClass.lookupSuperSelector(selector);
 | 
| -      // [target] may be null which means invoking noSuchMethod on
 | 
| -      // super.
 | 
| -      if (target == null) {
 | 
| -        target = warnAndCreateErroneousElement(
 | 
| -            node, name, MessageKind.NO_SUCH_SUPER_MEMBER,
 | 
| -            {'className': currentClass, 'memberName': name});
 | 
| -        // We still need to register the invocation, because we might
 | 
| -        // call [:super.noSuchMethod:] which calls
 | 
| -        // [JSInvocationMirror._invokeOn].
 | 
| -        registry.registerDynamicInvocation(selector);
 | 
| -        registry.registerSuperNoSuchMethod();
 | 
| -      }
 | 
| -    } else if (resolvedReceiver == null ||
 | 
| -               Elements.isUnresolved(resolvedReceiver.element)) {
 | 
| -      return null;
 | 
| -    } else if (resolvedReceiver.element.isClass) {
 | 
| -      ClassElement receiverClass = resolvedReceiver.element;
 | 
| -      receiverClass.ensureResolved(compiler);
 | 
| -      if (node.isOperator) {
 | 
| -        // When the resolved receiver is a class, we can have two cases:
 | 
| -        //  1) a static send: C.foo, or
 | 
| -        //  2) an operator send, where the receiver is a class literal: 'C + 1'.
 | 
| -        // The following code that looks up the selector on the resolved
 | 
| -        // receiver will treat the second as the invocation of a static operator
 | 
| -        // if the resolved receiver is not null.
 | 
| -        return null;
 | 
| -      }
 | 
| -      MembersCreator.computeClassMembersByName(
 | 
| -          compiler, receiverClass.declaration, name);
 | 
| -      target = receiverClass.lookupLocalMember(name);
 | 
| -      if (target == null || target.isInstanceMember) {
 | 
| -        registry.registerThrowNoSuchMethod();
 | 
| -        // TODO(johnniwinther): With the simplified [TreeElements] invariant,
 | 
| -        // try to resolve injected elements if [currentClass] is in the patch
 | 
| -        // library of [receiverClass].
 | 
| -
 | 
| -        // TODO(karlklose): this should be reported by the caller of
 | 
| -        // [resolveSend] to select better warning messages for getters and
 | 
| -        // setters.
 | 
| -        MessageKind kind = (target == null)
 | 
| -            ? MessageKind.MEMBER_NOT_FOUND
 | 
| -            : MessageKind.MEMBER_NOT_STATIC;
 | 
| -        return new ElementResult(warnAndCreateErroneousElement(
 | 
| -            node, name, kind,
 | 
| -            {'className': receiverClass.name, 'memberName': name}));
 | 
| -      } else if (isPrivateName(name) &&
 | 
| -                 target.library != enclosingElement.library) {
 | 
| -        registry.registerThrowNoSuchMethod();
 | 
| -        return new ElementResult(warnAndCreateErroneousElement(
 | 
| -            node, name, MessageKind.PRIVATE_ACCESS,
 | 
| -            {'libraryName': target.library.getLibraryOrScriptName(),
 | 
| -             'name': name}));
 | 
| -      }
 | 
| -    } else if (resolvedReceiver.element.isPrefix) {
 | 
| -      PrefixElement prefix = resolvedReceiver.element;
 | 
| -      target = prefix.lookupLocalMember(name);
 | 
| -      if (Elements.isUnresolved(target)) {
 | 
| -        registry.registerThrowNoSuchMethod();
 | 
| -        return new ElementResult(warnAndCreateErroneousElement(
 | 
| -            node, name, MessageKind.NO_SUCH_LIBRARY_MEMBER,
 | 
| -            {'libraryName': prefix.name, 'memberName': name}));
 | 
| -      } else if (target.isAmbiguous) {
 | 
| -        registry.registerThrowNoSuchMethod();
 | 
| -        AmbiguousElement ambiguous = target;
 | 
| -        target = warnAndCreateErroneousElement(node, name,
 | 
| -                                               ambiguous.messageKind,
 | 
| -                                               ambiguous.messageArguments);
 | 
| -        ambiguous.diagnose(enclosingElement, compiler);
 | 
| -        return new ElementResult(target);
 | 
| -      } else if (target.kind == ElementKind.CLASS) {
 | 
| -        ClassElement classElement = target;
 | 
| -        classElement.ensureResolved(compiler);
 | 
| -      }
 | 
| -    }
 | 
| -    return new ElementResult(target);
 | 
| -  }
 | 
| -
 | 
| -  static Selector computeSendSelector(Send node,
 | 
| -                                      LibraryElement library,
 | 
| -                                      Element element) {
 | 
| -    // First determine if this is part of an assignment.
 | 
| -    bool isSet = node.asSendSet() != null;
 | 
| -
 | 
| -    if (node.isIndex) {
 | 
| -      return isSet ? new Selector.indexSet() : new Selector.index();
 | 
| -    }
 | 
| -
 | 
| -    if (node.isOperator) {
 | 
| -      String source = node.selector.asOperator().source;
 | 
| -      String string = source;
 | 
| -      if (identical(string, '!') ||
 | 
| -          identical(string, '&&') || identical(string, '||') ||
 | 
| -          identical(string, 'is') || identical(string, 'as') ||
 | 
| -          identical(string, '?') ||
 | 
| -          identical(string, '>>>')) {
 | 
| -        return null;
 | 
| -      }
 | 
| -      String op = source;
 | 
| -      if (!isUserDefinableOperator(source)) {
 | 
| -        op = Elements.mapToUserOperatorOrNull(source);
 | 
| -      }
 | 
| -      if (op == null) {
 | 
| -        // Unsupported operator. An error has been reported during parsing.
 | 
| -        return new Selector.call(
 | 
| -            source, library, node.argumentsNode.slowLength(), []);
 | 
| -      }
 | 
| -      return node.arguments.isEmpty
 | 
| -          ? new Selector.unaryOperator(op)
 | 
| -          : new Selector.binaryOperator(op);
 | 
| -    }
 | 
| -
 | 
| -    Identifier identifier = node.selector.asIdentifier();
 | 
| -    if (node.isPropertyAccess) {
 | 
| -      assert(!isSet);
 | 
| -      return new Selector.getter(identifier.source, library);
 | 
| -    } else if (isSet) {
 | 
| -      return new Selector.setter(identifier.source, library);
 | 
| -    }
 | 
| -
 | 
| -    // Compute the arity and the list of named arguments.
 | 
| -    int arity = 0;
 | 
| -    List<String> named = <String>[];
 | 
| -    for (Link<Node> link = node.argumentsNode.nodes;
 | 
| -        !link.isEmpty;
 | 
| -        link = link.tail) {
 | 
| -      Expression argument = link.head;
 | 
| -      NamedArgument namedArgument = argument.asNamedArgument();
 | 
| -      if (namedArgument != null) {
 | 
| -        named.add(namedArgument.name.source);
 | 
| -      }
 | 
| -      arity++;
 | 
| -    }
 | 
| -
 | 
| -    if (element != null && element.isConstructor) {
 | 
| -      return new Selector.callConstructor(
 | 
| -          element.name, library, arity, named);
 | 
| -    }
 | 
| -
 | 
| -    // If we're invoking a closure, we do not have an identifier.
 | 
| -    return (identifier == null)
 | 
| -        ? new Selector.callClosure(arity, named)
 | 
| -        : new Selector.call(identifier.source, library, arity, named);
 | 
| -  }
 | 
| -
 | 
| -  Selector resolveSelector(Send node, Element element) {
 | 
| -    LibraryElement library = enclosingElement.library;
 | 
| -    Selector selector = computeSendSelector(node, library, element);
 | 
| -    if (selector != null) registry.setSelector(node, selector);
 | 
| -    return selector;
 | 
| -  }
 | 
| -
 | 
| -  void resolveArguments(NodeList list) {
 | 
| -    if (list == null) return;
 | 
| -    bool oldSendIsMemberAccess = sendIsMemberAccess;
 | 
| -    sendIsMemberAccess = false;
 | 
| -    Map<String, Node> seenNamedArguments = new Map<String, Node>();
 | 
| -    for (Link<Node> link = list.nodes; !link.isEmpty; link = link.tail) {
 | 
| -      Expression argument = link.head;
 | 
| -      visit(argument);
 | 
| -      NamedArgument namedArgument = argument.asNamedArgument();
 | 
| -      if (namedArgument != null) {
 | 
| -        String source = namedArgument.name.source;
 | 
| -        if (seenNamedArguments.containsKey(source)) {
 | 
| -          reportDuplicateDefinition(
 | 
| -              source,
 | 
| -              argument,
 | 
| -              seenNamedArguments[source]);
 | 
| -        } else {
 | 
| -          seenNamedArguments[source] = namedArgument;
 | 
| -        }
 | 
| -      } else if (!seenNamedArguments.isEmpty) {
 | 
| -        error(argument, MessageKind.INVALID_ARGUMENT_AFTER_NAMED);
 | 
| -      }
 | 
| -    }
 | 
| -    sendIsMemberAccess = oldSendIsMemberAccess;
 | 
| -  }
 | 
| -
 | 
| -  ResolutionResult visitSend(Send node) {
 | 
| -    bool oldSendIsMemberAccess = sendIsMemberAccess;
 | 
| -    sendIsMemberAccess = node.isPropertyAccess || node.isCall;
 | 
| -    ResolutionResult result;
 | 
| -    if (node.isLogicalAnd) {
 | 
| -      result = doInPromotionScope(node.receiver, () => resolveSend(node));
 | 
| -    } else {
 | 
| -      result = resolveSend(node);
 | 
| -    }
 | 
| -    sendIsMemberAccess = oldSendIsMemberAccess;
 | 
| -
 | 
| -    Element target = result != null ? result.element : null;
 | 
| -
 | 
| -    if (target != null
 | 
| -        && target == compiler.mirrorSystemGetNameFunction
 | 
| -        && !compiler.mirrorUsageAnalyzerTask.hasMirrorUsage(enclosingElement)) {
 | 
| -      compiler.reportHint(
 | 
| -          node.selector, MessageKind.STATIC_FUNCTION_BLOAT,
 | 
| -          {'class': compiler.mirrorSystemClass.name,
 | 
| -           'name': compiler.mirrorSystemGetNameFunction.name});
 | 
| -    }
 | 
| -
 | 
| -    if (!Elements.isUnresolved(target)) {
 | 
| -      if (target.isAbstractField) {
 | 
| -        AbstractFieldElement field = target;
 | 
| -        target = field.getter;
 | 
| -        if (target == null && !inInstanceContext) {
 | 
| -          registry.registerThrowNoSuchMethod();
 | 
| -          target =
 | 
| -              warnAndCreateErroneousElement(node.selector, field.name,
 | 
| -                                            MessageKind.CANNOT_RESOLVE_GETTER);
 | 
| -        }
 | 
| -      } else if (target.isTypeVariable) {
 | 
| -        ClassElement cls = target.enclosingClass;
 | 
| -        assert(enclosingElement.enclosingClass == cls);
 | 
| -        registry.registerClassUsingVariableExpression(cls);
 | 
| -        registry.registerTypeVariableExpression();
 | 
| -        // Set the type of the node to [Type] to mark this send as a
 | 
| -        // type variable expression.
 | 
| -        registry.registerTypeLiteral(node, target.computeType(compiler));
 | 
| -      } else if (target.impliesType && (!sendIsMemberAccess || node.isCall)) {
 | 
| -        // Set the type of the node to [Type] to mark this send as a
 | 
| -        // type literal.
 | 
| -        DartType type;
 | 
| -
 | 
| -        // TODO(johnniwinther): Remove this hack when we can pass more complex
 | 
| -        // information between methods than resolved elements.
 | 
| -        if (target == compiler.typeClass && node.receiver == null) {
 | 
| -          // Potentially a 'dynamic' type literal.
 | 
| -          type = registry.getType(node.selector);
 | 
| -        }
 | 
| -        if (type == null) {
 | 
| -          type = target.computeType(compiler);
 | 
| -        }
 | 
| -        registry.registerTypeLiteral(node, type);
 | 
| -
 | 
| -        // Don't try to make constants of calls to type literals.
 | 
| -        if (!node.isCall) {
 | 
| -          analyzeConstant(node);
 | 
| -        } else {
 | 
| -          // The node itself is not a constant but we register the selector (the
 | 
| -          // identifier that refers to the class/typedef) as a constant.
 | 
| -          analyzeConstant(node.selector);
 | 
| -        }
 | 
| -      }
 | 
| -      if (isPotentiallyMutableTarget(target)) {
 | 
| -        if (enclosingElement != target.enclosingElement) {
 | 
| -          for (Node scope in promotionScope) {
 | 
| -            registry.setAccessedByClosureIn(scope, target, node);
 | 
| -          }
 | 
| -        }
 | 
| -      }
 | 
| -    }
 | 
| -
 | 
| -    bool resolvedArguments = false;
 | 
| -    if (node.isOperator) {
 | 
| -      String operatorString = node.selector.asOperator().source;
 | 
| -      if (identical(operatorString, 'is')) {
 | 
| -        // TODO(johnniwinther): Use seen type tests to avoid registration of
 | 
| -        // mutation/access to unpromoted variables.
 | 
| -        DartType type =
 | 
| -            resolveTypeAnnotation(node.typeAnnotationFromIsCheckOrCast);
 | 
| -        if (type != null) {
 | 
| -          registry.registerIsCheck(type);
 | 
| -        }
 | 
| -        resolvedArguments = true;
 | 
| -      } else if (identical(operatorString, 'as')) {
 | 
| -        DartType type = resolveTypeAnnotation(node.arguments.head);
 | 
| -        if (type != null) {
 | 
| -          registry.registerAsCheck(type);
 | 
| -        }
 | 
| -        resolvedArguments = true;
 | 
| -      } else if (identical(operatorString, '&&')) {
 | 
| -        doInPromotionScope(node.arguments.head,
 | 
| -            () => resolveArguments(node.argumentsNode));
 | 
| -        resolvedArguments = true;
 | 
| -      }
 | 
| -    }
 | 
| -
 | 
| -    if (!resolvedArguments) {
 | 
| -      resolveArguments(node.argumentsNode);
 | 
| -    }
 | 
| -
 | 
| -    // If the selector is null, it means that we will not be generating
 | 
| -    // code for this as a send.
 | 
| -    Selector selector = registry.getSelector(node);
 | 
| -    if (selector == null) return null;
 | 
| -
 | 
| -    if (node.isCall) {
 | 
| -      if (Elements.isUnresolved(target) ||
 | 
| -          target.isGetter ||
 | 
| -          target.isField ||
 | 
| -          Elements.isClosureSend(node, target)) {
 | 
| -        // If we don't know what we're calling or if we are calling a getter,
 | 
| -        // we need to register that fact that we may be calling a closure
 | 
| -        // with the same arguments.
 | 
| -        Selector call = new Selector.callClosureFrom(selector);
 | 
| -        registry.registerDynamicInvocation(call);
 | 
| -      } else if (target.impliesType) {
 | 
| -        // We call 'call()' on a Type instance returned from the reference to a
 | 
| -        // class or typedef literal. We do not need to register this call as a
 | 
| -        // dynamic invocation, because we statically know what the target is.
 | 
| -      } else {
 | 
| -        if (target is FunctionElement) {
 | 
| -          FunctionElement function = target;
 | 
| -          function.computeSignature(compiler);
 | 
| -        }
 | 
| -        if (!selector.applies(target, compiler.world)) {
 | 
| -          registry.registerThrowNoSuchMethod();
 | 
| -          if (node.isSuperCall) {
 | 
| -            // Similar to what we do when we can't find super via selector
 | 
| -            // in [resolveSend] above, we still need to register the invocation,
 | 
| -            // because we might call [:super.noSuchMethod:] which calls
 | 
| -            // [JSInvocationMirror._invokeOn].
 | 
| -            registry.registerDynamicInvocation(selector);
 | 
| -            registry.registerSuperNoSuchMethod();
 | 
| -          }
 | 
| -        }
 | 
| -      }
 | 
| -
 | 
| -      if (target != null && target.isForeign(compiler.backend)) {
 | 
| -        if (selector.name == 'JS') {
 | 
| -          registry.registerJsCall(node, this);
 | 
| -        } else if (selector.name == 'JS_EMBEDDED_GLOBAL') {
 | 
| -          registry.registerJsEmbeddedGlobalCall(node, this);
 | 
| -        } else if (selector.name == 'JS_INTERCEPTOR_CONSTANT') {
 | 
| -          if (!node.argumentsNode.isEmpty) {
 | 
| -            Node argument = node.argumentsNode.nodes.head;
 | 
| -            if (argumentsToJsInterceptorConstant == null) {
 | 
| -              argumentsToJsInterceptorConstant = new Set<Node>();
 | 
| -            }
 | 
| -            argumentsToJsInterceptorConstant.add(argument);
 | 
| -          }
 | 
| -        }
 | 
| -      }
 | 
| -    }
 | 
| -
 | 
| -    registry.useElement(node, target);
 | 
| -    registerSend(selector, target);
 | 
| -    if (node.isPropertyAccess && Elements.isStaticOrTopLevelFunction(target)) {
 | 
| -      registry.registerGetOfStaticFunction(target.declaration);
 | 
| -    }
 | 
| -    return node.isPropertyAccess ? new ElementResult(target) : null;
 | 
| -  }
 | 
| -
 | 
| -  /// Callback for native enqueuer to parse a type.  Returns [:null:] on error.
 | 
| -  DartType resolveTypeFromString(Node node, String typeName) {
 | 
| -    Element element = lookupInScope(compiler, node,
 | 
| -                                    scope, typeName);
 | 
| -    if (element == null) return null;
 | 
| -    if (element is! ClassElement) return null;
 | 
| -    ClassElement cls = element;
 | 
| -    cls.ensureResolved(compiler);
 | 
| -    return cls.computeType(compiler);
 | 
| -  }
 | 
| -
 | 
| -  ResolutionResult visitSendSet(SendSet node) {
 | 
| -    bool oldSendIsMemberAccess = sendIsMemberAccess;
 | 
| -    sendIsMemberAccess = node.isPropertyAccess || node.isCall;
 | 
| -    ResolutionResult result = resolveSend(node);
 | 
| -    sendIsMemberAccess = oldSendIsMemberAccess;
 | 
| -    Element target = result != null ? result.element : null;
 | 
| -    Element setter = target;
 | 
| -    Element getter = target;
 | 
| -    String operatorName = node.assignmentOperator.source;
 | 
| -    String source = operatorName;
 | 
| -    bool isComplex = !identical(source, '=');
 | 
| -    if (!(result is AssertResult || Elements.isUnresolved(target))) {
 | 
| -      if (target.isAbstractField) {
 | 
| -        AbstractFieldElement field = target;
 | 
| -        setter = field.setter;
 | 
| -        getter = field.getter;
 | 
| -        if (setter == null && !inInstanceContext) {
 | 
| -          setter = warnAndCreateErroneousElement(
 | 
| -              node.selector, field.name, MessageKind.CANNOT_RESOLVE_SETTER);
 | 
| -          registry.registerThrowNoSuchMethod();
 | 
| -        }
 | 
| -        if (isComplex && getter == null && !inInstanceContext) {
 | 
| -          getter = warnAndCreateErroneousElement(
 | 
| -              node.selector, field.name, MessageKind.CANNOT_RESOLVE_GETTER);
 | 
| -          registry.registerThrowNoSuchMethod();
 | 
| -        }
 | 
| -      } else if (target.impliesType) {
 | 
| -        setter = warnAndCreateErroneousElement(
 | 
| -            node.selector, target.name, MessageKind.ASSIGNING_TYPE);
 | 
| -        registry.registerThrowNoSuchMethod();
 | 
| -      } else if (target.isFinal ||
 | 
| -                 target.isConst ||
 | 
| -                 (target.isFunction &&
 | 
| -                  Elements.isStaticOrTopLevelFunction(target) &&
 | 
| -                  !target.isSetter)) {
 | 
| -        if (target.isFunction) {
 | 
| -          setter = warnAndCreateErroneousElement(
 | 
| -              node.selector, target.name, MessageKind.ASSIGNING_METHOD);
 | 
| -        } else {
 | 
| -          setter = warnAndCreateErroneousElement(
 | 
| -              node.selector, target.name, MessageKind.CANNOT_RESOLVE_SETTER);
 | 
| -        }
 | 
| -        registry.registerThrowNoSuchMethod();
 | 
| -      }
 | 
| -      if (isPotentiallyMutableTarget(target)) {
 | 
| -        registry.registerPotentialMutation(target, node);
 | 
| -        if (enclosingElement != target.enclosingElement) {
 | 
| -          registry.registerPotentialMutationInClosure(target, node);
 | 
| -        }
 | 
| -        for (Node scope in promotionScope) {
 | 
| -          registry.registerPotentialMutationIn(scope, target, node);
 | 
| -        }
 | 
| -      }
 | 
| -    }
 | 
| -
 | 
| -    resolveArguments(node.argumentsNode);
 | 
| -
 | 
| -    Selector selector = registry.getSelector(node);
 | 
| -    if (isComplex) {
 | 
| -      Selector getterSelector;
 | 
| -      if (selector.isSetter) {
 | 
| -        getterSelector = new Selector.getterFrom(selector);
 | 
| -      } else {
 | 
| -        assert(selector.isIndexSet);
 | 
| -        getterSelector = new Selector.index();
 | 
| -      }
 | 
| -      registerSend(getterSelector, getter);
 | 
| -      registry.setGetterSelectorInComplexSendSet(node, getterSelector);
 | 
| -      if (node.isSuperCall) {
 | 
| -        getter = currentClass.lookupSuperSelector(getterSelector);
 | 
| -        if (getter == null) {
 | 
| -          target = warnAndCreateErroneousElement(
 | 
| -              node, selector.name, MessageKind.NO_SUCH_SUPER_MEMBER,
 | 
| -              {'className': currentClass, 'memberName': selector.name});
 | 
| -          registry.registerSuperNoSuchMethod();
 | 
| -        }
 | 
| -      }
 | 
| -      registry.useElement(node.selector, getter);
 | 
| -
 | 
| -      // Make sure we include the + and - operators if we are using
 | 
| -      // the ++ and -- ones.  Also, if op= form is used, include op itself.
 | 
| -      void registerBinaryOperator(String name) {
 | 
| -        Selector binop = new Selector.binaryOperator(name);
 | 
| -        registry.registerDynamicInvocation(binop);
 | 
| -        registry.setOperatorSelectorInComplexSendSet(node, binop);
 | 
| -      }
 | 
| -      if (identical(source, '++')) {
 | 
| -        registerBinaryOperator('+');
 | 
| -        registry.registerInstantiatedClass(compiler.intClass);
 | 
| -      } else if (identical(source, '--')) {
 | 
| -        registerBinaryOperator('-');
 | 
| -        registry.registerInstantiatedClass(compiler.intClass);
 | 
| -      } else if (source.endsWith('=')) {
 | 
| -        registerBinaryOperator(Elements.mapToUserOperator(operatorName));
 | 
| -      }
 | 
| -    }
 | 
| -
 | 
| -    registerSend(selector, setter);
 | 
| -    return new ElementResult(registry.useElement(node, setter));
 | 
| -  }
 | 
| -
 | 
| -  void registerSend(Selector selector, Element target) {
 | 
| -    if (target == null || target.isInstanceMember) {
 | 
| -      if (selector.isGetter) {
 | 
| -        registry.registerDynamicGetter(selector);
 | 
| -      } else if (selector.isSetter) {
 | 
| -        registry.registerDynamicSetter(selector);
 | 
| -      } else {
 | 
| -        registry.registerDynamicInvocation(selector);
 | 
| -      }
 | 
| -    } else if (Elements.isStaticOrTopLevel(target)) {
 | 
| -      // Avoid registration of type variables since they are not analyzable but
 | 
| -      // instead resolved through their enclosing type declaration.
 | 
| -      if (!target.isTypeVariable) {
 | 
| -        // [target] might be the implementation element and only declaration
 | 
| -        // elements may be registered.
 | 
| -        registry.registerStaticUse(target.declaration);
 | 
| -      }
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  visitLiteralInt(LiteralInt node) {
 | 
| -    registry.registerInstantiatedClass(compiler.intClass);
 | 
| -  }
 | 
| -
 | 
| -  visitLiteralDouble(LiteralDouble node) {
 | 
| -    registry.registerInstantiatedClass(compiler.doubleClass);
 | 
| -  }
 | 
| -
 | 
| -  visitLiteralBool(LiteralBool node) {
 | 
| -    registry.registerInstantiatedClass(compiler.boolClass);
 | 
| -  }
 | 
| -
 | 
| -  visitLiteralString(LiteralString node) {
 | 
| -    registry.registerInstantiatedClass(compiler.stringClass);
 | 
| -  }
 | 
| -
 | 
| -  visitLiteralNull(LiteralNull node) {
 | 
| -    registry.registerInstantiatedClass(compiler.nullClass);
 | 
| -  }
 | 
| -
 | 
| -  visitLiteralSymbol(LiteralSymbol node) {
 | 
| -    registry.registerInstantiatedClass(compiler.symbolClass);
 | 
| -    registry.registerStaticUse(compiler.symbolConstructor.declaration);
 | 
| -    registry.registerConstSymbol(node.slowNameString);
 | 
| -    if (!validateSymbol(node, node.slowNameString, reportError: false)) {
 | 
| -      compiler.reportError(node,
 | 
| -          MessageKind.UNSUPPORTED_LITERAL_SYMBOL,
 | 
| -          {'value': node.slowNameString});
 | 
| -    }
 | 
| -    analyzeConstant(node);
 | 
| -  }
 | 
| -
 | 
| -  visitStringJuxtaposition(StringJuxtaposition node) {
 | 
| -    registry.registerInstantiatedClass(compiler.stringClass);
 | 
| -    node.visitChildren(this);
 | 
| -  }
 | 
| -
 | 
| -  visitNodeList(NodeList node) {
 | 
| -    for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) {
 | 
| -      visit(link.head);
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  visitOperator(Operator node) {
 | 
| -    internalError(node, 'operator');
 | 
| -  }
 | 
| -
 | 
| -  visitRethrow(Rethrow node) {
 | 
| -    if (!inCatchBlock) {
 | 
| -      error(node, MessageKind.THROW_WITHOUT_EXPRESSION);
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  visitReturn(Return node) {
 | 
| -    Node expression = node.expression;
 | 
| -    if (expression != null &&
 | 
| -        enclosingElement.isGenerativeConstructor) {
 | 
| -      // It is a compile-time error if a return statement of the form
 | 
| -      // `return e;` appears in a generative constructor.  (Dart Language
 | 
| -      // Specification 13.12.)
 | 
| -      compiler.reportError(expression,
 | 
| -                           MessageKind.CANNOT_RETURN_FROM_CONSTRUCTOR);
 | 
| -    }
 | 
| -    visit(node.expression);
 | 
| -  }
 | 
| -
 | 
| -  visitYield(Yield node) {
 | 
| -    compiler.streamClass.ensureResolved(compiler);
 | 
| -    compiler.iterableClass.ensureResolved(compiler);
 | 
| -    visit(node.expression);
 | 
| -  }
 | 
| -
 | 
| -  visitRedirectingFactoryBody(RedirectingFactoryBody node) {
 | 
| -    final isSymbolConstructor = enclosingElement == compiler.symbolConstructor;
 | 
| -    if (!enclosingElement.isFactoryConstructor) {
 | 
| -      compiler.reportError(
 | 
| -          node, MessageKind.FACTORY_REDIRECTION_IN_NON_FACTORY);
 | 
| -      compiler.reportHint(
 | 
| -          enclosingElement, MessageKind.MISSING_FACTORY_KEYWORD);
 | 
| -    }
 | 
| -    ConstructorElementX constructor = enclosingElement;
 | 
| -    bool isConstConstructor = constructor.isConst;
 | 
| -    ConstructorElement redirectionTarget = resolveRedirectingFactory(
 | 
| -        node, inConstContext: isConstConstructor);
 | 
| -    constructor.immediateRedirectionTarget = redirectionTarget;
 | 
| -    registry.setRedirectingTargetConstructor(node, redirectionTarget);
 | 
| -    if (Elements.isUnresolved(redirectionTarget)) {
 | 
| -      registry.registerThrowNoSuchMethod();
 | 
| -      return;
 | 
| -    } else {
 | 
| -      if (isConstConstructor &&
 | 
| -          !redirectionTarget.isConst) {
 | 
| -        compiler.reportError(node, MessageKind.CONSTRUCTOR_IS_NOT_CONST);
 | 
| -      }
 | 
| -      if (redirectionTarget == constructor) {
 | 
| -        compiler.reportError(node, MessageKind.CYCLIC_REDIRECTING_FACTORY);
 | 
| -        return;
 | 
| -      }
 | 
| -    }
 | 
| -
 | 
| -    // Check that the target constructor is type compatible with the
 | 
| -    // redirecting constructor.
 | 
| -    ClassElement targetClass = redirectionTarget.enclosingClass;
 | 
| -    InterfaceType type = registry.getType(node);
 | 
| -    FunctionType targetType = redirectionTarget.computeType(compiler)
 | 
| -        .subst(type.typeArguments, targetClass.typeVariables);
 | 
| -    FunctionType constructorType = constructor.computeType(compiler);
 | 
| -    bool isSubtype = compiler.types.isSubtype(targetType, constructorType);
 | 
| -    if (!isSubtype) {
 | 
| -      warning(node, MessageKind.NOT_ASSIGNABLE,
 | 
| -              {'fromType': targetType, 'toType': constructorType});
 | 
| -    }
 | 
| -
 | 
| -    FunctionSignature targetSignature =
 | 
| -        redirectionTarget.computeSignature(compiler);
 | 
| -    FunctionSignature constructorSignature =
 | 
| -        constructor.computeSignature(compiler);
 | 
| -    if (!targetSignature.isCompatibleWith(constructorSignature)) {
 | 
| -      assert(!isSubtype);
 | 
| -      registry.registerThrowNoSuchMethod();
 | 
| -    }
 | 
| -
 | 
| -    // Register a post process to check for cycles in the redirection chain and
 | 
| -    // set the actual generative constructor at the end of the chain.
 | 
| -    addDeferredAction(constructor, () {
 | 
| -      compiler.resolver.resolveRedirectionChain(constructor, node);
 | 
| -    });
 | 
| -
 | 
| -    registry.registerStaticUse(redirectionTarget);
 | 
| -    // TODO(johnniwinther): Register the effective target type instead.
 | 
| -    registry.registerInstantiatedClass(
 | 
| -        redirectionTarget.enclosingClass.declaration);
 | 
| -    if (isSymbolConstructor) {
 | 
| -      registry.registerSymbolConstructor();
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  visitThrow(Throw node) {
 | 
| -    registry.registerThrowExpression();
 | 
| -    visit(node.expression);
 | 
| -  }
 | 
| -
 | 
| -  visitAwait(Await node) {
 | 
| -    compiler.futureClass.ensureResolved(compiler);
 | 
| -    visit(node.expression);
 | 
| -  }
 | 
| -
 | 
| -  visitVariableDefinitions(VariableDefinitions node) {
 | 
| -    DartType type;
 | 
| -    if (node.type != null) {
 | 
| -      type = resolveTypeAnnotation(node.type);
 | 
| -    } else {
 | 
| -      type = const DynamicType();
 | 
| -    }
 | 
| -    VariableList variables = new VariableList.node(node, type);
 | 
| -    VariableDefinitionsVisitor visitor =
 | 
| -        new VariableDefinitionsVisitor(compiler, node, this, variables);
 | 
| -
 | 
| -    Modifiers modifiers = node.modifiers;
 | 
| -    void reportExtraModifier(String modifier) {
 | 
| -      Node modifierNode;
 | 
| -      for (Link<Node> nodes = modifiers.nodes.nodes;
 | 
| -           !nodes.isEmpty;
 | 
| -           nodes = nodes.tail) {
 | 
| -        if (modifier == nodes.head.asIdentifier().source) {
 | 
| -          modifierNode = nodes.head;
 | 
| -          break;
 | 
| -        }
 | 
| -      }
 | 
| -      assert(modifierNode != null);
 | 
| -      compiler.reportError(modifierNode, MessageKind.EXTRANEOUS_MODIFIER,
 | 
| -          {'modifier': modifier});
 | 
| -    }
 | 
| -    if (modifiers.isFinal && (modifiers.isConst || modifiers.isVar)) {
 | 
| -      reportExtraModifier('final');
 | 
| -    }
 | 
| -    if (modifiers.isVar && (modifiers.isConst || node.type != null)) {
 | 
| -      reportExtraModifier('var');
 | 
| -    }
 | 
| -    if (enclosingElement.isFunction) {
 | 
| -      if (modifiers.isAbstract) {
 | 
| -        reportExtraModifier('abstract');
 | 
| -      }
 | 
| -      if (modifiers.isStatic) {
 | 
| -        reportExtraModifier('static');
 | 
| -      }
 | 
| -    }
 | 
| -    if (node.metadata != null) {
 | 
| -      variables.metadata =
 | 
| -          compiler.resolver.resolveMetadata(enclosingElement, node);
 | 
| -    }
 | 
| -    visitor.visit(node.definitions);
 | 
| -  }
 | 
| -
 | 
| -  visitWhile(While node) {
 | 
| -    visit(node.condition);
 | 
| -    visitLoopBodyIn(node, node.body, new BlockScope(scope));
 | 
| -  }
 | 
| -
 | 
| -  visitParenthesizedExpression(ParenthesizedExpression node) {
 | 
| -    bool oldSendIsMemberAccess = sendIsMemberAccess;
 | 
| -    sendIsMemberAccess = false;
 | 
| -    visit(node.expression);
 | 
| -    sendIsMemberAccess = oldSendIsMemberAccess;
 | 
| -  }
 | 
| -
 | 
| -  ResolutionResult visitNewExpression(NewExpression node) {
 | 
| -    Node selector = node.send.selector;
 | 
| -    FunctionElement constructor = resolveConstructor(node);
 | 
| -    final bool isSymbolConstructor = constructor == compiler.symbolConstructor;
 | 
| -    final bool isMirrorsUsedConstant =
 | 
| -        node.isConst && (constructor == compiler.mirrorsUsedConstructor);
 | 
| -    Selector callSelector = resolveSelector(node.send, constructor);
 | 
| -    resolveArguments(node.send.argumentsNode);
 | 
| -    registry.useElement(node.send, constructor);
 | 
| -    if (Elements.isUnresolved(constructor)) {
 | 
| -      return new ElementResult(constructor);
 | 
| -    }
 | 
| -    constructor.computeSignature(compiler);
 | 
| -    if (!callSelector.applies(constructor, compiler.world)) {
 | 
| -      registry.registerThrowNoSuchMethod();
 | 
| -    }
 | 
| -
 | 
| -    // [constructor] might be the implementation element
 | 
| -    // and only declaration elements may be registered.
 | 
| -    registry.registerStaticUse(constructor.declaration);
 | 
| -    ClassElement cls = constructor.enclosingClass;
 | 
| -    InterfaceType type = registry.getType(node);
 | 
| -    if (node.isConst && type.containsTypeVariables) {
 | 
| -      compiler.reportError(node.send.selector,
 | 
| -                           MessageKind.TYPE_VARIABLE_IN_CONSTANT);
 | 
| -    }
 | 
| -    // TODO(johniwinther): Avoid registration of `type` in face of redirecting
 | 
| -    // factory constructors.
 | 
| -    registry.registerInstantiatedType(type);
 | 
| -    if (constructor.isFactoryConstructor && !type.typeArguments.isEmpty) {
 | 
| -      registry.registerFactoryWithTypeArguments();
 | 
| -    }
 | 
| -    if (constructor.isGenerativeConstructor && cls.isAbstract) {
 | 
| -      warning(node, MessageKind.ABSTRACT_CLASS_INSTANTIATION);
 | 
| -      registry.registerAbstractClassInstantiation();
 | 
| -    }
 | 
| -
 | 
| -    if (isSymbolConstructor) {
 | 
| -      if (node.isConst) {
 | 
| -        Node argumentNode = node.send.arguments.head;
 | 
| -        ConstantExpression constant =
 | 
| -            compiler.resolver.constantCompiler.compileNode(
 | 
| -                argumentNode, registry.mapping);
 | 
| -        ConstantValue name = constant.value;
 | 
| -        if (!name.isString) {
 | 
| -          DartType type = name.computeType(compiler);
 | 
| -          compiler.reportError(argumentNode, MessageKind.STRING_EXPECTED,
 | 
| -                                   {'type': type});
 | 
| -        } else {
 | 
| -          StringConstantValue stringConstant = name;
 | 
| -          String nameString = stringConstant.toDartString().slowToString();
 | 
| -          if (validateSymbol(argumentNode, nameString)) {
 | 
| -            registry.registerConstSymbol(nameString);
 | 
| -          }
 | 
| -        }
 | 
| -      } else {
 | 
| -        if (!compiler.mirrorUsageAnalyzerTask.hasMirrorUsage(
 | 
| -                enclosingElement)) {
 | 
| -          compiler.reportHint(
 | 
| -              node.newToken, MessageKind.NON_CONST_BLOAT,
 | 
| -              {'name': compiler.symbolClass.name});
 | 
| -        }
 | 
| -        registry.registerNewSymbol();
 | 
| -      }
 | 
| -    } else if (isMirrorsUsedConstant) {
 | 
| -      compiler.mirrorUsageAnalyzerTask.validate(node, registry.mapping);
 | 
| -    }
 | 
| -    if (node.isConst) {
 | 
| -      analyzeConstant(node);
 | 
| -    }
 | 
| -
 | 
| -    return null;
 | 
| -  }
 | 
| -
 | 
| -  void checkConstMapKeysDontOverrideEquals(Spannable spannable,
 | 
| -                                           MapConstantValue map) {
 | 
| -    for (ConstantValue key in map.keys) {
 | 
| -      if (!key.isObject) continue;
 | 
| -      ObjectConstantValue objectConstant = key;
 | 
| -      DartType keyType = objectConstant.type;
 | 
| -      ClassElement cls = keyType.element;
 | 
| -      if (cls == compiler.stringClass) continue;
 | 
| -      Element equals = cls.lookupMember('==');
 | 
| -      if (equals.enclosingClass != compiler.objectClass) {
 | 
| -        compiler.reportError(spannable,
 | 
| -                             MessageKind.CONST_MAP_KEY_OVERRIDES_EQUALS,
 | 
| -                             {'type': keyType});
 | 
| -      }
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  void analyzeConstant(Node node) {
 | 
| -    addDeferredAction(enclosingElement, () {
 | 
| -      ConstantExpression constant =
 | 
| -          compiler.resolver.constantCompiler.compileNode(
 | 
| -              node, registry.mapping);
 | 
| -
 | 
| -      ConstantValue value = constant.value;
 | 
| -      if (value.isMap) {
 | 
| -        checkConstMapKeysDontOverrideEquals(node, value);
 | 
| -      }
 | 
| -
 | 
| -      // The type constant that is an argument to JS_INTERCEPTOR_CONSTANT names
 | 
| -      // a class that will be instantiated outside the program by attaching a
 | 
| -      // native class dispatch record referencing the interceptor.
 | 
| -      if (argumentsToJsInterceptorConstant != null &&
 | 
| -          argumentsToJsInterceptorConstant.contains(node)) {
 | 
| -        if (value.isType) {
 | 
| -          TypeConstantValue typeConstant = value;
 | 
| -          if (typeConstant.representedType is InterfaceType) {
 | 
| -            registry.registerInstantiatedType(typeConstant.representedType);
 | 
| -          } else {
 | 
| -            compiler.reportError(node,
 | 
| -                MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT);
 | 
| -          }
 | 
| -        } else {
 | 
| -          compiler.reportError(node,
 | 
| -              MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT);
 | 
| -        }
 | 
| -      }
 | 
| -    });
 | 
| -  }
 | 
| -
 | 
| -  bool validateSymbol(Node node, String name, {bool reportError: true}) {
 | 
| -    if (name.isEmpty) return true;
 | 
| -    if (name.startsWith('_')) {
 | 
| -      if (reportError) {
 | 
| -        compiler.reportError(node, MessageKind.PRIVATE_IDENTIFIER,
 | 
| -                             {'value': name});
 | 
| -      }
 | 
| -      return false;
 | 
| -    }
 | 
| -    if (!symbolValidationPattern.hasMatch(name)) {
 | 
| -      if (reportError) {
 | 
| -        compiler.reportError(node, MessageKind.INVALID_SYMBOL,
 | 
| -                             {'value': name});
 | 
| -      }
 | 
| -      return false;
 | 
| -    }
 | 
| -    return true;
 | 
| -  }
 | 
| -
 | 
| -  /**
 | 
| -   * Try to resolve the constructor that is referred to by [node].
 | 
| -   * Note: this function may return an ErroneousFunctionElement instead of
 | 
| -   * [:null:], if there is no corresponding constructor, class or library.
 | 
| -   */
 | 
| -  ConstructorElement resolveConstructor(NewExpression node) {
 | 
| -    return node.accept(new ConstructorResolver(compiler, this));
 | 
| -  }
 | 
| -
 | 
| -  ConstructorElement resolveRedirectingFactory(RedirectingFactoryBody node,
 | 
| -                                               {bool inConstContext: false}) {
 | 
| -    return node.accept(new ConstructorResolver(compiler, this,
 | 
| -                                               inConstContext: inConstContext));
 | 
| -  }
 | 
| -
 | 
| -  DartType resolveTypeAnnotation(TypeAnnotation node,
 | 
| -                                 {bool malformedIsError: false,
 | 
| -                                  bool deferredIsMalformed: true}) {
 | 
| -    DartType type = typeResolver.resolveTypeAnnotation(
 | 
| -        this, node, malformedIsError: malformedIsError,
 | 
| -        deferredIsMalformed: deferredIsMalformed);
 | 
| -    if (inCheckContext) {
 | 
| -      registry.registerIsCheck(type);
 | 
| -      registry.registerRequiredType(type, enclosingElement);
 | 
| -    }
 | 
| -    return type;
 | 
| -  }
 | 
| -
 | 
| -  visitModifiers(Modifiers node) {
 | 
| -    internalError(node, 'modifiers');
 | 
| -  }
 | 
| -
 | 
| -  visitLiteralList(LiteralList node) {
 | 
| -    bool oldSendIsMemberAccess = sendIsMemberAccess;
 | 
| -    sendIsMemberAccess = false;
 | 
| -
 | 
| -    NodeList arguments = node.typeArguments;
 | 
| -    DartType typeArgument;
 | 
| -    if (arguments != null) {
 | 
| -      Link<Node> nodes = arguments.nodes;
 | 
| -      if (nodes.isEmpty) {
 | 
| -        // The syntax [: <>[] :] is not allowed.
 | 
| -        error(arguments, MessageKind.MISSING_TYPE_ARGUMENT);
 | 
| -      } else {
 | 
| -        typeArgument = resolveTypeAnnotation(nodes.head);
 | 
| -        for (nodes = nodes.tail; !nodes.isEmpty; nodes = nodes.tail) {
 | 
| -          warning(nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT);
 | 
| -          resolveTypeAnnotation(nodes.head);
 | 
| -        }
 | 
| -      }
 | 
| -    }
 | 
| -    DartType listType;
 | 
| -    if (typeArgument != null) {
 | 
| -      if (node.isConst && typeArgument.containsTypeVariables) {
 | 
| -        compiler.reportError(arguments.nodes.head,
 | 
| -            MessageKind.TYPE_VARIABLE_IN_CONSTANT);
 | 
| -      }
 | 
| -      listType = new InterfaceType(compiler.listClass, [typeArgument]);
 | 
| -    } else {
 | 
| -      compiler.listClass.computeType(compiler);
 | 
| -      listType = compiler.listClass.rawType;
 | 
| -    }
 | 
| -    registry.setType(node, listType);
 | 
| -    registry.registerInstantiatedType(listType);
 | 
| -    registry.registerRequiredType(listType, enclosingElement);
 | 
| -    visit(node.elements);
 | 
| -    if (node.isConst) {
 | 
| -      analyzeConstant(node);
 | 
| -    }
 | 
| -
 | 
| -    sendIsMemberAccess = false;
 | 
| -  }
 | 
| -
 | 
| -  visitConditional(Conditional node) {
 | 
| -    doInPromotionScope(node.condition, () => visit(node.condition));
 | 
| -    doInPromotionScope(node.thenExpression, () => visit(node.thenExpression));
 | 
| -    visit(node.elseExpression);
 | 
| -  }
 | 
| -
 | 
| -  visitStringInterpolation(StringInterpolation node) {
 | 
| -    registry.registerInstantiatedClass(compiler.stringClass);
 | 
| -    registry.registerStringInterpolation();
 | 
| -    node.visitChildren(this);
 | 
| -  }
 | 
| -
 | 
| -  visitStringInterpolationPart(StringInterpolationPart node) {
 | 
| -    registerImplicitInvocation('toString', 0);
 | 
| -    node.visitChildren(this);
 | 
| -  }
 | 
| -
 | 
| -  visitBreakStatement(BreakStatement node) {
 | 
| -    JumpTarget target;
 | 
| -    if (node.target == null) {
 | 
| -      target = statementScope.currentBreakTarget();
 | 
| -      if (target == null) {
 | 
| -        error(node, MessageKind.NO_BREAK_TARGET);
 | 
| -        return;
 | 
| -      }
 | 
| -      target.isBreakTarget = true;
 | 
| -    } else {
 | 
| -      String labelName = node.target.source;
 | 
| -      LabelDefinition label = statementScope.lookupLabel(labelName);
 | 
| -      if (label == null) {
 | 
| -        error(node.target, MessageKind.UNBOUND_LABEL, {'labelName': labelName});
 | 
| -        return;
 | 
| -      }
 | 
| -      target = label.target;
 | 
| -      if (!target.statement.isValidBreakTarget()) {
 | 
| -        error(node.target, MessageKind.INVALID_BREAK);
 | 
| -        return;
 | 
| -      }
 | 
| -      label.setBreakTarget();
 | 
| -      registry.useLabel(node, label);
 | 
| -    }
 | 
| -    registry.registerTargetOf(node, target);
 | 
| -  }
 | 
| -
 | 
| -  visitContinueStatement(ContinueStatement node) {
 | 
| -    JumpTarget target;
 | 
| -    if (node.target == null) {
 | 
| -      target = statementScope.currentContinueTarget();
 | 
| -      if (target == null) {
 | 
| -        error(node, MessageKind.NO_CONTINUE_TARGET);
 | 
| -        return;
 | 
| -      }
 | 
| -      target.isContinueTarget = true;
 | 
| -    } else {
 | 
| -      String labelName = node.target.source;
 | 
| -      LabelDefinition label = statementScope.lookupLabel(labelName);
 | 
| -      if (label == null) {
 | 
| -        error(node.target, MessageKind.UNBOUND_LABEL, {'labelName': labelName});
 | 
| -        return;
 | 
| -      }
 | 
| -      target = label.target;
 | 
| -      if (!target.statement.isValidContinueTarget()) {
 | 
| -        error(node.target, MessageKind.INVALID_CONTINUE);
 | 
| -      }
 | 
| -      label.setContinueTarget();
 | 
| -      registry.useLabel(node, label);
 | 
| -    }
 | 
| -    registry.registerTargetOf(node, target);
 | 
| -  }
 | 
| -
 | 
| -  registerImplicitInvocation(String name, int arity) {
 | 
| -    Selector selector = new Selector.call(name, null, arity);
 | 
| -    registry.registerDynamicInvocation(selector);
 | 
| -  }
 | 
| -
 | 
| -  visitForIn(ForIn node) {
 | 
| -    LibraryElement library = enclosingElement.library;
 | 
| -    registry.setIteratorSelector(node, compiler.iteratorSelector);
 | 
| -    registry.registerDynamicGetter(compiler.iteratorSelector);
 | 
| -    registry.setCurrentSelector(node, compiler.currentSelector);
 | 
| -    registry.registerDynamicGetter(compiler.currentSelector);
 | 
| -    registry.setMoveNextSelector(node, compiler.moveNextSelector);
 | 
| -    registry.registerDynamicInvocation(compiler.moveNextSelector);
 | 
| -
 | 
| -    visit(node.expression);
 | 
| -    Scope blockScope = new BlockScope(scope);
 | 
| -    Node declaration = node.declaredIdentifier;
 | 
| -
 | 
| -    bool oldAllowFinalWithoutInitializer = allowFinalWithoutInitializer;
 | 
| -    allowFinalWithoutInitializer = true;
 | 
| -    visitIn(declaration, blockScope);
 | 
| -    allowFinalWithoutInitializer = oldAllowFinalWithoutInitializer;
 | 
| -
 | 
| -    Send send = declaration.asSend();
 | 
| -    VariableDefinitions variableDefinitions =
 | 
| -        declaration.asVariableDefinitions();
 | 
| -    Element loopVariable;
 | 
| -    Selector loopVariableSelector;
 | 
| -    if (send != null) {
 | 
| -      loopVariable = registry.getDefinition(send);
 | 
| -      Identifier identifier = send.selector.asIdentifier();
 | 
| -      if (identifier == null) {
 | 
| -        compiler.reportError(send.selector, MessageKind.INVALID_FOR_IN);
 | 
| -      } else {
 | 
| -        loopVariableSelector = new Selector.setter(identifier.source, library);
 | 
| -      }
 | 
| -      if (send.receiver != null) {
 | 
| -        compiler.reportError(send.receiver, MessageKind.INVALID_FOR_IN);
 | 
| -      }
 | 
| -    } else if (variableDefinitions != null) {
 | 
| -      Link<Node> nodes = variableDefinitions.definitions.nodes;
 | 
| -      if (!nodes.tail.isEmpty) {
 | 
| -        compiler.reportError(nodes.tail.head, MessageKind.INVALID_FOR_IN);
 | 
| -      }
 | 
| -      Node first = nodes.head;
 | 
| -      Identifier identifier = first.asIdentifier();
 | 
| -      if (identifier == null) {
 | 
| -        compiler.reportError(first, MessageKind.INVALID_FOR_IN);
 | 
| -      } else {
 | 
| -        loopVariableSelector = new Selector.setter(identifier.source, library);
 | 
| -        loopVariable = registry.getDefinition(identifier);
 | 
| -      }
 | 
| -    } else {
 | 
| -      compiler.reportError(declaration, MessageKind.INVALID_FOR_IN);
 | 
| -    }
 | 
| -    if (loopVariableSelector != null) {
 | 
| -      registry.setSelector(declaration, loopVariableSelector);
 | 
| -      registerSend(loopVariableSelector, loopVariable);
 | 
| -    } else {
 | 
| -      // The selector may only be null if we reported an error.
 | 
| -      assert(invariant(declaration, compiler.compilationFailed));
 | 
| -    }
 | 
| -    if (loopVariable != null) {
 | 
| -      // loopVariable may be null if it could not be resolved.
 | 
| -      registry.setForInVariable(node, loopVariable);
 | 
| -    }
 | 
| -    visitLoopBodyIn(node, node.body, blockScope);
 | 
| -  }
 | 
| -
 | 
| -  visitLabel(Label node) {
 | 
| -    // Labels are handled by their containing statements/cases.
 | 
| -  }
 | 
| -
 | 
| -  visitLabeledStatement(LabeledStatement node) {
 | 
| -    Statement body = node.statement;
 | 
| -    JumpTarget targetElement = getOrDefineTarget(body);
 | 
| -    Map<String, LabelDefinition> labelElements = <String, LabelDefinition>{};
 | 
| -    for (Label label in node.labels) {
 | 
| -      String labelName = label.labelName;
 | 
| -      if (labelElements.containsKey(labelName)) continue;
 | 
| -      LabelDefinition element = targetElement.addLabel(label, labelName);
 | 
| -      labelElements[labelName] = element;
 | 
| -    }
 | 
| -    statementScope.enterLabelScope(labelElements);
 | 
| -    visit(node.statement);
 | 
| -    statementScope.exitLabelScope();
 | 
| -    labelElements.forEach((String labelName, LabelDefinition element) {
 | 
| -      if (element.isTarget) {
 | 
| -        registry.defineLabel(element.label, element);
 | 
| -      } else {
 | 
| -        warning(element.label, MessageKind.UNUSED_LABEL,
 | 
| -                {'labelName': labelName});
 | 
| -      }
 | 
| -    });
 | 
| -    if (!targetElement.isTarget) {
 | 
| -      registry.undefineTarget(body);
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  visitLiteralMap(LiteralMap node) {
 | 
| -    bool oldSendIsMemberAccess = sendIsMemberAccess;
 | 
| -    sendIsMemberAccess = false;
 | 
| -
 | 
| -    NodeList arguments = node.typeArguments;
 | 
| -    DartType keyTypeArgument;
 | 
| -    DartType valueTypeArgument;
 | 
| -    if (arguments != null) {
 | 
| -      Link<Node> nodes = arguments.nodes;
 | 
| -      if (nodes.isEmpty) {
 | 
| -        // The syntax [: <>{} :] is not allowed.
 | 
| -        error(arguments, MessageKind.MISSING_TYPE_ARGUMENT);
 | 
| -      } else {
 | 
| -        keyTypeArgument = resolveTypeAnnotation(nodes.head);
 | 
| -        nodes = nodes.tail;
 | 
| -        if (nodes.isEmpty) {
 | 
| -          warning(arguments, MessageKind.MISSING_TYPE_ARGUMENT);
 | 
| -        } else {
 | 
| -          valueTypeArgument = resolveTypeAnnotation(nodes.head);
 | 
| -          for (nodes = nodes.tail; !nodes.isEmpty; nodes = nodes.tail) {
 | 
| -            warning(nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT);
 | 
| -            resolveTypeAnnotation(nodes.head);
 | 
| -          }
 | 
| -        }
 | 
| -      }
 | 
| -    }
 | 
| -    DartType mapType;
 | 
| -    if (valueTypeArgument != null) {
 | 
| -      mapType = new InterfaceType(compiler.mapClass,
 | 
| -          [keyTypeArgument, valueTypeArgument]);
 | 
| -    } else {
 | 
| -      compiler.mapClass.computeType(compiler);
 | 
| -      mapType = compiler.mapClass.rawType;
 | 
| -    }
 | 
| -    if (node.isConst && mapType.containsTypeVariables) {
 | 
| -      compiler.reportError(arguments,
 | 
| -          MessageKind.TYPE_VARIABLE_IN_CONSTANT);
 | 
| -    }
 | 
| -    registry.setType(node, mapType);
 | 
| -    registry.registerInstantiatedType(mapType);
 | 
| -    if (node.isConst) {
 | 
| -      registry.registerConstantMap();
 | 
| -    }
 | 
| -    registry.registerRequiredType(mapType, enclosingElement);
 | 
| -    node.visitChildren(this);
 | 
| -    if (node.isConst) {
 | 
| -      analyzeConstant(node);
 | 
| -    }
 | 
| -
 | 
| -    sendIsMemberAccess = false;
 | 
| -  }
 | 
| -
 | 
| -  visitLiteralMapEntry(LiteralMapEntry node) {
 | 
| -    node.visitChildren(this);
 | 
| -  }
 | 
| -
 | 
| -  visitNamedArgument(NamedArgument node) {
 | 
| -    visit(node.expression);
 | 
| -  }
 | 
| -
 | 
| -  DartType typeOfConstant(ConstantValue constant) {
 | 
| -    if (constant.isInt) return compiler.intClass.rawType;
 | 
| -    if (constant.isBool) return compiler.boolClass.rawType;
 | 
| -    if (constant.isDouble) return compiler.doubleClass.rawType;
 | 
| -    if (constant.isString) return compiler.stringClass.rawType;
 | 
| -    if (constant.isNull) return compiler.nullClass.rawType;
 | 
| -    if (constant.isFunction) return compiler.functionClass.rawType;
 | 
| -    assert(constant.isObject);
 | 
| -    ObjectConstantValue objectConstant = constant;
 | 
| -    return objectConstant.type;
 | 
| -  }
 | 
| -
 | 
| -  bool overridesEquals(DartType type) {
 | 
| -    ClassElement cls = type.element;
 | 
| -    Element equals = cls.lookupMember('==');
 | 
| -    return equals.enclosingClass != compiler.objectClass;
 | 
| -  }
 | 
| -
 | 
| -  void checkCaseExpressions(SwitchStatement node) {
 | 
| -    JumpTarget breakElement = getOrDefineTarget(node);
 | 
| -    Map<String, LabelDefinition> continueLabels = <String, LabelDefinition>{};
 | 
| -
 | 
| -    Link<Node> cases = node.cases.nodes;
 | 
| -    CaseMatch firstCase = null;
 | 
| -    DartType firstCaseType = null;
 | 
| -    bool hasReportedProblem = false;
 | 
| -
 | 
| -    for (Link<Node> cases = node.cases.nodes;
 | 
| -         !cases.isEmpty;
 | 
| -         cases = cases.tail) {
 | 
| -      SwitchCase switchCase = cases.head;
 | 
| -
 | 
| -      for (Node labelOrCase in switchCase.labelsAndCases) {
 | 
| -        CaseMatch caseMatch = labelOrCase.asCaseMatch();
 | 
| -        if (caseMatch == null) continue;
 | 
| -
 | 
| -        // Analyze the constant.
 | 
| -        ConstantExpression constant =
 | 
| -            registry.getConstant(caseMatch.expression);
 | 
| -        assert(invariant(node, constant != null,
 | 
| -            message: 'No constant computed for $node'));
 | 
| -
 | 
| -        DartType caseType = typeOfConstant(constant.value);
 | 
| -
 | 
| -        if (firstCaseType == null) {
 | 
| -          firstCase = caseMatch;
 | 
| -          firstCaseType = caseType;
 | 
| -
 | 
| -          // We only report the bad type on the first class element. All others
 | 
| -          // get a "type differs" error.
 | 
| -          if (caseType.element == compiler.doubleClass) {
 | 
| -            compiler.reportError(node,
 | 
| -                                 MessageKind.SWITCH_CASE_VALUE_OVERRIDES_EQUALS,
 | 
| -                                 {'type': "double"});
 | 
| -          } else if (caseType.element == compiler.functionClass) {
 | 
| -            compiler.reportError(node, MessageKind.SWITCH_CASE_FORBIDDEN,
 | 
| -                                 {'type': "Function"});
 | 
| -          } else if (constant.value.isObject && overridesEquals(caseType)) {
 | 
| -            compiler.reportError(firstCase.expression,
 | 
| -                MessageKind.SWITCH_CASE_VALUE_OVERRIDES_EQUALS,
 | 
| -                {'type': caseType});
 | 
| -          }
 | 
| -        } else {
 | 
| -          if (caseType != firstCaseType) {
 | 
| -            if (!hasReportedProblem) {
 | 
| -              compiler.reportError(
 | 
| -                  node,
 | 
| -                  MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL,
 | 
| -                  {'type': firstCaseType});
 | 
| -              compiler.reportInfo(
 | 
| -                  firstCase.expression,
 | 
| -                  MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL_CASE,
 | 
| -                  {'type': firstCaseType});
 | 
| -              hasReportedProblem = true;
 | 
| -            }
 | 
| -            compiler.reportInfo(
 | 
| -                caseMatch.expression,
 | 
| -                MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL_CASE,
 | 
| -                {'type': caseType});
 | 
| -          }
 | 
| -        }
 | 
| -      }
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  visitSwitchStatement(SwitchStatement node) {
 | 
| -    node.expression.accept(this);
 | 
| -
 | 
| -    JumpTarget breakElement = getOrDefineTarget(node);
 | 
| -    Map<String, LabelDefinition> continueLabels = <String, LabelDefinition>{};
 | 
| -    Link<Node> cases = node.cases.nodes;
 | 
| -    while (!cases.isEmpty) {
 | 
| -      SwitchCase switchCase = cases.head;
 | 
| -      for (Node labelOrCase in switchCase.labelsAndCases) {
 | 
| -        CaseMatch caseMatch = labelOrCase.asCaseMatch();
 | 
| -        if (caseMatch != null) {
 | 
| -          analyzeConstant(caseMatch.expression);
 | 
| -          continue;
 | 
| -        }
 | 
| -        Label label = labelOrCase;
 | 
| -        String labelName = label.labelName;
 | 
| -
 | 
| -        LabelDefinition existingElement = continueLabels[labelName];
 | 
| -        if (existingElement != null) {
 | 
| -          // It's an error if the same label occurs twice in the same switch.
 | 
| -          compiler.reportError(
 | 
| -              label,
 | 
| -              MessageKind.DUPLICATE_LABEL, {'labelName': labelName});
 | 
| -          compiler.reportInfo(
 | 
| -              existingElement.label,
 | 
| -              MessageKind.EXISTING_LABEL, {'labelName': labelName});
 | 
| -        } else {
 | 
| -          // It's only a warning if it shadows another label.
 | 
| -          existingElement = statementScope.lookupLabel(labelName);
 | 
| -          if (existingElement != null) {
 | 
| -            compiler.reportWarning(
 | 
| -                label,
 | 
| -                MessageKind.DUPLICATE_LABEL, {'labelName': labelName});
 | 
| -            compiler.reportInfo(
 | 
| -                existingElement.label,
 | 
| -                MessageKind.EXISTING_LABEL, {'labelName': labelName});
 | 
| -          }
 | 
| -        }
 | 
| -
 | 
| -        JumpTarget targetElement = getOrDefineTarget(switchCase);
 | 
| -        LabelDefinition labelElement = targetElement.addLabel(label, labelName);
 | 
| -        registry.defineLabel(label, labelElement);
 | 
| -        continueLabels[labelName] = labelElement;
 | 
| -      }
 | 
| -      cases = cases.tail;
 | 
| -      // Test that only the last case, if any, is a default case.
 | 
| -      if (switchCase.defaultKeyword != null && !cases.isEmpty) {
 | 
| -        error(switchCase, MessageKind.INVALID_CASE_DEFAULT);
 | 
| -      }
 | 
| -    }
 | 
| -
 | 
| -    addDeferredAction(enclosingElement, () {
 | 
| -      checkCaseExpressions(node);
 | 
| -    });
 | 
| -
 | 
| -    statementScope.enterSwitch(breakElement, continueLabels);
 | 
| -    node.cases.accept(this);
 | 
| -    statementScope.exitSwitch();
 | 
| -
 | 
| -    // Clean-up unused labels.
 | 
| -    continueLabels.forEach((String key, LabelDefinition label) {
 | 
| -      if (!label.isContinueTarget) {
 | 
| -        JumpTarget targetElement = label.target;
 | 
| -        SwitchCase switchCase = targetElement.statement;
 | 
| -        registry.undefineTarget(switchCase);
 | 
| -        registry.undefineLabel(label.label);
 | 
| -      }
 | 
| -    });
 | 
| -    // TODO(15575): We should warn if we can detect a fall through
 | 
| -    // error.
 | 
| -    registry.registerFallThroughError();
 | 
| -  }
 | 
| -
 | 
| -  visitSwitchCase(SwitchCase node) {
 | 
| -    node.labelsAndCases.accept(this);
 | 
| -    visitIn(node.statements, new BlockScope(scope));
 | 
| -  }
 | 
| -
 | 
| -  visitCaseMatch(CaseMatch node) {
 | 
| -    visit(node.expression);
 | 
| -  }
 | 
| -
 | 
| -  visitTryStatement(TryStatement node) {
 | 
| -    visit(node.tryBlock);
 | 
| -    if (node.catchBlocks.isEmpty && node.finallyBlock == null) {
 | 
| -      error(node.getEndToken().next, MessageKind.NO_CATCH_NOR_FINALLY);
 | 
| -    }
 | 
| -    visit(node.catchBlocks);
 | 
| -    visit(node.finallyBlock);
 | 
| -  }
 | 
| -
 | 
| -  visitCatchBlock(CatchBlock node) {
 | 
| -    registry.registerCatchStatement();
 | 
| -    // Check that if catch part is present, then
 | 
| -    // it has one or two formal parameters.
 | 
| -    VariableDefinitions exceptionDefinition;
 | 
| -    VariableDefinitions stackTraceDefinition;
 | 
| -    if (node.formals != null) {
 | 
| -      Link<Node> formalsToProcess = node.formals.nodes;
 | 
| -      if (formalsToProcess.isEmpty) {
 | 
| -        error(node, MessageKind.EMPTY_CATCH_DECLARATION);
 | 
| -      } else {
 | 
| -        exceptionDefinition = formalsToProcess.head.asVariableDefinitions();
 | 
| -        formalsToProcess = formalsToProcess.tail;
 | 
| -        if (!formalsToProcess.isEmpty) {
 | 
| -          stackTraceDefinition = formalsToProcess.head.asVariableDefinitions();
 | 
| -          formalsToProcess = formalsToProcess.tail;
 | 
| -          if (!formalsToProcess.isEmpty) {
 | 
| -            for (Node extra in formalsToProcess) {
 | 
| -              error(extra, MessageKind.EXTRA_CATCH_DECLARATION);
 | 
| -            }
 | 
| -          }
 | 
| -          registry.registerStackTraceInCatch();
 | 
| -        }
 | 
| -      }
 | 
| -
 | 
| -      // Check that the formals aren't optional and that they have no
 | 
| -      // modifiers or type.
 | 
| -      for (Link<Node> link = node.formals.nodes;
 | 
| -           !link.isEmpty;
 | 
| -           link = link.tail) {
 | 
| -        // If the formal parameter is a node list, it means that it is a
 | 
| -        // sequence of optional parameters.
 | 
| -        NodeList nodeList = link.head.asNodeList();
 | 
| -        if (nodeList != null) {
 | 
| -          error(nodeList, MessageKind.OPTIONAL_PARAMETER_IN_CATCH);
 | 
| -        } else {
 | 
| -          VariableDefinitions declaration = link.head;
 | 
| -          for (Node modifier in declaration.modifiers.nodes) {
 | 
| -            error(modifier, MessageKind.PARAMETER_WITH_MODIFIER_IN_CATCH);
 | 
| -          }
 | 
| -          TypeAnnotation type = declaration.type;
 | 
| -          if (type != null) {
 | 
| -            error(type, MessageKind.PARAMETER_WITH_TYPE_IN_CATCH);
 | 
| -          }
 | 
| -        }
 | 
| -      }
 | 
| -    }
 | 
| -
 | 
| -    Scope blockScope = new BlockScope(scope);
 | 
| -    doInCheckContext(() => visitIn(node.type, blockScope));
 | 
| -    visitIn(node.formals, blockScope);
 | 
| -    var oldInCatchBlock = inCatchBlock;
 | 
| -    inCatchBlock = true;
 | 
| -    visitIn(node.block, blockScope);
 | 
| -    inCatchBlock = oldInCatchBlock;
 | 
| -
 | 
| -    if (node.type != null && exceptionDefinition != null) {
 | 
| -      DartType exceptionType = registry.getType(node.type);
 | 
| -      Node exceptionVariable = exceptionDefinition.definitions.nodes.head;
 | 
| -      VariableElementX exceptionElement =
 | 
| -          registry.getDefinition(exceptionVariable);
 | 
| -      exceptionElement.variables.type = exceptionType;
 | 
| -    }
 | 
| -    if (stackTraceDefinition != null) {
 | 
| -      Node stackTraceVariable = stackTraceDefinition.definitions.nodes.head;
 | 
| -      VariableElementX stackTraceElement =
 | 
| -          registry.getDefinition(stackTraceVariable);
 | 
| -      registry.registerInstantiatedClass(compiler.stackTraceClass);
 | 
| -      stackTraceElement.variables.type = compiler.stackTraceClass.rawType;
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  visitTypedef(Typedef node) {
 | 
| -    internalError(node, 'typedef');
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -class TypeDefinitionVisitor extends MappingVisitor<DartType> {
 | 
| -  Scope scope;
 | 
| -  final TypeDeclarationElement enclosingElement;
 | 
| -  TypeDeclarationElement get element => enclosingElement;
 | 
| -
 | 
| -  TypeDefinitionVisitor(Compiler compiler,
 | 
| -                        TypeDeclarationElement element,
 | 
| -                        ResolutionRegistry registry)
 | 
| -      : this.enclosingElement = element,
 | 
| -        scope = Scope.buildEnclosingScope(element),
 | 
| -        super(compiler, registry);
 | 
| -
 | 
| -  DartType get objectType => compiler.objectClass.rawType;
 | 
| -
 | 
| -  void resolveTypeVariableBounds(NodeList node) {
 | 
| -    if (node == null) return;
 | 
| -
 | 
| -    Setlet<String> nameSet = new Setlet<String>();
 | 
| -    // Resolve the bounds of type variables.
 | 
| -    Iterator<DartType> types = element.typeVariables.iterator;
 | 
| -    Link<Node> nodeLink = node.nodes;
 | 
| -    while (!nodeLink.isEmpty) {
 | 
| -      types.moveNext();
 | 
| -      TypeVariableType typeVariable = types.current;
 | 
| -      String typeName = typeVariable.name;
 | 
| -      TypeVariable typeNode = nodeLink.head;
 | 
| -      registry.useType(typeNode, typeVariable);
 | 
| -      if (nameSet.contains(typeName)) {
 | 
| -        error(typeNode, MessageKind.DUPLICATE_TYPE_VARIABLE_NAME,
 | 
| -              {'typeVariableName': typeName});
 | 
| -      }
 | 
| -      nameSet.add(typeName);
 | 
| -
 | 
| -      TypeVariableElementX variableElement = typeVariable.element;
 | 
| -      if (typeNode.bound != null) {
 | 
| -        DartType boundType = typeResolver.resolveTypeAnnotation(
 | 
| -            this, typeNode.bound);
 | 
| -        variableElement.boundCache = boundType;
 | 
| -
 | 
| -        void checkTypeVariableBound() {
 | 
| -          Link<TypeVariableElement> seenTypeVariables =
 | 
| -              const Link<TypeVariableElement>();
 | 
| -          seenTypeVariables = seenTypeVariables.prepend(variableElement);
 | 
| -          DartType bound = boundType;
 | 
| -          while (bound.isTypeVariable) {
 | 
| -            TypeVariableElement element = bound.element;
 | 
| -            if (seenTypeVariables.contains(element)) {
 | 
| -              if (identical(element, variableElement)) {
 | 
| -                // Only report an error on the checked type variable to avoid
 | 
| -                // generating multiple errors for the same cyclicity.
 | 
| -                warning(typeNode.name, MessageKind.CYCLIC_TYPE_VARIABLE,
 | 
| -                    {'typeVariableName': variableElement.name});
 | 
| -              }
 | 
| -              break;
 | 
| -            }
 | 
| -            seenTypeVariables = seenTypeVariables.prepend(element);
 | 
| -            bound = element.bound;
 | 
| -          }
 | 
| -        }
 | 
| -        addDeferredAction(element, checkTypeVariableBound);
 | 
| -      } else {
 | 
| -        variableElement.boundCache = objectType;
 | 
| -      }
 | 
| -      nodeLink = nodeLink.tail;
 | 
| -    }
 | 
| -    assert(!types.moveNext());
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -class TypedefResolverVisitor extends TypeDefinitionVisitor {
 | 
| -  TypedefElementX get element => enclosingElement;
 | 
| -
 | 
| -  TypedefResolverVisitor(Compiler compiler,
 | 
| -                         TypedefElement typedefElement,
 | 
| -                         ResolutionRegistry registry)
 | 
| -      : super(compiler, typedefElement, registry);
 | 
| -
 | 
| -  visitTypedef(Typedef node) {
 | 
| -    TypedefType type = element.computeType(compiler);
 | 
| -    scope = new TypeDeclarationScope(scope, element);
 | 
| -    resolveTypeVariableBounds(node.typeParameters);
 | 
| -
 | 
| -    FunctionSignature signature = SignatureResolver.analyze(
 | 
| -        compiler, node.formals, node.returnType, element, registry,
 | 
| -        defaultValuesError: MessageKind.TYPEDEF_FORMAL_WITH_DEFAULT);
 | 
| -    element.functionSignature = signature;
 | 
| -
 | 
| -    scope = new MethodScope(scope, element);
 | 
| -    signature.forEachParameter(addToScope);
 | 
| -
 | 
| -    element.alias = signature.type;
 | 
| -
 | 
| -    void checkCyclicReference() {
 | 
| -      element.checkCyclicReference(compiler);
 | 
| -    }
 | 
| -    addDeferredAction(element, checkCyclicReference);
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -// TODO(johnniwinther): Replace with a traversal on the AST when the type
 | 
| -// annotations in typedef alias are stored in a [TreeElements] mapping.
 | 
| -class TypedefCyclicVisitor extends DartTypeVisitor {
 | 
| -  final Compiler compiler;
 | 
| -  final TypedefElementX element;
 | 
| -  bool hasCyclicReference = false;
 | 
| -
 | 
| -  Link<TypedefElement> seenTypedefs = const Link<TypedefElement>();
 | 
| -
 | 
| -  int seenTypedefsCount = 0;
 | 
| -
 | 
| -  Link<TypeVariableElement> seenTypeVariables =
 | 
| -      const Link<TypeVariableElement>();
 | 
| -
 | 
| -  TypedefCyclicVisitor(Compiler this.compiler, TypedefElement this.element);
 | 
| -
 | 
| -  visitType(DartType type, _) {
 | 
| -    // Do nothing.
 | 
| -  }
 | 
| -
 | 
| -  visitTypedefType(TypedefType type, _) {
 | 
| -    TypedefElementX typedefElement = type.element;
 | 
| -    if (seenTypedefs.contains(typedefElement)) {
 | 
| -      if (!hasCyclicReference && identical(element, typedefElement)) {
 | 
| -        // Only report an error on the checked typedef to avoid generating
 | 
| -        // multiple errors for the same cyclicity.
 | 
| -        hasCyclicReference = true;
 | 
| -        if (seenTypedefsCount == 1) {
 | 
| -          // Direct cyclicity.
 | 
| -          compiler.reportError(element,
 | 
| -              MessageKind.CYCLIC_TYPEDEF,
 | 
| -              {'typedefName': element.name});
 | 
| -        } else if (seenTypedefsCount == 2) {
 | 
| -          // Cyclicity through one other typedef.
 | 
| -          compiler.reportError(element,
 | 
| -              MessageKind.CYCLIC_TYPEDEF_ONE,
 | 
| -              {'typedefName': element.name,
 | 
| -               'otherTypedefName': seenTypedefs.head.name});
 | 
| -        } else {
 | 
| -          // Cyclicity through more than one other typedef.
 | 
| -          for (TypedefElement cycle in seenTypedefs) {
 | 
| -            if (!identical(typedefElement, cycle)) {
 | 
| -              compiler.reportError(element,
 | 
| -                  MessageKind.CYCLIC_TYPEDEF_ONE,
 | 
| -                  {'typedefName': element.name,
 | 
| -                   'otherTypedefName': cycle.name});
 | 
| -            }
 | 
| -          }
 | 
| -        }
 | 
| -        ErroneousElementX erroneousElement = new ErroneousElementX(
 | 
| -              MessageKind.CYCLIC_TYPEDEF,
 | 
| -              {'typedefName': element.name},
 | 
| -              element.name, element);
 | 
| -        element.alias =
 | 
| -            new MalformedType(erroneousElement, typedefElement.alias);
 | 
| -        element.hasBeenCheckedForCycles = true;
 | 
| -      }
 | 
| -    } else {
 | 
| -      seenTypedefs = seenTypedefs.prepend(typedefElement);
 | 
| -      seenTypedefsCount++;
 | 
| -      type.visitChildren(this, null);
 | 
| -      typedefElement.alias.accept(this, null);
 | 
| -      seenTypedefs = seenTypedefs.tail;
 | 
| -      seenTypedefsCount--;
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  visitFunctionType(FunctionType type, _) {
 | 
| -    type.visitChildren(this, null);
 | 
| -  }
 | 
| -
 | 
| -  visitInterfaceType(InterfaceType type, _) {
 | 
| -    type.visitChildren(this, null);
 | 
| -  }
 | 
| -
 | 
| -  visitTypeVariableType(TypeVariableType type, _) {
 | 
| -    TypeVariableElement typeVariableElement = type.element;
 | 
| -    if (seenTypeVariables.contains(typeVariableElement)) {
 | 
| -      // Avoid running in cycles on cyclic type variable bounds.
 | 
| -      // Cyclicity is reported elsewhere.
 | 
| -      return;
 | 
| -    }
 | 
| -    seenTypeVariables = seenTypeVariables.prepend(typeVariableElement);
 | 
| -    typeVariableElement.bound.accept(this, null);
 | 
| -    seenTypeVariables = seenTypeVariables.tail;
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -/**
 | 
| - * The implementation of [ResolverTask.resolveClass].
 | 
| - *
 | 
| - * This visitor has to be extra careful as it is building the basic
 | 
| - * element information, and cannot safely look at other elements as
 | 
| - * this may lead to cycles.
 | 
| - *
 | 
| - * This visitor can assume that the supertypes have already been
 | 
| - * resolved, but it cannot call [ResolverTask.resolveClass] directly
 | 
| - * or indirectly (through [ClassElement.ensureResolved]) for any other
 | 
| - * types.
 | 
| - */
 | 
| -class ClassResolverVisitor extends TypeDefinitionVisitor {
 | 
| -  BaseClassElementX get element => enclosingElement;
 | 
| -
 | 
| -  ClassResolverVisitor(Compiler compiler,
 | 
| -                       ClassElement classElement,
 | 
| -                       ResolutionRegistry registry)
 | 
| -    : super(compiler, classElement, registry);
 | 
| -
 | 
| -  DartType visitClassNode(ClassNode node) {
 | 
| -    invariant(node, element != null);
 | 
| -    invariant(element, element.resolutionState == STATE_STARTED,
 | 
| -        message: () => 'cyclic resolution of class $element');
 | 
| -
 | 
| -    InterfaceType type = element.computeType(compiler);
 | 
| -    scope = new TypeDeclarationScope(scope, element);
 | 
| -    // TODO(ahe): It is not safe to call resolveTypeVariableBounds yet.
 | 
| -    // As a side-effect, this may get us back here trying to
 | 
| -    // resolve this class again.
 | 
| -    resolveTypeVariableBounds(node.typeParameters);
 | 
| -
 | 
| -    // Setup the supertype for the element (if there is a cycle in the
 | 
| -    // class hierarchy, it has already been set to Object).
 | 
| -    if (element.supertype == null && node.superclass != null) {
 | 
| -      MixinApplication superMixin = node.superclass.asMixinApplication();
 | 
| -      if (superMixin != null) {
 | 
| -        DartType supertype = resolveSupertype(element, superMixin.superclass);
 | 
| -        Link<Node> link = superMixin.mixins.nodes;
 | 
| -        while (!link.isEmpty) {
 | 
| -          supertype = applyMixin(supertype,
 | 
| -                                 checkMixinType(link.head), link.head);
 | 
| -          link = link.tail;
 | 
| -        }
 | 
| -        element.supertype = supertype;
 | 
| -      } else {
 | 
| -        element.supertype = resolveSupertype(element, node.superclass);
 | 
| -      }
 | 
| -    }
 | 
| -    // If the super type isn't specified, we provide a default.  The language
 | 
| -    // specifies [Object] but the backend can pick a specific 'implementation'
 | 
| -    // of Object - the JavaScript backend chooses between Object and
 | 
| -    // Interceptor.
 | 
| -    if (element.supertype == null) {
 | 
| -      ClassElement superElement = registry.defaultSuperclass(element);
 | 
| -      // Avoid making the superclass (usually Object) extend itself.
 | 
| -      if (element != superElement) {
 | 
| -        if (superElement == null) {
 | 
| -          compiler.internalError(node,
 | 
| -              "Cannot resolve default superclass for $element.");
 | 
| -        } else {
 | 
| -          superElement.ensureResolved(compiler);
 | 
| -        }
 | 
| -        element.supertype = superElement.computeType(compiler);
 | 
| -      }
 | 
| -    }
 | 
| -
 | 
| -    if (element.interfaces == null) {
 | 
| -      element.interfaces = resolveInterfaces(node.interfaces, node.superclass);
 | 
| -    } else {
 | 
| -      assert(invariant(element, element.hasIncompleteHierarchy));
 | 
| -    }
 | 
| -    calculateAllSupertypes(element);
 | 
| -
 | 
| -    if (!element.hasConstructor) {
 | 
| -      Element superMember = element.superclass.localLookup('');
 | 
| -      if (superMember == null || !superMember.isGenerativeConstructor) {
 | 
| -        MessageKind kind = MessageKind.CANNOT_FIND_CONSTRUCTOR;
 | 
| -        Map arguments = {'constructorName': ''};
 | 
| -        // TODO(ahe): Why is this a compile-time error? Or if it is an error,
 | 
| -        // why do we bother to registerThrowNoSuchMethod below?
 | 
| -        compiler.reportError(node, kind, arguments);
 | 
| -        superMember = new ErroneousElementX(
 | 
| -            kind, arguments, '', element);
 | 
| -        registry.registerThrowNoSuchMethod();
 | 
| -      } else {
 | 
| -        ConstructorElement superConstructor = superMember;
 | 
| -        Selector callToMatch = new Selector.call("", element.library, 0);
 | 
| -        superConstructor.computeSignature(compiler);
 | 
| -        if (!callToMatch.applies(superConstructor, compiler.world)) {
 | 
| -          MessageKind kind = MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT;
 | 
| -          compiler.reportError(node, kind);
 | 
| -          superMember = new ErroneousElementX(kind, {}, '', element);
 | 
| -        }
 | 
| -      }
 | 
| -      FunctionElement constructor =
 | 
| -          new SynthesizedConstructorElementX.forDefault(superMember, element);
 | 
| -      element.setDefaultConstructor(constructor, compiler);
 | 
| -    }
 | 
| -    return element.computeType(compiler);
 | 
| -  }
 | 
| -
 | 
| -  /// Resolves the mixed type for [mixinNode] and checks that the the mixin type
 | 
| -  /// is a valid, non-blacklisted interface type. The mixin type is returned.
 | 
| -  DartType checkMixinType(TypeAnnotation mixinNode) {
 | 
| -    DartType mixinType = resolveType(mixinNode);
 | 
| -    if (isBlackListed(mixinType)) {
 | 
| -      compiler.reportError(mixinNode,
 | 
| -          MessageKind.CANNOT_MIXIN, {'type': mixinType});
 | 
| -    } else if (mixinType.isTypeVariable) {
 | 
| -      compiler.reportError(mixinNode, MessageKind.CLASS_NAME_EXPECTED);
 | 
| -    } else if (mixinType.isMalformed) {
 | 
| -      compiler.reportError(mixinNode, MessageKind.CANNOT_MIXIN_MALFORMED,
 | 
| -          {'className': element.name, 'malformedType': mixinType});
 | 
| -    }
 | 
| -    return mixinType;
 | 
| -  }
 | 
| -
 | 
| -  DartType visitNamedMixinApplication(NamedMixinApplication node) {
 | 
| -    invariant(node, element != null);
 | 
| -    invariant(element, element.resolutionState == STATE_STARTED,
 | 
| -        message: () => 'cyclic resolution of class $element');
 | 
| -
 | 
| -    if (identical(node.classKeyword.stringValue, 'typedef')) {
 | 
| -      // TODO(aprelev@gmail.com): Remove this deprecation diagnostic
 | 
| -      // together with corresponding TODO in parser.dart.
 | 
| -      compiler.reportWarning(node.classKeyword,
 | 
| -          MessageKind.DEPRECATED_TYPEDEF_MIXIN_SYNTAX);
 | 
| -    }
 | 
| -
 | 
| -    InterfaceType type = element.computeType(compiler);
 | 
| -    scope = new TypeDeclarationScope(scope, element);
 | 
| -    resolveTypeVariableBounds(node.typeParameters);
 | 
| -
 | 
| -    // Generate anonymous mixin application elements for the
 | 
| -    // intermediate mixin applications (excluding the last).
 | 
| -    DartType supertype = resolveSupertype(element, node.superclass);
 | 
| -    Link<Node> link = node.mixins.nodes;
 | 
| -    while (!link.tail.isEmpty) {
 | 
| -      supertype = applyMixin(supertype, checkMixinType(link.head), link.head);
 | 
| -      link = link.tail;
 | 
| -    }
 | 
| -    doApplyMixinTo(element, supertype, checkMixinType(link.head));
 | 
| -    return element.computeType(compiler);
 | 
| -  }
 | 
| -
 | 
| -  DartType applyMixin(DartType supertype, DartType mixinType, Node node) {
 | 
| -    String superName = supertype.name;
 | 
| -    String mixinName = mixinType.name;
 | 
| -    MixinApplicationElementX mixinApplication = new MixinApplicationElementX(
 | 
| -        "${superName}+${mixinName}",
 | 
| -        element.compilationUnit,
 | 
| -        compiler.getNextFreeClassId(),
 | 
| -        node,
 | 
| -        new Modifiers.withFlags(new NodeList.empty(), Modifiers.FLAG_ABSTRACT));
 | 
| -    // Create synthetic type variables for the mixin application.
 | 
| -    List<DartType> typeVariables = <DartType>[];
 | 
| -    element.typeVariables.forEach((TypeVariableType type) {
 | 
| -      TypeVariableElementX typeVariableElement = new TypeVariableElementX(
 | 
| -          type.name, mixinApplication, type.element.node);
 | 
| -      TypeVariableType typeVariable = new TypeVariableType(typeVariableElement);
 | 
| -      typeVariables.add(typeVariable);
 | 
| -    });
 | 
| -    // Setup bounds on the synthetic type variables.
 | 
| -    List<DartType> link = typeVariables;
 | 
| -    int index = 0;
 | 
| -    element.typeVariables.forEach((TypeVariableType type) {
 | 
| -      TypeVariableType typeVariable = typeVariables[index++];
 | 
| -      TypeVariableElementX typeVariableElement = typeVariable.element;
 | 
| -      typeVariableElement.typeCache = typeVariable;
 | 
| -      typeVariableElement.boundCache =
 | 
| -          type.element.bound.subst(typeVariables, element.typeVariables);
 | 
| -    });
 | 
| -    // Setup this and raw type for the mixin application.
 | 
| -    mixinApplication.computeThisAndRawType(compiler, typeVariables);
 | 
| -    // Substitute in synthetic type variables in super and mixin types.
 | 
| -    supertype = supertype.subst(typeVariables, element.typeVariables);
 | 
| -    mixinType = mixinType.subst(typeVariables, element.typeVariables);
 | 
| -
 | 
| -    doApplyMixinTo(mixinApplication, supertype, mixinType);
 | 
| -    mixinApplication.resolutionState = STATE_DONE;
 | 
| -    mixinApplication.supertypeLoadState = STATE_DONE;
 | 
| -    // Replace the synthetic type variables by the original type variables in
 | 
| -    // the returned type (which should be the type actually extended).
 | 
| -    InterfaceType mixinThisType = mixinApplication.computeType(compiler);
 | 
| -    return mixinThisType.subst(element.typeVariables,
 | 
| -                               mixinThisType.typeArguments);
 | 
| -  }
 | 
| -
 | 
| -  bool isDefaultConstructor(FunctionElement constructor) {
 | 
| -    return constructor.name == '' &&
 | 
| -        constructor.computeSignature(compiler).parameterCount == 0;
 | 
| -  }
 | 
| -
 | 
| -  FunctionElement createForwardingConstructor(ConstructorElement target,
 | 
| -                                              ClassElement enclosing) {
 | 
| -    return new SynthesizedConstructorElementX(
 | 
| -        target.name, target, enclosing, false);
 | 
| -  }
 | 
| -
 | 
| -  void doApplyMixinTo(MixinApplicationElementX mixinApplication,
 | 
| -                      DartType supertype,
 | 
| -                      DartType mixinType) {
 | 
| -    Node node = mixinApplication.parseNode(compiler);
 | 
| -
 | 
| -    if (mixinApplication.supertype != null) {
 | 
| -      // [supertype] is not null if there was a cycle.
 | 
| -      assert(invariant(node, compiler.compilationFailed));
 | 
| -      supertype = mixinApplication.supertype;
 | 
| -      assert(invariant(node, supertype.element == compiler.objectClass));
 | 
| -    } else {
 | 
| -      mixinApplication.supertype = supertype;
 | 
| -    }
 | 
| -
 | 
| -    // Named mixin application may have an 'implements' clause.
 | 
| -    NamedMixinApplication namedMixinApplication =
 | 
| -        node.asNamedMixinApplication();
 | 
| -    Link<DartType> interfaces = (namedMixinApplication != null)
 | 
| -        ? resolveInterfaces(namedMixinApplication.interfaces,
 | 
| -                            namedMixinApplication.superclass)
 | 
| -        : const Link<DartType>();
 | 
| -
 | 
| -    // The class that is the result of a mixin application implements
 | 
| -    // the interface of the class that was mixed in so always prepend
 | 
| -    // that to the interface list.
 | 
| -    if (mixinApplication.interfaces == null) {
 | 
| -      if (mixinType.isInterfaceType) {
 | 
| -        // Avoid malformed types in the interfaces.
 | 
| -        interfaces = interfaces.prepend(mixinType);
 | 
| -      }
 | 
| -      mixinApplication.interfaces = interfaces;
 | 
| -    } else {
 | 
| -      assert(invariant(mixinApplication,
 | 
| -          mixinApplication.hasIncompleteHierarchy));
 | 
| -    }
 | 
| -
 | 
| -    ClassElement superclass = supertype.element;
 | 
| -    if (mixinType.kind != TypeKind.INTERFACE) {
 | 
| -      mixinApplication.hasIncompleteHierarchy = true;
 | 
| -      mixinApplication.allSupertypesAndSelf = superclass.allSupertypesAndSelf;
 | 
| -      return;
 | 
| -    }
 | 
| -
 | 
| -    assert(mixinApplication.mixinType == null);
 | 
| -    mixinApplication.mixinType = resolveMixinFor(mixinApplication, mixinType);
 | 
| -
 | 
| -    // Create forwarding constructors for constructor defined in the superclass
 | 
| -    // because they are now hidden by the mixin application.
 | 
| -    superclass.forEachLocalMember((Element member) {
 | 
| -      if (!member.isGenerativeConstructor) return;
 | 
| -      FunctionElement forwarder =
 | 
| -          createForwardingConstructor(member, mixinApplication);
 | 
| -      if (isPrivateName(member.name) &&
 | 
| -          mixinApplication.library != superclass.library) {
 | 
| -        // Do not create a forwarder to the super constructor, because the mixin
 | 
| -        // application is in a different library than the constructor in the
 | 
| -        // super class and it is not possible to call that constructor from the
 | 
| -        // library using the mixin application.
 | 
| -        return;
 | 
| -      }
 | 
| -      mixinApplication.addConstructor(forwarder);
 | 
| -    });
 | 
| -    calculateAllSupertypes(mixinApplication);
 | 
| -  }
 | 
| -
 | 
| -  InterfaceType resolveMixinFor(MixinApplicationElement mixinApplication,
 | 
| -                                DartType mixinType) {
 | 
| -    ClassElement mixin = mixinType.element;
 | 
| -    mixin.ensureResolved(compiler);
 | 
| -
 | 
| -    // Check for cycles in the mixin chain.
 | 
| -    ClassElement previous = mixinApplication;  // For better error messages.
 | 
| -    ClassElement current = mixin;
 | 
| -    while (current != null && current.isMixinApplication) {
 | 
| -      MixinApplicationElement currentMixinApplication = current;
 | 
| -      if (currentMixinApplication == mixinApplication) {
 | 
| -        compiler.reportError(
 | 
| -            mixinApplication, MessageKind.ILLEGAL_MIXIN_CYCLE,
 | 
| -            {'mixinName1': current.name, 'mixinName2': previous.name});
 | 
| -        // We have found a cycle in the mixin chain. Return null as
 | 
| -        // the mixin for this application to avoid getting into
 | 
| -        // infinite recursion when traversing members.
 | 
| -        return null;
 | 
| -      }
 | 
| -      previous = current;
 | 
| -      current = currentMixinApplication.mixin;
 | 
| -    }
 | 
| -    registry.registerMixinUse(mixinApplication, mixin);
 | 
| -    return mixinType;
 | 
| -  }
 | 
| -
 | 
| -  DartType resolveType(TypeAnnotation node) {
 | 
| -    return typeResolver.resolveTypeAnnotation(this, node);
 | 
| -  }
 | 
| -
 | 
| -  DartType resolveSupertype(ClassElement cls, TypeAnnotation superclass) {
 | 
| -    DartType supertype = resolveType(superclass);
 | 
| -    if (supertype != null) {
 | 
| -      if (identical(supertype.kind, TypeKind.MALFORMED_TYPE)) {
 | 
| -        compiler.reportError(superclass, MessageKind.CANNOT_EXTEND_MALFORMED,
 | 
| -            {'className': element.name, 'malformedType': supertype});
 | 
| -        return objectType;
 | 
| -      } else if (!identical(supertype.kind, TypeKind.INTERFACE)) {
 | 
| -        compiler.reportError(superclass.typeName,
 | 
| -            MessageKind.CLASS_NAME_EXPECTED);
 | 
| -        return objectType;
 | 
| -      } else if (isBlackListed(supertype)) {
 | 
| -        compiler.reportError(superclass, MessageKind.CANNOT_EXTEND,
 | 
| -            {'type': supertype});
 | 
| -        return objectType;
 | 
| -      }
 | 
| -    }
 | 
| -    return supertype;
 | 
| -  }
 | 
| -
 | 
| -  Link<DartType> resolveInterfaces(NodeList interfaces, Node superclass) {
 | 
| -    Link<DartType> result = const Link<DartType>();
 | 
| -    if (interfaces == null) return result;
 | 
| -    for (Link<Node> link = interfaces.nodes; !link.isEmpty; link = link.tail) {
 | 
| -      DartType interfaceType = resolveType(link.head);
 | 
| -      if (interfaceType != null) {
 | 
| -        if (identical(interfaceType.kind, TypeKind.MALFORMED_TYPE)) {
 | 
| -          compiler.reportError(superclass,
 | 
| -              MessageKind.CANNOT_IMPLEMENT_MALFORMED,
 | 
| -              {'className': element.name, 'malformedType': interfaceType});
 | 
| -        } else if (!identical(interfaceType.kind, TypeKind.INTERFACE)) {
 | 
| -          // TODO(johnniwinther): Handle dynamic.
 | 
| -          TypeAnnotation typeAnnotation = link.head;
 | 
| -          error(typeAnnotation.typeName, MessageKind.CLASS_NAME_EXPECTED);
 | 
| -        } else {
 | 
| -          if (interfaceType == element.supertype) {
 | 
| -            compiler.reportError(
 | 
| -                superclass,
 | 
| -                MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS,
 | 
| -                {'type': interfaceType});
 | 
| -            compiler.reportError(
 | 
| -                link.head,
 | 
| -                MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS,
 | 
| -                {'type': interfaceType});
 | 
| -          }
 | 
| -          if (result.contains(interfaceType)) {
 | 
| -            compiler.reportError(
 | 
| -                link.head,
 | 
| -                MessageKind.DUPLICATE_IMPLEMENTS,
 | 
| -                {'type': interfaceType});
 | 
| -          }
 | 
| -          result = result.prepend(interfaceType);
 | 
| -          if (isBlackListed(interfaceType)) {
 | 
| -            error(link.head, MessageKind.CANNOT_IMPLEMENT,
 | 
| -                  {'type': interfaceType});
 | 
| -          }
 | 
| -        }
 | 
| -      }
 | 
| -    }
 | 
| -    return result;
 | 
| -  }
 | 
| -
 | 
| -  /**
 | 
| -   * Compute the list of all supertypes.
 | 
| -   *
 | 
| -   * The elements of this list are ordered as follows: first the supertype that
 | 
| -   * the class extends, then the implemented interfaces, and then the supertypes
 | 
| -   * of these.  The class [Object] appears only once, at the end of the list.
 | 
| -   *
 | 
| -   * For example, for a class `class C extends S implements I1, I2`, we compute
 | 
| -   *   supertypes(C) = [S, I1, I2] ++ supertypes(S) ++ supertypes(I1)
 | 
| -   *                   ++ supertypes(I2),
 | 
| -   * where ++ stands for list concatenation.
 | 
| -   *
 | 
| -   * This order makes sure that if a class implements an interface twice with
 | 
| -   * different type arguments, the type used in the most specific class comes
 | 
| -   * first.
 | 
| -   */
 | 
| -  void calculateAllSupertypes(BaseClassElementX cls) {
 | 
| -    if (cls.allSupertypesAndSelf != null) return;
 | 
| -    final DartType supertype = cls.supertype;
 | 
| -    if (supertype != null) {
 | 
| -      OrderedTypeSetBuilder allSupertypes = new OrderedTypeSetBuilder(cls);
 | 
| -      // TODO(15296): Collapse these iterations to one when the order is not
 | 
| -      // needed.
 | 
| -      allSupertypes.add(compiler, supertype);
 | 
| -      for (Link<DartType> interfaces = cls.interfaces;
 | 
| -           !interfaces.isEmpty;
 | 
| -           interfaces = interfaces.tail) {
 | 
| -        allSupertypes.add(compiler, interfaces.head);
 | 
| -      }
 | 
| -
 | 
| -      addAllSupertypes(allSupertypes, supertype);
 | 
| -      for (Link<DartType> interfaces = cls.interfaces;
 | 
| -           !interfaces.isEmpty;
 | 
| -           interfaces = interfaces.tail) {
 | 
| -        addAllSupertypes(allSupertypes, interfaces.head);
 | 
| -      }
 | 
| -      allSupertypes.add(compiler, cls.computeType(compiler));
 | 
| -      cls.allSupertypesAndSelf = allSupertypes.toTypeSet();
 | 
| -    } else {
 | 
| -      assert(identical(cls, compiler.objectClass));
 | 
| -      cls.allSupertypesAndSelf =
 | 
| -          new OrderedTypeSet.singleton(cls.computeType(compiler));
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  /**
 | 
| -   * Adds [type] and all supertypes of [type] to [allSupertypes] while
 | 
| -   * substituting type variables.
 | 
| -   */
 | 
| -  void addAllSupertypes(OrderedTypeSetBuilder allSupertypes,
 | 
| -                        InterfaceType type) {
 | 
| -    ClassElement classElement = type.element;
 | 
| -    Link<DartType> supertypes = classElement.allSupertypes;
 | 
| -    assert(invariant(element, supertypes != null,
 | 
| -        message: "Supertypes not computed on $classElement "
 | 
| -                 "during resolution of $element"));
 | 
| -    while (!supertypes.isEmpty) {
 | 
| -      DartType supertype = supertypes.head;
 | 
| -      allSupertypes.add(compiler, supertype.substByContext(type));
 | 
| -      supertypes = supertypes.tail;
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  isBlackListed(DartType type) {
 | 
| -    LibraryElement lib = element.library;
 | 
| -    return
 | 
| -      !identical(lib, compiler.coreLibrary) &&
 | 
| -      !compiler.backend.isBackendLibrary(lib) &&
 | 
| -      (type.isDynamic ||
 | 
| -       identical(type.element, compiler.boolClass) ||
 | 
| -       identical(type.element, compiler.numClass) ||
 | 
| -       identical(type.element, compiler.intClass) ||
 | 
| -       identical(type.element, compiler.doubleClass) ||
 | 
| -       identical(type.element, compiler.stringClass) ||
 | 
| -       identical(type.element, compiler.nullClass));
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -class ClassSupertypeResolver extends CommonResolverVisitor {
 | 
| -  Scope context;
 | 
| -  ClassElement classElement;
 | 
| -
 | 
| -  ClassSupertypeResolver(Compiler compiler, ClassElement cls)
 | 
| -    : context = Scope.buildEnclosingScope(cls),
 | 
| -      this.classElement = cls,
 | 
| -      super(compiler);
 | 
| -
 | 
| -  void loadSupertype(ClassElement element, Node from) {
 | 
| -    compiler.resolver.loadSupertypes(element, from);
 | 
| -    element.ensureResolved(compiler);
 | 
| -  }
 | 
| -
 | 
| -  void visitNodeList(NodeList node) {
 | 
| -    if (node != null) {
 | 
| -      for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) {
 | 
| -        link.head.accept(this);
 | 
| -      }
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  void visitClassNode(ClassNode node) {
 | 
| -    if (node.superclass == null) {
 | 
| -      if (!identical(classElement, compiler.objectClass)) {
 | 
| -        loadSupertype(compiler.objectClass, node);
 | 
| -      }
 | 
| -    } else {
 | 
| -      node.superclass.accept(this);
 | 
| -    }
 | 
| -    visitNodeList(node.interfaces);
 | 
| -  }
 | 
| -
 | 
| -  void visitMixinApplication(MixinApplication node) {
 | 
| -    node.superclass.accept(this);
 | 
| -    visitNodeList(node.mixins);
 | 
| -  }
 | 
| -
 | 
| -  void visitNamedMixinApplication(NamedMixinApplication node) {
 | 
| -    node.superclass.accept(this);
 | 
| -    visitNodeList(node.mixins);
 | 
| -    visitNodeList(node.interfaces);
 | 
| -  }
 | 
| -
 | 
| -  void visitTypeAnnotation(TypeAnnotation node) {
 | 
| -    node.typeName.accept(this);
 | 
| -  }
 | 
| -
 | 
| -  void visitIdentifier(Identifier node) {
 | 
| -    Element element = lookupInScope(compiler, node, context, node.source);
 | 
| -    if (element != null && element.isClass) {
 | 
| -      loadSupertype(element, node);
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  void visitSend(Send node) {
 | 
| -    Identifier prefix = node.receiver.asIdentifier();
 | 
| -    if (prefix == null) {
 | 
| -      error(node.receiver, MessageKind.NOT_A_PREFIX, {'node': node.receiver});
 | 
| -      return;
 | 
| -    }
 | 
| -    Element element = lookupInScope(compiler, prefix, context, prefix.source);
 | 
| -    if (element == null || !identical(element.kind, ElementKind.PREFIX)) {
 | 
| -      error(node.receiver, MessageKind.NOT_A_PREFIX, {'node': node.receiver});
 | 
| -      return;
 | 
| -    }
 | 
| -    PrefixElement prefixElement = element;
 | 
| -    Identifier selector = node.selector.asIdentifier();
 | 
| -    var e = prefixElement.lookupLocalMember(selector.source);
 | 
| -    if (e == null || !e.impliesType) {
 | 
| -      error(node.selector, MessageKind.CANNOT_RESOLVE_TYPE,
 | 
| -            {'typeName': node.selector});
 | 
| -      return;
 | 
| -    }
 | 
| -    loadSupertype(e, node);
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -class VariableDefinitionsVisitor extends CommonResolverVisitor<Identifier> {
 | 
| -  VariableDefinitions definitions;
 | 
| -  ResolverVisitor resolver;
 | 
| -  VariableList variables;
 | 
| -
 | 
| -  VariableDefinitionsVisitor(Compiler compiler,
 | 
| -                             this.definitions,
 | 
| -                             this.resolver,
 | 
| -                             this.variables)
 | 
| -      : super(compiler) {
 | 
| -  }
 | 
| -
 | 
| -  ResolutionRegistry get registry => resolver.registry;
 | 
| -
 | 
| -  Identifier visitSendSet(SendSet node) {
 | 
| -    assert(node.arguments.tail.isEmpty); // Sanity check
 | 
| -    Identifier identifier = node.selector;
 | 
| -    String name = identifier.source;
 | 
| -    VariableDefinitionScope scope =
 | 
| -        new VariableDefinitionScope(resolver.scope, name);
 | 
| -    resolver.visitIn(node.arguments.head, scope);
 | 
| -    if (scope.variableReferencedInInitializer) {
 | 
| -      compiler.reportError(
 | 
| -          identifier, MessageKind.REFERENCE_IN_INITIALIZATION,
 | 
| -          {'variableName': name});
 | 
| -    }
 | 
| -    return identifier;
 | 
| -  }
 | 
| -
 | 
| -  Identifier visitIdentifier(Identifier node) {
 | 
| -    // The variable is initialized to null.
 | 
| -    registry.registerInstantiatedClass(compiler.nullClass);
 | 
| -    if (definitions.modifiers.isConst) {
 | 
| -      compiler.reportError(node, MessageKind.CONST_WITHOUT_INITIALIZER);
 | 
| -    }
 | 
| -    if (definitions.modifiers.isFinal &&
 | 
| -        !resolver.allowFinalWithoutInitializer) {
 | 
| -      compiler.reportError(node, MessageKind.FINAL_WITHOUT_INITIALIZER);
 | 
| -    }
 | 
| -    return node;
 | 
| -  }
 | 
| -
 | 
| -  visitNodeList(NodeList node) {
 | 
| -    for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) {
 | 
| -      Identifier name = visit(link.head);
 | 
| -      LocalVariableElement element = new LocalVariableElementX(
 | 
| -          name.source, resolver.enclosingElement,
 | 
| -          variables, name.token);
 | 
| -      resolver.defineLocalVariable(link.head, element);
 | 
| -      resolver.addToScope(element);
 | 
| -      if (definitions.modifiers.isConst) {
 | 
| -        compiler.enqueuer.resolution.addDeferredAction(element, () {
 | 
| -          compiler.resolver.constantCompiler.compileConstant(element);
 | 
| -        });
 | 
| -      }
 | 
| -    }
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -class ConstructorResolver extends CommonResolverVisitor<Element> {
 | 
| -  final ResolverVisitor resolver;
 | 
| -  bool inConstContext;
 | 
| -  DartType type;
 | 
| -
 | 
| -  ConstructorResolver(Compiler compiler, this.resolver,
 | 
| -                      {bool this.inConstContext: false})
 | 
| -      : super(compiler);
 | 
| -
 | 
| -  ResolutionRegistry get registry => resolver.registry;
 | 
| -
 | 
| -  visitNode(Node node) {
 | 
| -    throw 'not supported';
 | 
| -  }
 | 
| -
 | 
| -  failOrReturnErroneousElement(Element enclosing, Node diagnosticNode,
 | 
| -                               String targetName, MessageKind kind,
 | 
| -                               Map arguments) {
 | 
| -    if (kind == MessageKind.CANNOT_FIND_CONSTRUCTOR) {
 | 
| -      registry.registerThrowNoSuchMethod();
 | 
| -    } else {
 | 
| -      registry.registerThrowRuntimeError();
 | 
| -    }
 | 
| -    if (inConstContext) {
 | 
| -      compiler.reportError(diagnosticNode, kind, arguments);
 | 
| -    } else {
 | 
| -      compiler.reportWarning(diagnosticNode, kind, arguments);
 | 
| -    }
 | 
| -    return new ErroneousElementX(kind, arguments, targetName, enclosing);
 | 
| -  }
 | 
| -
 | 
| -  Selector createConstructorSelector(String constructorName) {
 | 
| -    return constructorName == ''
 | 
| -        ? new Selector.callDefaultConstructor(
 | 
| -            resolver.enclosingElement.library)
 | 
| -        : new Selector.callConstructor(
 | 
| -            constructorName,
 | 
| -            resolver.enclosingElement.library);
 | 
| -  }
 | 
| -
 | 
| -  FunctionElement resolveConstructor(ClassElement cls,
 | 
| -                                     Node diagnosticNode,
 | 
| -                                     String constructorName) {
 | 
| -    cls.ensureResolved(compiler);
 | 
| -    Selector selector = createConstructorSelector(constructorName);
 | 
| -    Element result = cls.lookupConstructor(selector);
 | 
| -    if (result == null) {
 | 
| -      String fullConstructorName = Elements.constructorNameForDiagnostics(
 | 
| -              cls.name,
 | 
| -              constructorName);
 | 
| -      return failOrReturnErroneousElement(
 | 
| -          cls,
 | 
| -          diagnosticNode,
 | 
| -          fullConstructorName,
 | 
| -          MessageKind.CANNOT_FIND_CONSTRUCTOR,
 | 
| -          {'constructorName': fullConstructorName});
 | 
| -    } else if (inConstContext && !result.isConst) {
 | 
| -      error(diagnosticNode, MessageKind.CONSTRUCTOR_IS_NOT_CONST);
 | 
| -    }
 | 
| -    return result;
 | 
| -  }
 | 
| -
 | 
| -  Element visitNewExpression(NewExpression node) {
 | 
| -    inConstContext = node.isConst;
 | 
| -    Node selector = node.send.selector;
 | 
| -    Element element = visit(selector);
 | 
| -    assert(invariant(selector, element != null,
 | 
| -        message: 'No element return for $selector.'));
 | 
| -    return finishConstructorReference(element, node.send.selector, node);
 | 
| -  }
 | 
| -
 | 
| -  /// Finishes resolution of a constructor reference and records the
 | 
| -  /// type of the constructed instance on [expression].
 | 
| -  FunctionElement finishConstructorReference(Element element,
 | 
| -                                             Node diagnosticNode,
 | 
| -                                             Node expression) {
 | 
| -    assert(invariant(diagnosticNode, element != null,
 | 
| -        message: 'No element return for $diagnosticNode.'));
 | 
| -    // Find the unnamed constructor if the reference resolved to a
 | 
| -    // class.
 | 
| -    if (!Elements.isUnresolved(element) && !element.isConstructor) {
 | 
| -      if (element.isClass) {
 | 
| -        ClassElement cls = element;
 | 
| -        cls.ensureResolved(compiler);
 | 
| -        // The unnamed constructor may not exist, so [e] may become unresolved.
 | 
| -        element = resolveConstructor(cls, diagnosticNode, '');
 | 
| -      } else {
 | 
| -        element = failOrReturnErroneousElement(
 | 
| -            element, diagnosticNode, element.name, MessageKind.NOT_A_TYPE,
 | 
| -            {'node': diagnosticNode});
 | 
| -      }
 | 
| -    }
 | 
| -    if (type == null) {
 | 
| -      if (Elements.isUnresolved(element)) {
 | 
| -        type = const DynamicType();
 | 
| -      } else {
 | 
| -        type = element.enclosingClass.rawType;
 | 
| -      }
 | 
| -    }
 | 
| -    resolver.registry.setType(expression, type);
 | 
| -    return element;
 | 
| -  }
 | 
| -
 | 
| -  Element visitTypeAnnotation(TypeAnnotation node) {
 | 
| -    assert(invariant(node, type == null));
 | 
| -    // This is not really resolving a type-annotation, but the name of the
 | 
| -    // constructor. Therefore we allow deferred types.
 | 
| -    type = resolver.resolveTypeAnnotation(node,
 | 
| -                                          malformedIsError: inConstContext,
 | 
| -                                          deferredIsMalformed: false);
 | 
| -    registry.registerRequiredType(type, resolver.enclosingElement);
 | 
| -    return type.element;
 | 
| -  }
 | 
| -
 | 
| -  Element visitSend(Send node) {
 | 
| -    Element element = visit(node.receiver);
 | 
| -    assert(invariant(node.receiver, element != null,
 | 
| -        message: 'No element return for $node.receiver.'));
 | 
| -    if (Elements.isUnresolved(element)) return element;
 | 
| -    Identifier name = node.selector.asIdentifier();
 | 
| -    if (name == null) internalError(node.selector, 'unexpected node');
 | 
| -
 | 
| -    if (element.isClass) {
 | 
| -      ClassElement cls = element;
 | 
| -      cls.ensureResolved(compiler);
 | 
| -      return resolveConstructor(cls, name, name.source);
 | 
| -    } else if (element.isPrefix) {
 | 
| -      PrefixElement prefix = element;
 | 
| -      element = prefix.lookupLocalMember(name.source);
 | 
| -      element = Elements.unwrap(element, compiler, node);
 | 
| -      if (element == null) {
 | 
| -        return failOrReturnErroneousElement(
 | 
| -            resolver.enclosingElement, name,
 | 
| -            name.source,
 | 
| -            MessageKind.CANNOT_RESOLVE,
 | 
| -            {'name': name});
 | 
| -      } else if (!element.isClass) {
 | 
| -        error(node, MessageKind.NOT_A_TYPE, {'node': name});
 | 
| -      }
 | 
| -    } else {
 | 
| -      internalError(node.receiver, 'unexpected element $element');
 | 
| -    }
 | 
| -    return element;
 | 
| -  }
 | 
| -
 | 
| -  Element visitIdentifier(Identifier node) {
 | 
| -    String name = node.source;
 | 
| -    Element element = resolver.reportLookupErrorIfAny(
 | 
| -        lookupInScope(compiler, node, resolver.scope, name), node, name);
 | 
| -    registry.useElement(node, element);
 | 
| -    // TODO(johnniwinther): Change errors to warnings, cf. 11.11.1.
 | 
| -    if (element == null) {
 | 
| -      return failOrReturnErroneousElement(resolver.enclosingElement, node, name,
 | 
| -                                          MessageKind.CANNOT_RESOLVE,
 | 
| -                                          {'name': name});
 | 
| -    } else if (element.isErroneous) {
 | 
| -      return element;
 | 
| -    } else if (element.isTypedef) {
 | 
| -      error(node, MessageKind.CANNOT_INSTANTIATE_TYPEDEF,
 | 
| -            {'typedefName': name});
 | 
| -    } else if (element.isTypeVariable) {
 | 
| -      error(node, MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE,
 | 
| -            {'typeVariableName': name});
 | 
| -    } else if (!element.isClass && !element.isPrefix) {
 | 
| -      error(node, MessageKind.NOT_A_TYPE, {'node': name});
 | 
| -    }
 | 
| -    return element;
 | 
| -  }
 | 
| -
 | 
| -  /// Assumed to be called by [resolveRedirectingFactory].
 | 
| -  Element visitRedirectingFactoryBody(RedirectingFactoryBody node) {
 | 
| -    Node constructorReference = node.constructorReference;
 | 
| -    return finishConstructorReference(visit(constructorReference),
 | 
| -        constructorReference, node);
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -/// Looks up [name] in [scope] and unwraps the result.
 | 
| -Element lookupInScope(Compiler compiler, Node node,
 | 
| -                      Scope scope, String name) {
 | 
| -  return Elements.unwrap(scope.lookup(name), compiler, node);
 | 
| -}
 | 
| -
 | 
| -TreeElements _ensureTreeElements(AnalyzableElementX element) {
 | 
| -  if (element._treeElements == null) {
 | 
| -    element._treeElements = new TreeElementMapping(element);
 | 
| -  }
 | 
| -  return element._treeElements;
 | 
| -}
 | 
| -
 | 
| -abstract class AnalyzableElementX implements AnalyzableElement {
 | 
| -  TreeElements _treeElements;
 | 
| -
 | 
| -  bool get hasTreeElements => _treeElements != null;
 | 
| -
 | 
| -  TreeElements get treeElements {
 | 
| -    assert(invariant(this, _treeElements !=null,
 | 
| -        message: "TreeElements have not been computed for $this."));
 | 
| -    return _treeElements;
 | 
| -  }
 | 
| -
 | 
| -  void reuseElement() {
 | 
| -    _treeElements = null;
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -/// The result of resolving a node.
 | 
| -abstract class ResolutionResult {
 | 
| -  Element get element;
 | 
| -}
 | 
| -
 | 
| -/// The result for the resolution of a node that points to an [Element].
 | 
| -class ElementResult implements ResolutionResult {
 | 
| -  final Element element;
 | 
| -
 | 
| -  // TODO(johnniwinther): Remove this factory constructor when `null` is never
 | 
| -  // passed as an element result.
 | 
| -  factory ElementResult(Element element) {
 | 
| -    return element != null ? new ElementResult.internal(element) : null;
 | 
| -  }
 | 
| -
 | 
| -  ElementResult.internal(this.element);
 | 
| -
 | 
| -  String toString() => 'ElementResult($element)';
 | 
| -}
 | 
| -
 | 
| -/// The result for the resolution of a node that points to an [DartType].
 | 
| -class TypeResult implements ResolutionResult {
 | 
| -  final DartType type;
 | 
| -
 | 
| -  TypeResult(this.type) {
 | 
| -    assert(type != null);
 | 
| -  }
 | 
| -
 | 
| -  Element get element => type.element;
 | 
| -
 | 
| -  String toString() => 'TypeResult($type)';
 | 
| -}
 | 
| -
 | 
| -/// The result for the resolution of the `assert` method.
 | 
| -class AssertResult implements ResolutionResult {
 | 
| -  const AssertResult();
 | 
| -
 | 
| -  Element get element => null;
 | 
| -
 | 
| -  String toString() => 'AssertResult()';
 | 
| -}
 | 
| 
 |