package org.checkerframework.javacutil;

/*>>>
import org.checkerframework.checker.nullness.qual.*;
*/

import java.util.EnumSet;
import java.util.Set;

import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Name;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.util.ElementFilter;

import com.sun.source.tree.AnnotatedTypeTree;
import com.sun.source.tree.ArrayAccessTree;
import com.sun.source.tree.AssignmentTree;
import com.sun.source.tree.BinaryTree;
import com.sun.source.tree.BlockTree;
import com.sun.source.tree.ClassTree;
import com.sun.source.tree.CompoundAssignmentTree;
import com.sun.source.tree.ExpressionStatementTree;
import com.sun.source.tree.ExpressionTree;
import com.sun.source.tree.IdentifierTree;
import com.sun.source.tree.LiteralTree;
import com.sun.source.tree.MemberSelectTree;
import com.sun.source.tree.MethodInvocationTree;
import com.sun.source.tree.MethodTree;
import com.sun.source.tree.NewArrayTree;
import com.sun.source.tree.NewClassTree;
import com.sun.source.tree.ParameterizedTypeTree;
import com.sun.source.tree.ParenthesizedTree;
import com.sun.source.tree.PrimitiveTypeTree;
import com.sun.source.tree.ReturnTree;
import com.sun.source.tree.StatementTree;
import com.sun.source.tree.Tree;
import com.sun.source.tree.TypeCastTree;
import com.sun.source.tree.VariableTree;
import com.sun.source.util.TreePath;
import com.sun.source.util.Trees;
import com.sun.tools.javac.code.Flags;
import com.sun.tools.javac.code.Symbol.MethodSymbol;
import com.sun.tools.javac.tree.JCTree;

/**
 * A utility class made for helping to analyze a given {@code Tree}.
 */
// TODO: This class needs significant restructuring
public final class TreeUtils {

    // Class cannot be instantiated.
    private TreeUtils() { throw new AssertionError("Class TreeUtils cannot be instantiated."); }

    /**
     * Checks if the provided method is a constructor method or no.
     *
     * @param tree
     *            a tree defining the method
     * @return true iff tree describes a constructor
     */
    public static boolean isConstructor(final MethodTree tree) {
        return tree.getName().contentEquals("<init>");
    }

    /**
     * Checks if the method invocation is a call to super.
     *
     * @param tree
     *            a tree defining a method invocation
     *
     * @return true iff tree describes a call to super
     */
    public static boolean isSuperCall(MethodInvocationTree tree) {
        /*@Nullable*/ ExpressionTree mst = tree.getMethodSelect();
        assert mst != null; /*nninvariant*/

        if (mst.getKind() == Tree.Kind.IDENTIFIER ) {
            return ((IdentifierTree)mst).getName().contentEquals("super");
        }

        if (mst.getKind() == Tree.Kind.MEMBER_SELECT) {
            MemberSelectTree selectTree = (MemberSelectTree)mst;

            if (selectTree.getExpression().getKind() != Tree.Kind.IDENTIFIER) {
                return false;
            }

            return ((IdentifierTree) selectTree.getExpression()).getName()
                .contentEquals("super");
        }

        return false;
    }

    /**
     * Returns true if the tree is a tree that 'looks like' either an access
     * of a field or an invocation of a method that are owned by the same
     * accessing instance.
     *
     * It would only return true if the access tree is of the form:
     * <pre>
     *   field
     *   this.field
     *
     *   method()
     *   this.method()
     * </pre>
     *
     * It does not perform any semantical check to differentiate between
     * fields and local variables; local methods or imported static methods.
     *
     * @param tree  expression tree representing an access to object member
     * @return {@code true} iff the member is a member of {@code this} instance
     */
    public static boolean isSelfAccess(final ExpressionTree tree) {
        ExpressionTree tr = TreeUtils.skipParens(tree);
        // If method invocation check the method select
        if (tr.getKind() == Tree.Kind.ARRAY_ACCESS)
            return false;

        if (tree.getKind() == Tree.Kind.METHOD_INVOCATION) {
            tr = ((MethodInvocationTree)tree).getMethodSelect();
        }
        tr = TreeUtils.skipParens(tr);
        if (tr.getKind() == Tree.Kind.TYPE_CAST)
            tr = ((TypeCastTree)tr).getExpression();
        tr = TreeUtils.skipParens(tr);

        if (tr.getKind() == Tree.Kind.IDENTIFIER)
            return true;

        if (tr.getKind() == Tree.Kind.MEMBER_SELECT) {
            tr = ((MemberSelectTree)tr).getExpression();
            if (tr.getKind() == Tree.Kind.IDENTIFIER) {
                Name ident = ((IdentifierTree)tr).getName();
                return ident.contentEquals("this") ||
                        ident.contentEquals("super");
            }
        }

        return false;
    }

