content: // 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 dart2js;
  
  abstract class ResolvedVisitor<R> extends Visitor<R> {
    final Compiler compiler;
    TreeElements elements;
  
    ResolvedVisitor(this.elements, this.compiler);
  
    R visitSend(Send node) {
      Element element = elements[node];
      if (node.isSuperCall) {
        return visitSuperSend(node);
      } else if (node.isOperator) {
        return visitOperatorSend(node);
      } else if (node.isPropertyAccess) {
        if (!Elements.isUnresolved(element) && element.impliesType()) {
          // A reference to a class literal, typedef or type variable.
          return visitTypeReferenceSend(node);
        } else {
          return visitGetterSend(node);
        }
      } else if (element != null && Initializers.isConstructorRedirect(node)) {
        return visitStaticSend(node);
      } else if (Elements.isClosureSend(node, element)) {
        return visitClosureSend(node);
      } else if (element == compiler.assertMethod) {
        assert(element != null);
        return visitAssert(node);
      } else {
        if (Elements.isUnresolved(element)) {
          if (element == null) {
            // Example: f() with 'f' unbound.
            // This can only happen inside an instance method.
            return visitDynamicSend(node);
          } else {
            return visitStaticSend(node);
          }
        } else if (element.impliesType()) {
          // A reference to a class literal, typedef or type variable.
          return visitTypeReferenceSend(node);
        } else if (element.isInstanceMember()) {
          // Example: f() with 'f' bound to instance method.
          return visitDynamicSend(node);
        } else if (!element.isInstanceMember()) {
          // Example: A.f() or f() with 'f' bound to a static function.
          // Also includes new A() or new A.named() which is treated like a
          // static call to a factory.
          return visitStaticSend(node);
        } else {
          internalError("Cannot generate code for send", node: node);
        }
      }
    }
  
    R visitSuperSend(Send node);
    R visitOperatorSend(Send node);
    R visitGetterSend(Send node);
    R visitClosureSend(Send node);
    R visitDynamicSend(Send node);
    R visitStaticSend(Send node);
    R visitTypeReferenceSend(Send node);
    R visitAssert(Send node);
  
    void internalError(String reason, {Node node});
  
    R visitNode(Node node) {
      internalError("Unhandled node", node: node);
    }
  }
  