package org.checkerframework.javacutil;

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

import com.sun.source.tree.AnnotatedTypeTree;
import com.sun.source.tree.ArrayAccessTree;
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.ConditionalExpressionTree;
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.NewClassTree;
import com.sun.source.tree.ParameterizedTypeTree;
import com.sun.source.tree.ParenthesizedTree;
import com.sun.source.tree.PrimitiveTypeTree;
import com.sun.source.tree.StatementTree;
import com.sun.source.tree.Tree;
import com.sun.source.tree.Tree.Kind;
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;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
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.Modifier;
import javax.lang.model.element.Name;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.TypeKind;
import javax.lang.model.util.ElementFilter;

/** 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) {
        return isNamedMethodCall("super", tree);
    }

    /**
     * Checks if the method invocation is a call to this.
     *
     * @param tree a tree defining a method invocation
     * @return true iff tree describes a call to this
     */
    public static boolean isThisCall(MethodInvocationTree tree) {
        return isNamedMethodCall("this", tree);
    }

    protected static boolean isNamedMethodCall(String name, MethodInvocationTree tree) {
        /*@Nullable*/ ExpressionTree mst = tree.getMethodSelect();
        assert mst != null; /*nninvariant*/

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

        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(name);
        }

        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.
     *
     * <p>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 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 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 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 {@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 {@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 && !classTreeKinds.contains(parpath.getLeaf().getKind())) {
            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. (Does not handle
     * pseudo-assignment of an argument to a parameter or a receiver expression to a receiver.)
     *
     * <p>The assignment context for the {@code treePath} is the leaf of its parent, if the parent
     * is one of the following trees:
     *
     * <ul>
     *   <li>AssignmentTree
     *   <li>CompoundAssignmentTree
     *   <li>MethodInvocationTree
     *   <li>NewArrayTree
     *   <li>NewClassTree
     *   <li>ReturnTree
     *   <li>VariableTree
     * </ul>
     *
     * If the parent is a ConditionalExpressionTree we need to distinguish two cases: If the leaf is
     * either the then or else branch of the ConditionalExpressionTree, then recurse on the parent.
     * If the leaf is the condition of the ConditionalExpressionTree, then return null to not
     * consider this assignment context.
     *
     * <p>If the leaf is a ParenthesizedTree, then recurse on the parent.
     *
     * <p>Otherwise, null is returned.
     *
     * @return the assignment context as described
     */
    public static Tree getAssignmentContext(final TreePath treePath) {
        TreePath parentPath = treePath.getParentPath();

        if (parentPath == null) {
            return null;
        }

        Tree parent = parentPath.getLeaf();
        switch (parent.getKind()) {
            case PARENTHESIZED:
                return getAssignmentContext(parentPath);
            case CONDITIONAL_EXPRESSION:
                ConditionalExpressionTree cet = (ConditionalExpressionTree) parent;
                if (cet.getCondition() == treePath.getLeaf()) {
                    // The assignment context for the condition is simply boolean.
                    // No point in going on.
                    return null;
                }
                // Otherwise use the context of the ConditionalExpressionTree.
                return getAssignmentContext(parentPath);
            case ASSIGNMENT:
            case METHOD_INVOCATION:
            case NEW_ARRAY:
            case NEW_CLASS:
            case RETURN:
            case VARIABLE:
                return parent;
            default:
                // 11 Tree.Kinds are CompoundAssignmentTrees,
                // so use instanceof rather than listing all 11.
                if (parent instanceof CompoundAssignmentTree) {
                    return parent;
                }
                return null;
        }
    }

    /**
     * Gets the element for a class corresponding to a declaration.
     *
     * @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.
     *
     * @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.
     *
     * @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.
     *
     * <p>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.
    // Might return null if element wasn't found.
    public static final ExecutableElement elementFromUse(MethodInvocationTree node) {
        Element el = elementFromUse((ExpressionTree) node);
        if (el instanceof ExecutableElement) {
            return (ExecutableElement) el;
        } else {
            return null;
        }
    }

    // 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.
     *
     * <p>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 static final 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 static final 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?
     *
     * <p>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 ElementUtils.isMethod(invoked, method, env);
    }

    /**
     * Returns the ExecutableElement for a method declaration of methodName, in class typeName, with
     * params parameters.
     *
     * <p>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 typeElt = env.getElementUtils().getTypeElement(typeName);
        for (ExecutableElement exec : ElementFilter.methodsIn(typeElt.getEnclosedElements())) {
            if (exec.getSimpleName().contentEquals(methodName)
                    && exec.getParameters().size() == params) {
                return exec;
            }
        }
        ErrorReporter.errorAbort("TreeUtils.getMethod: shouldn't be here!");
        return null; // dead code
    }

    public static List<ExecutableElement> getMethodList(
            String typeName, String methodName, int params, ProcessingEnvironment env) {
        List<ExecutableElement> methods = new ArrayList<>();
        TypeElement typeElement = env.getElementUtils().getTypeElement(typeName);
        for (ExecutableElement exec : ElementFilter.methodsIn(typeElement.getEnclosedElements())) {
            if (exec.getSimpleName().contentEquals(methodName)
                    && exec.getParameters().size() == params) {
                methods.add(exec);
            }
        }
        return methods;
    }

    /**
     * Determine whether the given expression is either "this" or an outer "C.this".
     *
     * <p>TODO: Should this also handle "super"?
     */
    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} is a class literal, such as
     *
     * <pre>
     *   <em>Object</em> . <em>class</em>
     * </pre>
     *
     * @return true iff if tree is a class literal
     */
    public static boolean isClassLiteral(Tree tree) {
        if (tree.getKind() != Tree.Kind.MEMBER_SELECT) {
            return false;
        }
        return "class".equals(((MemberSelectTree) tree).getIdentifier().toString());
    }

    /**
     * Determine whether {@code tree} 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} accesses. Requires {@code
     * tree} to be a field access, as determined by {@code isFieldAccess}.
     *
     * @return the name of the field accessed by {@code tree}.
     */
    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} 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} accesses. Requires {@code
     * tree} to be a method access, as determined by {@code isMethodAccess}.
     *
     * @return the name of the method accessed by {@code tree}.
     */
    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.
     *     <p>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.
     *
     * <p>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;
        }
    }

    /**
     * @see Object#getClass()
     * @return true iff invocationTree is an instance of getClass()
     */
    public static boolean isGetClassInvocation(MethodInvocationTree invocationTree) {
        final Element declarationElement = elementFromUse(invocationTree);
        String ownerName =
                ElementUtils.getQualifiedClassName(declarationElement.getEnclosingElement())
                        .toString();
        return ownerName.equals("java.lang.Object")
                && declarationElement.getSimpleName().toString().equals("getClass");
    }

    /**
     * Returns whether or not the leaf of the tree path is in a static scope.
     *
     * @param path TreePath whose leaf may or may not be in static scope
     * @return returns whether or not the leaf of the tree path is in a static scope
     */
    public static boolean isTreeInStaticScope(TreePath path) {
        MethodTree enclosingMethod = TreeUtils.enclosingMethod(path);

        if (enclosingMethod != null) {
            return enclosingMethod.getModifiers().getFlags().contains(Modifier.STATIC);
        }
        // no enclosing method, check for static or initializer block
        BlockTree block = enclosingTopLevelBlock(path);
        if (block != null) {
            return block.isStatic();
        }

        // check if its in a variable initializer
        Tree t = enclosingVariable(path);
        if (t != null) {
            return ((VariableTree) t).getModifiers().getFlags().contains((Modifier.STATIC));
        }
        ClassTree classTree = enclosingClass(path);
        if (classTree != null) {
            return classTree.getModifiers().getFlags().contains((Modifier.STATIC));
        }
        return false;
    }

    /**
     * Returns whether or not tree is an access of array length.
     *
     * @param tree tree to check
     * @return true if tree is an access of array length
     */
    public static boolean isArrayLengthAccess(Tree tree) {
        if (tree.getKind() == Kind.MEMBER_SELECT
                && isFieldAccess(tree)
                && getFieldName(tree).equals("length")) {
            ExpressionTree expressionTree = ((MemberSelectTree) tree).getExpression();
            if (InternalUtils.typeOf(expressionTree).getKind() == TypeKind.ARRAY) {
                return true;
            }
        }
        return false;
    }
}