    /**
     * Gets the first enclosing tree in path, of the specified kind.
     *
     * @param path  the path defining the tree node
     * @param kind  the kind of the desired tree
     * @return the enclosing tree of the given type as given by the path
     */
    public static Tree enclosingOfKind(final TreePath path, final Tree.Kind kind) {
        return enclosingOfKind(path, EnumSet.of(kind));
    }

    /**
     * Gets the first enclosing tree in path, with any one of the specified kinds.
     *
     * @param path  the path defining the tree node
     * @param kinds  the set of kinds of the desired tree
     * @return the enclosing tree of the given type as given by the path
     */
    public static Tree enclosingOfKind(final TreePath path, final Set<Tree.Kind> kinds) {
        TreePath p = path;

        while (p != null) {
            Tree leaf = p.getLeaf();
            assert leaf != null; /*nninvariant*/
            if (kinds.contains(leaf.getKind()))
                return leaf;
            p = p.getParentPath();
        }

        return null;
    }

    /**
     * Gets path to the the first enclosing class tree, where class is
     * defined by the classTreeKinds method.
     *
     * @param path  the path defining the tree node
     * @return the path to the enclosing class tree
     */
    public static TreePath pathTillClass(final TreePath path) {
        return pathTillOfKind(path, classTreeKinds());
    }

    /**
     * Gets path to the the first enclosing tree of the specified kind.
     *
     * @param path  the path defining the tree node
     * @param kind  the kind of the desired tree
     * @return the path to the enclosing tree of the given type
     */
    public static TreePath pathTillOfKind(final TreePath path, final Tree.Kind kind) {
        return pathTillOfKind(path, EnumSet.of(kind));
    }

    /**
     * Gets path to the the first enclosing tree with any one of the specified kinds.
     *
     * @param path  the path defining the tree node
     * @param kinds  the set of kinds of the desired tree
     * @return the path to the enclosing tree of the given type
     */
    public static TreePath pathTillOfKind(final TreePath path, final Set<Tree.Kind> kinds) {
        TreePath p = path;

        while (p != null) {
            Tree leaf = p.getLeaf();
            assert leaf != null; /*nninvariant*/
            if (kinds.contains(leaf.getKind()))
                return p;
            p = p.getParentPath();
        }

        return null;
    }

    /**
     * Gets the first enclosing tree in path, of the specified class
     *
     * @param path  the path defining the tree node
     * @param treeClass the class of the desired tree
     * @return the enclosing tree of the given type as given by the path
     */
    public static <T extends Tree> T enclosingOfClass(final TreePath path, final Class<T> treeClass) {
        TreePath p = path;

        while (p != null) {
            Tree leaf = p.getLeaf();
            if (treeClass.isInstance(leaf))
                return treeClass.cast(leaf);
            p = p.getParentPath();
        }

        return null;
    }

    /**
     * Gets the enclosing class of the tree node defined by the given
     * {@code {@link TreePath}}. It returns a {@link Tree}, from which
     * {@code checkers.types.AnnotatedTypeMirror} or {@link Element} can be
     * obtained.
     *
     * @param path the path defining the tree node
     * @return the enclosing class (or interface) as given by the path, or null
     *         if one does not exist.
     */
    public static /*@Nullable*/ ClassTree enclosingClass(final /*@Nullable*/ TreePath path) {
        return (ClassTree) enclosingOfKind(path, classTreeKinds());
    }

    /**
     * Gets the enclosing variable of a tree node defined by the given
     * {@link TreePath}.
     *
     * @param path the path defining the tree node
     * @return the enclosing variable as given by the path, or null if one does not exist
     */
    public static VariableTree enclosingVariable(final TreePath path) {
        return (VariableTree) enclosingOfKind(path, Tree.Kind.VARIABLE);
    }

    /**
     * Gets the enclosing method of the tree node defined by the given
     * {@code {@link TreePath}}. It returns a {@link Tree}, from which an
     * {@code checkers.types.AnnotatedTypeMirror} or {@link Element} can be
     * obtained.
     *
     * @param path the path defining the tree node
     * @return the enclosing method as given by the path, or null if one does
     *         not exist
     */
    public static /*@Nullable*/ MethodTree enclosingMethod(final /*@Nullable*/ TreePath path) {
        return (MethodTree) enclosingOfKind(path, Tree.Kind.METHOD);
    }

    public static /*@Nullable*/ BlockTree enclosingTopLevelBlock(TreePath path) {
        TreePath parpath = path.getParentPath();
        while (parpath!=null && parpath.getLeaf().getKind() != Tree.Kind.CLASS) {
            path = parpath;
            parpath = parpath.getParentPath();
        }
        if (path.getLeaf().getKind() == Tree.Kind.BLOCK) {
            return (BlockTree) path.getLeaf();
        }
        return null;
    }


    /**
     * If the given tree is a parenthesized tree, it returns the enclosed
     * non-parenthesized tree. Otherwise, it returns the same tree.
     *
     * @param tree  an expression tree
     * @return  the outermost non-parenthesized tree enclosed by the given tree
     */
    public static ExpressionTree skipParens(final ExpressionTree tree) {
        ExpressionTree t = tree;
        while (t.getKind() == Tree.Kind.PARENTHESIZED)
            t = ((ParenthesizedTree)t).getExpression();
        return t;
    }

    /**
     * Returns the tree with the assignment context for the treePath
     * leaf node.
     *
     * The assignment context for the treepath is the most enclosing
     * tree of type:
     * <ul>
     *   <li>AssignmentTree </li>
     *   <li>CompoundAssignmentTree </li>
     *   <li>MethodInvocationTree</li>
     *   <li>NewArrayTree</li>
     *   <li>NewClassTree</li>
     *   <li>ReturnTree</li>
     *   <li>VariableTree</li>
     * </ul>
     *
     * @param treePath
     * @return  the assignment context as described.
     */
    public static Tree getAssignmentContext(final TreePath treePath) {
        TreePath path = treePath.getParentPath();

        if (path == null)
            return null;
        Tree node = path.getLeaf();
        if ((node instanceof AssignmentTree) ||
                (node instanceof CompoundAssignmentTree) ||
                (node instanceof MethodInvocationTree) ||
                (node instanceof NewArrayTree) ||
                (node instanceof NewClassTree) ||
                (node instanceof ReturnTree) ||
                (node instanceof VariableTree))
            return node;
        return null;
    }

    /**
     * Gets the element for a class corresponding to a declaration.
     *
     * @param node
     * @return the element for the given class
     */
    public static final TypeElement elementFromDeclaration(ClassTree node) {
        TypeElement elt = (TypeElement) InternalUtils.symbol(node);
        return elt;
    }

    /**
     * Gets the element for a method corresponding to a declaration.
     *
     * @param node
     * @return the element for the given method
     */
    public static final ExecutableElement elementFromDeclaration(MethodTree node) {
        ExecutableElement elt = (ExecutableElement) InternalUtils.symbol(node);
        return elt;
    }

    /**
     * Gets the element for a variable corresponding to its declaration.
     *
     * @param node
     * @return the element for the given variable
     */
    public static final VariableElement elementFromDeclaration(VariableTree node) {
        VariableElement elt = (VariableElement) InternalUtils.symbol(node);
        return elt;
    }

    /**
     * Gets the element for the declaration corresponding to this use of an element.
     * To get the element for a declaration, use {@link
     * Trees#getElement(TreePath)} instead.
     *
     * TODO: remove this method, as it really doesn't do anything.
     *
     * @param node the tree corresponding to a use of an element
     * @return the element for the corresponding declaration
     */
    public static final Element elementFromUse(ExpressionTree node) {
        return InternalUtils.symbol(node);
    }

    // Specialization for return type.
    public static final ExecutableElement elementFromUse(MethodInvocationTree node) {
        return (ExecutableElement) elementFromUse((ExpressionTree) node);
    }

    // Specialization for return type.
    public static final ExecutableElement elementFromUse(NewClassTree node) {
        return (ExecutableElement) elementFromUse((ExpressionTree) node);
    }


    /**
     * Determine whether the given ExpressionTree has an underlying element.
     *
     * @param node the ExpressionTree to test
     * @return whether the tree refers to an identifier, member select, or method invocation.
     */
    public static final boolean isUseOfElement(ExpressionTree node) {
        node = TreeUtils.skipParens(node);
        switch (node.getKind()) {
            case IDENTIFIER:
            case MEMBER_SELECT:
            case METHOD_INVOCATION:
            case NEW_CLASS:
                return true;
            default:
                return false;
        }
    }

    /**
     * @return the name of the invoked method
     */
    public static final Name methodName(MethodInvocationTree node) {
        ExpressionTree expr = node.getMethodSelect();
        if (expr.getKind() == Tree.Kind.IDENTIFIER)
            return ((IdentifierTree)expr).getName();
        else if (expr.getKind() == Tree.Kind.MEMBER_SELECT)
            return ((MemberSelectTree)expr).getIdentifier();
        ErrorReporter.errorAbort("TreeUtils.methodName: cannot be here: " + node);
        return null; // dead code
    }

    /**
     * @return true if the first statement in the body is a self constructor
     *  invocation within a constructor
     */
    public static final boolean containsThisConstructorInvocation(MethodTree node) {
        if (!TreeUtils.isConstructor(node)
                || node.getBody().getStatements().isEmpty())
            return false;

        StatementTree st = node.getBody().getStatements().get(0);
        if (!(st instanceof ExpressionStatementTree)
                || !(((ExpressionStatementTree)st).getExpression() instanceof MethodInvocationTree))
            return false;

        MethodInvocationTree invocation = (MethodInvocationTree)
            ((ExpressionStatementTree)st).getExpression();

        return "this".contentEquals(TreeUtils.methodName(invocation));
    }

    public static final Tree firstStatement(Tree tree) {
        Tree first;
        if (tree.getKind() == Tree.Kind.BLOCK) {
            BlockTree block = (BlockTree)tree;
            if (block.getStatements().isEmpty())
                first = block;
            else
                first = block.getStatements().iterator().next();
        } else {
            first = tree;
        }
        return first;
    }

    /**
     * Determine whether the given class contains an explicit constructor.
     *
     * @param node A class tree.
     * @return True, iff there is an explicit constructor.
     */
    public static boolean hasExplicitConstructor(ClassTree node) {
        TypeElement elem = TreeUtils.elementFromDeclaration(node);

        for ( ExecutableElement ee : ElementFilter.constructorsIn(elem.getEnclosedElements())) {
            MethodSymbol ms = (MethodSymbol) ee;
            long mod = ms.flags();

            if ((mod & Flags.SYNTHETIC) == 0) {
                return true;
            }
        }
        return false;
    }

    /**
     * Returns true if the tree is of a diamond type.
     * In contrast to the implementation in TreeInfo, this version
     * works on Trees.
     *
     * @see com.sun.tools.javac.tree.TreeInfo#isDiamond(JCTree)
     */
    public static final boolean isDiamondTree(Tree tree) {
        switch (tree.getKind()) {
        case ANNOTATED_TYPE: return isDiamondTree(((AnnotatedTypeTree)tree).getUnderlyingType());
        case PARAMETERIZED_TYPE: return ((ParameterizedTypeTree)tree).getTypeArguments().isEmpty();
        case NEW_CLASS: return isDiamondTree(((NewClassTree)tree).getIdentifier());
        default: return false;
        }
    }

    /**
     * Returns true if the tree represents a {@code String} concatenation
     * operation
     */
    public static final boolean isStringConcatenation(Tree tree) {
        return (tree.getKind() == Tree.Kind.PLUS
                && TypesUtils.isString(InternalUtils.typeOf(tree)));
    }

    /**
     * Returns true if the compound assignment tree is a string concatenation
     */
    public static final boolean isStringCompoundConcatenation(CompoundAssignmentTree tree) {
        return (tree.getKind() == Tree.Kind.PLUS_ASSIGNMENT
                && TypesUtils.isString(InternalUtils.typeOf(tree)));
    }

    /**
     * Returns true if the node is a constant-time expression.
     *
     * A tree is a constant-time expression if it is:
     * <ol>
     * <li>a literal tree
     * <li>a reference to a final variable initialized with a compile time
     *  constant
     * <li>a String concatenation of two compile time constants
     * </ol>
     */
    public static boolean isCompileTimeString(ExpressionTree node) {
        ExpressionTree tree = TreeUtils.skipParens(node);
        if (tree instanceof LiteralTree)
            return true;

        if (TreeUtils.isUseOfElement(tree)) {
            Element elt = TreeUtils.elementFromUse(tree);
            return ElementUtils.isCompileTimeConstant(elt);
        } else if (TreeUtils.isStringConcatenation(tree)) {
            BinaryTree binOp = (BinaryTree) tree;
            return isCompileTimeString(binOp.getLeftOperand())
                && isCompileTimeString(binOp.getRightOperand());
        } else {
            return false;
        }
    }

    /**
     * Returns the receiver tree of a field access or a method invocation
     */
    public static ExpressionTree getReceiverTree(ExpressionTree expression) {
        ExpressionTree receiver = TreeUtils.skipParens(expression);

        if (!(receiver.getKind() == Tree.Kind.METHOD_INVOCATION
                || receiver.getKind() == Tree.Kind.MEMBER_SELECT
                || receiver.getKind() == Tree.Kind.IDENTIFIER
                || receiver.getKind() == Tree.Kind.ARRAY_ACCESS)) {
            // No receiver tree for anything but these four kinds.
            return null;
        }

        if (receiver.getKind() == Tree.Kind.METHOD_INVOCATION) {
            // Trying to handle receiver calls to trees of the form
            //     ((m).getArray())
            // returns the type of 'm' in this case
            receiver = ((MethodInvocationTree)receiver).getMethodSelect();

            if (receiver.getKind() == Tree.Kind.IDENTIFIER) {
                // It's a method call "m(foo)" without an explicit receiver
                return null;
            } else if (receiver.getKind() == Tree.Kind.MEMBER_SELECT) {
                receiver = ((MemberSelectTree)receiver).getExpression();
            } else {
                // Otherwise, e.g. a NEW_CLASS: nothing to do.
            }
        } else if (receiver.getKind() == Tree.Kind.IDENTIFIER) {
            // It's a field access on implicit this or a local variable/parameter.
            return null;
        } else if (receiver.getKind() == Tree.Kind.ARRAY_ACCESS) {
            return TreeUtils.skipParens(((ArrayAccessTree)receiver).getExpression());
        } else if (receiver.getKind() == Tree.Kind.MEMBER_SELECT) {
            receiver = ((MemberSelectTree)receiver).getExpression();
            // Avoid int.class
            if (receiver instanceof PrimitiveTypeTree) {
                return null;
            }
        }

        // Receiver is now really just the receiver tree.
        return TreeUtils.skipParens(receiver);
    }

    // TODO: What about anonymous classes?
    // Adding Tree.Kind.NEW_CLASS here doesn't work, because then a
    // tree gets cast to ClassTree when it is actually a NewClassTree,
    // for example in enclosingClass above.
    private final static Set<Tree.Kind> classTreeKinds = EnumSet.of(
            Tree.Kind.CLASS,
            Tree.Kind.ENUM,
            Tree.Kind.INTERFACE,
            Tree.Kind.ANNOTATION_TYPE
    );

    public static Set<Tree.Kind> classTreeKinds() {
        return classTreeKinds;
    }

    /**
     * Is the given tree kind a class, i.e. a class, enum,
     * interface, or annotation type.
     *
     * @param tree the tree to test
     * @return true, iff the given kind is a class kind
     */
    public static boolean isClassTree(Tree tree) {
        return classTreeKinds().contains(tree.getKind());
    }

    private final static Set<Tree.Kind> typeTreeKinds = EnumSet.of(
            Tree.Kind.PRIMITIVE_TYPE,
            Tree.Kind.PARAMETERIZED_TYPE,
            Tree.Kind.TYPE_PARAMETER,
            Tree.Kind.ARRAY_TYPE,
            Tree.Kind.UNBOUNDED_WILDCARD,
            Tree.Kind.EXTENDS_WILDCARD,
            Tree.Kind.SUPER_WILDCARD,
            Tree.Kind.ANNOTATED_TYPE
    );

    public static Set<Tree.Kind> typeTreeKinds() {
        return typeTreeKinds;
    }

    /**
     * Is the given tree a type instantiation?
     *
     * TODO: this is an under-approximation: e.g. an identifier could
     * be either a type use or an expression. How can we distinguish.
     *
     * @param tree the tree to test
     * @return true, iff the given tree is a type
     */
    public static boolean isTypeTree(Tree tree) {
        return typeTreeKinds().contains(tree.getKind());
    }

    /**
     * Returns true if the given element is an invocation of the method, or
     * of any method that overrides that one.
     */
    public static boolean isMethodInvocation(Tree tree, ExecutableElement method, ProcessingEnvironment env) {
        if (!(tree instanceof MethodInvocationTree))
            return false;
        MethodInvocationTree methInvok = (MethodInvocationTree)tree;
        ExecutableElement invoked = TreeUtils.elementFromUse(methInvok);
        return isMethod(invoked, method, env);
    }

    /** Returns true if the given element is, or overrides, method. */
    private static boolean isMethod(ExecutableElement questioned, ExecutableElement method, ProcessingEnvironment env) {
        return (questioned.equals(method)
                || env.getElementUtils().overrides(questioned, method,
                        (TypeElement)questioned.getEnclosingElement()));
    }

    /**
     * Returns the ExecutableElement for a method declaration of
     * methodName, in class typeName, with params parameters.
     *
     * TODO: to precisely resolve method overloading, we should use parameter types and not just
     * the number of parameters!
     */
    public static ExecutableElement getMethod(String typeName, String methodName, int params, ProcessingEnvironment env) {
        TypeElement mapElt = env.getElementUtils().getTypeElement(typeName);
        for (ExecutableElement exec : ElementFilter.methodsIn(mapElt.getEnclosedElements())) {
            if (exec.getSimpleName().contentEquals(methodName)
                    && exec.getParameters().size() == params)
                return exec;
        }
        ErrorReporter.errorAbort("TreeUtils.getMethod: shouldn't be here!");
        return null; // dead code
    }

    /**
     * Determine whether the given expression is either "this" or an outer
     * "C.this".
     *
     * TODO: Should this also handle "super"?
     *
     * @param tree
     * @return
     */
    public static final boolean isExplicitThisDereference(ExpressionTree tree) {
        if (tree.getKind() == Tree.Kind.IDENTIFIER
                && ((IdentifierTree)tree).getName().contentEquals("this")) {
            // Explicit this reference "this"
            return true;
        }

        if (tree.getKind() != Tree.Kind.MEMBER_SELECT) {
            return false;
        }

        MemberSelectTree memSelTree = (MemberSelectTree) tree;
        if (memSelTree.getIdentifier().contentEquals("this")) {
            // Outer this reference "C.this"
            return true;
        }
        return false;
    }

    /**
     * Determine whether <code>tree</code> is a field access expressions, such
     * as
     *
     * <pre>
     *   <em>f</em>
     *   <em>obj</em> . <em>f</em>
     * </pre>
     *
     * @return true iff if tree is a field access expression (implicit or
     *         explicit).
     */
    public static boolean isFieldAccess(Tree tree) {
        if (tree.getKind().equals(Tree.Kind.MEMBER_SELECT)) {
            // explicit field access
            MemberSelectTree memberSelect = (MemberSelectTree) tree;
            Element el = TreeUtils.elementFromUse(memberSelect);
            return el.getKind().isField();
        } else if (tree.getKind().equals(Tree.Kind.IDENTIFIER)) {
            // implicit field access
            IdentifierTree ident = (IdentifierTree) tree;
            Element el = TreeUtils.elementFromUse(ident);
            return el.getKind().isField()
                    && !ident.getName().contentEquals("this") && !ident.getName().contentEquals("super");
        }
        return false;
    }

    /**
     * Compute the name of the field that the field access <code>tree</code>
     * accesses. Requires <code>tree</code> to be a field access, as determined
     * by <code>isFieldAccess</code>.
     *
     * @return The name of the field accessed by <code>tree</code>.
     */
    public static String getFieldName(Tree tree) {
        assert isFieldAccess(tree);
        if (tree.getKind().equals(Tree.Kind.MEMBER_SELECT)) {
            MemberSelectTree mtree = (MemberSelectTree) tree;
            return mtree.getIdentifier().toString();
        } else {
            IdentifierTree itree = (IdentifierTree) tree;
            return itree.getName().toString();
        }
    }

    /**
     * Determine whether <code>tree</code> refers to a method element, such
     * as
     *
     * <pre>
     *   <em>m</em>(...)
     *   <em>obj</em> . <em>m</em>(...)
     * </pre>
     *
     * @return true iff if tree is a method access expression (implicit or
     *         explicit).
     */
    public static boolean isMethodAccess(Tree tree) {
        if (tree.getKind().equals(Tree.Kind.MEMBER_SELECT)) {
            // explicit method access
            MemberSelectTree memberSelect = (MemberSelectTree) tree;
            Element el = TreeUtils.elementFromUse(memberSelect);
            return el.getKind() == ElementKind.METHOD
                    || el.getKind() == ElementKind.CONSTRUCTOR;
        } else if (tree.getKind().equals(Tree.Kind.IDENTIFIER)) {
            // implicit method access
            IdentifierTree ident = (IdentifierTree) tree;
            // The field "super" and "this" are also legal methods
            if (ident.getName().contentEquals("super")
                    || ident.getName().contentEquals("this")) {
                return true;
            }
            Element el = TreeUtils.elementFromUse(ident);
            return el.getKind() == ElementKind.METHOD
                    || el.getKind() == ElementKind.CONSTRUCTOR;
        }
        return false;
    }

    /**
     * Compute the name of the method that the method access <code>tree</code>
     * accesses. Requires <code>tree</code> to be a method access, as determined
     * by <code>isMethodAccess</code>.
     *
     * @return The name of the method accessed by <code>tree</code>.
     */
    public static String getMethodName(Tree tree) {
        assert isMethodAccess(tree);
        if (tree.getKind().equals(Tree.Kind.MEMBER_SELECT)) {
            MemberSelectTree mtree = (MemberSelectTree) tree;
            return mtree.getIdentifier().toString();
        } else {
            IdentifierTree itree = (IdentifierTree) tree;
            return itree.getName().toString();
        }
    }

    /**
     * @return {@code true} if and only if {@code tree} can have a type
     *         annotation.
     *
     * TODO: is this implementation precise enough? E.g. does
     * a .class literal work correctly?
     */
    public static boolean canHaveTypeAnnotation(Tree tree) {
        return ((JCTree) tree).type != null;
    }

    /**
     * Returns true if and only if the given {@code tree} represents a field
     * access of the given {@link VariableElement}.
     */
    public static boolean isSpecificFieldAccess(Tree tree, VariableElement var) {
        if (tree instanceof MemberSelectTree) {
            MemberSelectTree memSel = (MemberSelectTree) tree;
            Element field = TreeUtils.elementFromUse(memSel);
            return field.equals(var);
        } else if (tree instanceof IdentifierTree) {
            IdentifierTree idTree = (IdentifierTree) tree;
            Element field = TreeUtils.elementFromUse(idTree);
            return field.equals(var);
        } else {
            return false;
        }
    }

    /**
     * Returns the VariableElement for a field declaration.
     *
     * @param typeName the class where the field is declared.
     * @param fieldName the name of the field.
     * @param env the processing environment.
     * @return the VariableElement for typeName.fieldName
     */
    public static VariableElement getField(String typeName, String fieldName, ProcessingEnvironment env) {
        TypeElement mapElt = env.getElementUtils().getTypeElement(typeName);
        for (VariableElement var : ElementFilter.fieldsIn(mapElt.getEnclosedElements())) {
            if (var.getSimpleName().contentEquals(fieldName)) {
                return var;
            }
        }
        ErrorReporter.errorAbort("TreeUtils.getField: shouldn't be here!");
        return null; // dead code
    }

    /** Determine whether the given tree represents an ExpressionTree.
     *
     * TODO: is there a nicer way than an instanceof?
     *
     * @param tree the Tree to test.
     * @return whether the tree is an ExpressionTree
     */
    public static boolean isExpressionTree(Tree tree) {
        return tree instanceof ExpressionTree;
    }

    /**
     * @param node the method invocation to check
     * @return true if this is a super call to the {@link Enum} constructor
     */
    public static boolean isEnumSuper(MethodInvocationTree node) {
        ExecutableElement ex = TreeUtils.elementFromUse(node);
        Name name = ElementUtils.getQualifiedClassName(ex);
        boolean correctClass = "java.lang.Enum".contentEquals(name);
        boolean correctMethod = "<init>".contentEquals(ex.getSimpleName());
        return correctClass && correctMethod;
    }

    /** Determine whether the given tree represents a declaration of a type
     * (including type parameters).
     *
     * @param node  the Tree to test
     * @return true if the tree is a type declaration
     */
    public static boolean isTypeDeclaration(Tree node) {
        switch (node.getKind()) {
            // These tree kinds are always declarations.  Uses of the declared
            // types have tree kind IDENTIFIER.
            case ANNOTATION_TYPE:
            case CLASS:
            case ENUM:
            case INTERFACE:
            case TYPE_PARAMETER:
                return true;

            default:
                return false;
        }
    }
}
