package org.checkerframework.javacutil;

import com.sun.tools.javac.code.Flags;
import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Symbol.MethodSymbol;
import com.sun.tools.javac.code.Type;
import com.sun.tools.javac.model.JavacTypes;
import com.sun.tools.javac.processing.JavacProcessingEnvironment;
import com.sun.tools.javac.util.Context;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Deque;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.StringJoiner;
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.AnnotationMirror;
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.PackageElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.ElementFilter;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
import javax.tools.JavaFileObject;
import javax.tools.JavaFileObject.Kind;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.checker.signature.qual.BinaryName;
import org.checkerframework.checker.signature.qual.CanonicalName;
import org.plumelib.util.CollectionsPlume;

/**
 * Utility methods for analyzing {@code Element}s. This complements {@link Elements}, providing
 * functionality that it does not.
 */
public class ElementUtils {

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

  /**
   * Returns the innermost type element enclosing the given element. Returns the element itself if
   * it is a type element.
   *
   * @param elem the enclosed element of a class
   * @return the innermost type element, or null if no type element encloses {@code elem}
   * @deprecated use {@link #enclosingTypeElement}
   */
  @Deprecated // use enclosingTypeElement
  public static @Nullable TypeElement enclosingClass(final Element elem) {
    return enclosingTypeElement(elem);
  }

  /**
   * Returns the innermost type element that is, or encloses, the given element.
   *
   * <p>Note that in this code:
   *
   * <pre>{@code
   * class Outer {
   *   static class Inner {  }
   * }
   * }</pre>
   *
   * {@code Inner} has no enclosing type, but this method returns {@code Outer}.
   *
   * @param elem the enclosed element of a class
   * @return the innermost type element (possibly the argument itself), or null if {@code elem} is
   *     not, and is not enclosed by, a type element
   */
  public static @Nullable TypeElement enclosingTypeElement(final Element elem) {
    Element result = elem;
    while (result != null && !isTypeElement(result)) {
      result = result.getEnclosingElement();
    }
    return (TypeElement) result;
  }

  /**
   * Returns the innermost type element enclosing the given element, that is different from the
   * element itself. By contrast, {@link #enclosingTypeElement} returns its argument if the argument
   * is a type element.
   *
   * @param elem the enclosed element of a class
   * @return the innermost type element, or null if no type element encloses {@code elem}
   */
  public static @Nullable TypeElement strictEnclosingTypeElement(final Element elem) {
    Element enclosingElement = elem.getEnclosingElement();
    if (enclosingElement == null) {
      return null;
    }

    return enclosingTypeElement(enclosingElement);
  }

  /**
   * Returns the top-level type element that contains {@code element}.
   *
   * @param element the element whose enclosing tye element to find
   * @return a type element containing {@code element} that isn't contained in another class
   */
  public static TypeElement toplevelEnclosingTypeElement(Element element) {
    TypeElement result = enclosingTypeElement(element);
    if (result == null) {
      return (TypeElement) element;
    }

    TypeElement enclosing = strictEnclosingTypeElement(result);
    while (enclosing != null) {
      result = enclosing;
      enclosing = strictEnclosingTypeElement(enclosing);
    }

    return result;
  }

  /**
   * Returns the binary name of the class enclosing {@code executableElement}.
   *
   * @param executableElement the ExecutableElement
   * @return the binary name of the class enclosing {@code executableElement}
   */
  public static @BinaryName String getEnclosingClassName(ExecutableElement executableElement) {
    return getBinaryName(((MethodSymbol) executableElement).enclClass());
  }

  /**
   * Returns the binary name of the class enclosing {@code variableElement}.
   *
   * @param variableElement the VariableElement
   * @return the binary name of the class enclosing {@code variableElement}
   */
  public static @BinaryName String getEnclosingClassName(VariableElement variableElement) {
    TypeElement enclosingType = enclosingTypeElement(variableElement);
    if (enclosingType == null) {
      throw new BugInCF("enclosingTypeElement(%s) is null", variableElement);
    }
    return getBinaryName(enclosingType);
  }

  /**
   * Returns the innermost package element enclosing the given element. The same effect as {@link
   * javax.lang.model.util.Elements#getPackageOf(Element)}. Returns the element itself if it is a
   * package.
   *
   * @param elem the enclosed element of a package
   * @return the innermost package element
   */
  public static PackageElement enclosingPackage(final Element elem) {
    Element result = elem;
    while (result != null && result.getKind() != ElementKind.PACKAGE) {
      @Nullable Element encl = result.getEnclosingElement();
      result = encl;
    }
    return (PackageElement) result;
  }

  /**
   * Returns the "parent" package element for the given package element. For package "A.B" it gives
   * "A". For package "A" it gives the default package. For the default package it returns null.
   *
   * <p>Note that packages are not enclosed within each other, we have to manually climb the
   * namespaces. Calling "enclosingPackage" on a package element returns the package element itself
   * again.
   *
   * @param elem the package to start from
   * @return the parent package element or {@code null}
   */
  public static @Nullable PackageElement parentPackage(
      final PackageElement elem, final Elements e) {
    // The following might do the same thing:
    //   ((Symbol) elt).owner;
    // TODO: verify and see whether the change is worth it.
    String fqnstart = elem.getQualifiedName().toString();
    String fqn = fqnstart;
    if (fqn != null && !fqn.isEmpty()) {
      int dotPos = fqn.lastIndexOf('.');
      if (dotPos != -1) {
        return e.getPackageElement(fqn.substring(0, dotPos));
      }
    }
    return null;
  }

  /**
   * Returns true if the element is a static element: whether it is a static field, static method,
   * or static class.
   *
   * @return true if element is static
   */
  public static boolean isStatic(Element element) {
    return element.getModifiers().contains(Modifier.STATIC);
  }

  /**
   * Returns true if the element is a final element: a final field, final method, or final class.
   *
   * @return true if the element is final
   */
  public static boolean isFinal(Element element) {
    return element.getModifiers().contains(Modifier.FINAL);
  }

  /**
   * Returns true if the element is a effectively final element.
   *
   * @return true if the element is effectively final
   */
  public static boolean isEffectivelyFinal(Element element) {
    Symbol sym = (Symbol) element;
    if (sym.getEnclosingElement().getKind() == ElementKind.METHOD
        && (sym.getEnclosingElement().flags() & Flags.ABSTRACT) != 0) {
      return true;
    }
    return (sym.flags() & (Flags.FINAL | Flags.EFFECTIVELY_FINAL)) != 0;
  }

  /**
   * Returns the {@code TypeMirror} for usage of Element as a value. It returns the return type of a
   * method element, the class type of a constructor, or simply the type mirror of the element
   * itself.
   *
   * @param element the element whose type to obtain
   * @return the type for the element used as a value
   */
  @SuppressWarnings("nullness:dereference.of.nullable") // a constructor has an enclosing class
  public static TypeMirror getType(Element element) {
    if (element.getKind() == ElementKind.METHOD) {
      return ((ExecutableElement) element).getReturnType();
    } else if (element.getKind() == ElementKind.CONSTRUCTOR) {
      return enclosingClass(element).asType();
    } else {
      return element.asType();
    }
  }

  /**
   * Returns the qualified name of the innermost class enclosing the provided {@code Element}.
   *
   * @param element an element enclosed by a class, or a {@code TypeElement}
   * @return the qualified {@code Name} of the innermost class enclosing the element
   */
  public static @Nullable Name getQualifiedClassName(Element element) {
    if (element.getKind() == ElementKind.PACKAGE) {
      PackageElement elem = (PackageElement) element;
      return elem.getQualifiedName();
    }

    TypeElement elem = enclosingClass(element);
    if (elem == null) {
      return null;
    }

    return elem.getQualifiedName();
  }

  /**
   * Returns a verbose name that identifies the element.
   *
   * @param elt the element whose name to obtain
   * @return the qualified name of the given element
   */
  public static String getQualifiedName(Element elt) {
    if (elt.getKind() == ElementKind.PACKAGE || isTypeElement(elt)) {
      Name n = getQualifiedClassName(elt);
      if (n == null) {
        return "Unexpected element: " + elt;
      }
      return n.toString();
    } else {
      return getQualifiedName(elt.getEnclosingElement()) + "." + elt;
    }
  }

  /**
   * Returns the binary name of the given type.
   *
   * @param te a type
   * @return the binary name of the type
   */
  @SuppressWarnings("signature:return") // string manipulation
  public static @BinaryName String getBinaryName(TypeElement te) {
    Element enclosing = te.getEnclosingElement();
    String simpleName = te.getSimpleName().toString();
    if (enclosing == null) { // is this possible?
      return simpleName;
    }
    if (ElementUtils.isTypeElement(enclosing)) {
      return getBinaryName((TypeElement) enclosing) + "$" + simpleName;
    } else if (enclosing.getKind() == ElementKind.PACKAGE) {
      PackageElement pe = (PackageElement) enclosing;
      if (pe.isUnnamed()) {
        return simpleName;
      } else {
        return pe.getQualifiedName() + "." + simpleName;
      }
    } else {
      // This case occurs for anonymous inner classes. Fall back to the flatname method.
      return ((ClassSymbol) te).flatName().toString();
    }
  }

  /**
   * Returns the canonical representation of the method declaration, which contains simple names of
   * the types only.
   *
   * @param element a method declaration
   * @return the simple name of the method, followed by the simple names of the formal parameter
   *     types
   */
  public static String getSimpleSignature(ExecutableElement element) {
    // note: constructor simple name is <init>
    StringJoiner sj = new StringJoiner(",", element.getSimpleName() + "(", ")");
    for (Iterator<? extends VariableElement> i = element.getParameters().iterator();
        i.hasNext(); ) {
      sj.add(TypesUtils.simpleTypeName(i.next().asType()));
    }
    return sj.toString();
  }

  /**
   * Returns a user-friendly name for the given method. Does not return {@code "<init>"} or {@code
   * "<clinit>"} as ExecutableElement.getSimpleName() does.
   *
   * @param element a method declaration
   * @return a user-friendly name for the method
   */
  public static CharSequence getSimpleNameOrDescription(ExecutableElement element) {
    Name result = element.getSimpleName();
    switch (result.toString()) {
      case "<init>":
        return element.getEnclosingElement().getSimpleName();
      case "<clinit>":
        return "class initializer";
      default:
        return result;
    }
  }

  /**
   * Check if the element is an element for 'java.lang.Object'
   *
   * @param element the type element
   * @return true iff the element is java.lang.Object element
   */
  public static boolean isObject(TypeElement element) {
    return element.getQualifiedName().contentEquals("java.lang.Object");
  }

  /**
   * Check if the element is an element for 'java.lang.String'
   *
   * @param element the type element
   * @return true iff the element is java.lang.String element
   */
  public static boolean isString(TypeElement element) {
    return element.getQualifiedName().contentEquals("java.lang.String");
  }

  /**
   * Returns true if the element is a reference to a compile-time constant.
   *
   * @param elt an element
   * @return true if the element is a reference to a compile-time constant
   */
  public static boolean isCompileTimeConstant(Element elt) {
    return elt != null
        && (elt.getKind() == ElementKind.FIELD || elt.getKind() == ElementKind.LOCAL_VARIABLE)
        && ((VariableElement) elt).getConstantValue() != null;
  }

  /**
   * Checks whether a given element came from a source file.
   *
   * <p>By contrast, {@link ElementUtils#isElementFromByteCode(Element)} returns true if there is a
   * classfile for the given element, even if there is also a source file.
   *
   * @param element the element to check, or null
   * @return true if a source file containing the element is being compiled
   */
  public static boolean isElementFromSourceCode(@Nullable Element element) {
    if (element == null) {
      return false;
    }
    TypeElement enclosingClass = enclosingClass(element);
    if (enclosingClass == null) {
      throw new BugInCF("enclosingClass(%s) is null", element);
    }
    return isElementFromSourceCodeImpl((Symbol.ClassSymbol) enclosingClass);
  }

  /**
   * Checks whether a given ClassSymbol came from a source file.
   *
   * <p>By contrast, {@link ElementUtils#isElementFromByteCode(Element)} returns true if there is a
   * classfile for the given element, even if there is also a source file.
   *
   * @param symbol the class to check
   * @return true if a source file containing the class is being compiled
   */
  private static boolean isElementFromSourceCodeImpl(Symbol.ClassSymbol symbol) {
    // This is a bit of a hack to avoid treating JDK as source files. JDK files' toUri() method
    // returns just the name of the file (e.g. "Object.java"), but any file actually being
    // compiled returns a file URI to the source file.
    return symbol.sourcefile != null
        && symbol.sourcefile.getKind() == JavaFileObject.Kind.SOURCE
        && symbol.sourcefile.toUri().toString().startsWith("file:");
  }

  /**
   * Returns true if the element is declared in ByteCode. Always return false if elt is a package.
   *
   * @param elt some element
   * @return true if the element is declared in ByteCode
   */
  public static boolean isElementFromByteCode(@Nullable Element elt) {
    if (elt == null) {
      return false;
    }

    if (elt instanceof Symbol.ClassSymbol) {
      Symbol.ClassSymbol clss = (Symbol.ClassSymbol) elt;
      if (null != clss.classfile) {
        // The class file could be a .java file
        return clss.classfile.getKind() == Kind.CLASS;
      } else {
        return elt.asType().getKind().isPrimitive();
      }
    }
    return isElementFromByteCode(elt.getEnclosingElement());
  }

  /**
   * Returns the path to the source file containing {@code element}, which must be from source code.
   *
   * @param element the type element to look at
   * @return path to the source file containing {@code element}
   */
  public static String getSourceFilePath(TypeElement element) {
    return ((ClassSymbol) element).sourcefile.toUri().getPath();
  }

  /**
   * Returns the field of the class or {@code null} if not found.
   *
   * @param type TypeElement to search
   * @param name name of a field
   * @return The VariableElement for the field if it was found, null otherwise
   */
  public static @Nullable VariableElement findFieldInType(TypeElement type, String name) {
    for (VariableElement field : ElementFilter.fieldsIn(type.getEnclosedElements())) {
      if (field.getSimpleName().contentEquals(name)) {
        return field;
      }
    }
    return null;
  }

  /**
   * Returns the elements of the fields whose simple names are {@code names} and are declared in
   * {@code type}.
   *
   * <p>If a field isn't declared in {@code type}, its element isn't included in the returned set.
   * If none of the fields is declared in {@code type}, the empty set is returned.
   *
   * @param type where to look for fields
   * @param names simple names of fields that might be declared in {@code type}
   * @return the elements of the fields whose simple names are {@code names} and are declared in
   *     {@code type}
   */
  public static Set<VariableElement> findFieldsInType(TypeElement type, Collection<String> names) {
    Set<VariableElement> results = new HashSet<>();
    for (VariableElement field : ElementFilter.fieldsIn(type.getEnclosedElements())) {
      if (names.contains(field.getSimpleName().toString())) {
        results.add(field);
      }
    }
    return results;
  }

  /**
   * Returns non-private field elements, and side-effects {@code names} to remove them. For every
   * field name in {@code names} that is declared in {@code type} or a supertype, add its element to
   * the returned set and remove it from {@code names}.
   *
   * <p>When this routine returns, the combination of the return value and {@code names} has the
   * same cardinality, and represents the same fields, as {@code names} did when the method was
   * called.
   *
   * @param type where to look for fields
   * @param names simple names of fields that might be declared in {@code type} or a supertype
   *     (Names that are found are removed from this list.)
   * @return the {@code VariableElement}s for non-private fields that are declared in {@code type}
   *     whose simple names were in {@code names} when the method was called.
   */
  public static Set<VariableElement> findFieldsInTypeOrSuperType(
      TypeMirror type, Collection<String> names) {
    int origCardinality = names.size();
    Set<VariableElement> elements = new HashSet<>();
    findFieldsInTypeOrSuperType(type, names, elements);
    // Since names may contain duplicates, I don't trust the claim in the documentation about
    // cardinality.  (Does any code depend on the invariant, though?)
    if (origCardinality != names.size() + elements.size()) {
      throw new BugInCF("Bad sizes: %d != %d + %d", origCardinality, names.size(), elements.size());
    }
    return elements;
  }

  /**
   * Side-effects both {@code foundFields} (which starts empty) and {@code notFound}, conceptually
   * moving elements from {@code notFound} to {@code foundFields}.
   */
  private static void findFieldsInTypeOrSuperType(
      TypeMirror type, Collection<String> notFound, Set<VariableElement> foundFields) {
    if (TypesUtils.isObject(type)) {
      return;
    }
    TypeElement elt = TypesUtils.getTypeElement(type);
    assert elt != null : "@AssumeAssertion(nullness): assumption";
    Set<VariableElement> fieldElts = findFieldsInType(elt, notFound);
    for (VariableElement field : new HashSet<VariableElement>(fieldElts)) {
      if (!field.getModifiers().contains(Modifier.PRIVATE)) {
        notFound.remove(field.getSimpleName().toString());
      } else {
        fieldElts.remove(field);
      }
    }
    foundFields.addAll(fieldElts);

    if (!notFound.isEmpty()) {
      findFieldsInTypeOrSuperType(elt.getSuperclass(), notFound, foundFields);
    }
  }

  /**
   * Returns true if {@code element} is "com.sun.tools.javac.comp.Resolve$SymbolNotFoundError".
   *
   * @param element the element to test
   * @return true if {@code element} is "com.sun.tools.javac.comp.Resolve$SymbolNotFoundError"
   */
  public static boolean isError(Element element) {
    return element.getClass().getName()
        == "com.sun.tools.javac.comp.Resolve$SymbolNotFoundError"; // interned
  }

  /**
   * Does the given element need a receiver for accesses? For example, an access to a local variable
   * does not require a receiver.
   *
   * @param element the element to test
   * @return whether the element requires a receiver for accesses
   */
  public static boolean hasReceiver(Element element) {
    if (element.getKind() == ElementKind.CONSTRUCTOR) {
      // The enclosing element of a constructor is the class it creates.
      // A constructor can only have a receiver if the class it creates has an outer type.
      TypeMirror t = element.getEnclosingElement().asType();
      return TypesUtils.hasEnclosingType(t);
    } else if (element.getKind() == ElementKind.FIELD) {
      if (ElementUtils.isStatic(element)
          // Artificial fields in interfaces are not marked as static, so check that
          // the field is not declared in an interface.
          || element.getEnclosingElement().getKind().isInterface()) {
        return false;
      } else {
        // In constructors, the element for "this" is a non-static field, but that field
        // does not have a receiver.
        return !element.getSimpleName().contentEquals("this");
      }
    }
    return element.getKind() == ElementKind.METHOD && !ElementUtils.isStatic(element);
  }

  /**
   * Returns a type's superclass, or null if it does not have a superclass (it is object or an
   * interface, or the superclass is not on the classpath).
   *
   * @param typeElt a type element
   * @return the superclass of {@code typeElt}
   */
  public static @Nullable TypeElement getSuperClass(TypeElement typeElt) {
    TypeMirror superTypeMirror;
    try {
      superTypeMirror = typeElt.getSuperclass();
    } catch (com.sun.tools.javac.code.Symbol.CompletionFailure cf) {
      // Looking up a supertype failed. This sometimes happens
      // when transitive dependencies are not on the classpath.
      // As javac didn't complain, let's also not complain.
      return null;
    }

    if (superTypeMirror == null || superTypeMirror.getKind() == TypeKind.NONE) {
      return null;
    } else {
      return (TypeElement) ((DeclaredType) superTypeMirror).asElement();
    }
  }

  /**
   * Determine all type elements for the supertypes of the given type element. This is the
   * transitive closure of the extends and implements clauses.
   *
   * <p>TODO: can we learn from the implementation of
   * com.sun.tools.javac.model.JavacElements.getAllMembers(TypeElement)?
   *
   * @param type the type whose supertypes to return
   * @param elements the Element utilities
   * @return supertypes of {@code type}
   */
  public static List<TypeElement> getSuperTypes(TypeElement type, Elements elements) {

    if (type == null) {
      return Collections.emptyList();
    }

    List<TypeElement> superelems = new ArrayList<>();

    // Set up a stack containing type, which is our starting point.
    Deque<TypeElement> stack = new ArrayDeque<>();
    stack.push(type);

    while (!stack.isEmpty()) {
      TypeElement current = stack.pop();

      // For each direct supertype of the current type element, if it
      // hasn't already been visited, push it onto the stack and
      // add it to our superelems set.
      TypeElement supercls = ElementUtils.getSuperClass(current);
      if (supercls != null) {
        if (!superelems.contains(supercls)) {
          stack.push(supercls);
          superelems.add(supercls);
        }
      }

      for (TypeMirror supertypeitf : current.getInterfaces()) {
        TypeElement superitf = (TypeElement) ((DeclaredType) supertypeitf).asElement();
        if (!superelems.contains(superitf)) {
          stack.push(superitf);
          superelems.add(superitf);
        }
      }
    }

    // Include java.lang.Object as implicit superclass for all classes and interfaces.
    TypeElement jlobject = elements.getTypeElement("java.lang.Object");
    if (!superelems.contains(jlobject)) {
      superelems.add(jlobject);
    }

    return Collections.unmodifiableList(superelems);
  }

  /**
   * Return all fields declared in the given type or any superclass/interface.
   *
   * <p>TODO: should this use javax.lang.model.util.Elements.getAllMembers(TypeElement) instead of
   * our own getSuperTypes?
   *
   * @param type the type whose fields to return
   * @param elements the Element utilities
   * @return fields of {@code type}
   */
  public static List<VariableElement> getAllFieldsIn(TypeElement type, Elements elements) {
    List<VariableElement> fields =
        new ArrayList<>(ElementFilter.fieldsIn(type.getEnclosedElements()));
    List<TypeElement> alltypes = getSuperTypes(type, elements);
    for (TypeElement atype : alltypes) {
      fields.addAll(ElementFilter.fieldsIn(atype.getEnclosedElements()));
    }
    return Collections.unmodifiableList(fields);
  }

  /**
   * Return all methods declared in the given type or any superclass/interface. Note that no
   * constructors will be returned.
   *
   * <p>TODO: should this use javax.lang.model.util.Elements.getAllMembers(TypeElement) instead of
   * our own getSuperTypes?
   *
   * @param type the type whose methods to return
   * @param elements the Element utilities
   * @return methods of {@code type}
   */
  public static List<ExecutableElement> getAllMethodsIn(TypeElement type, Elements elements) {
    List<ExecutableElement> meths =
        new ArrayList<>(ElementFilter.methodsIn(type.getEnclosedElements()));

    List<TypeElement> alltypes = getSuperTypes(type, elements);
    for (TypeElement atype : alltypes) {
      meths.addAll(ElementFilter.methodsIn(atype.getEnclosedElements()));
    }
    return Collections.unmodifiableList(meths);
  }

  /**
   * Return all nested/inner classes/interfaces declared in the given type.
   *
   * @param type a type
   * @return all nested/inner classes/interfaces declared in {@code type}
   */
  public static List<TypeElement> getAllTypeElementsIn(TypeElement type) {
    return ElementFilter.typesIn(type.getEnclosedElements());
  }

  /** The set of kinds that represent types. */
  private static final Set<ElementKind> typeElementKinds;

  static {
    typeElementKinds = EnumSet.noneOf(ElementKind.class);
    for (ElementKind kind : ElementKind.values()) {
      if (kind.isClass() || kind.isInterface()) {
        typeElementKinds.add(kind);
      }
    }
  }

  /**
   * Return the set of kinds that represent classes.
   *
   * @return the set of kinds that represent classes
   * @deprecated use {@link #typeElementKinds()}
   */
  @Deprecated // use typeElementKinds
  public static Set<ElementKind> classElementKinds() {
    return typeElementKinds();
  }

  /**
   * Return the set of kinds that represent classes.
   *
   * @return the set of kinds that represent classes
   */
  public static Set<ElementKind> typeElementKinds() {
    return typeElementKinds;
  }

  /**
   * Is the given element kind a type, i.e., a class, enum, interface, or annotation type.
   *
   * @param element the element to test
   * @return true, iff the given kind is a class kind
   * @deprecated use {@link #isTypeElement}
   */
  @Deprecated // use isTypeElement
  public static boolean isClassElement(Element element) {
    return isTypeElement(element);
  }

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

  /**
   * Return true if the element is a type declaration.
   *
   * @param elt the element to test
   * @return true if the argument is a type declaration
   */
  public static boolean isTypeDeclaration(Element elt) {
    return isClassElement(elt) || elt.getKind() == ElementKind.TYPE_PARAMETER;
  }

  /**
   * Return true if the element is a binding variable.
   *
   * <p>Note: This is to conditionally support Java 15 instanceof pattern matching. When available,
   * this should use {@code ElementKind.BINDING_VARIABLE} directly.
   *
   * @param element the element to test
   * @return true if the element is a binding variable
   */
  public static boolean isBindingVariable(Element element) {
    return "BINDING_VARIABLE".equals(element.getKind().name());
  }

  /**
   * Check that a method Element matches a signature.
   *
   * <p>Note: Matching the receiver type must be done elsewhere as the Element receiver type is only
   * populated when annotated.
   *
   * @param method the method Element to be tested
   * @param methodName the goal method name
   * @param parameters the goal formal parameter Classes
   * @return true if the method matches the methodName and parameters
   */
  public static boolean matchesElement(
      ExecutableElement method, String methodName, Class<?>... parameters) {

    if (!method.getSimpleName().contentEquals(methodName)) {
      return false;
    }

    if (method.getParameters().size() != parameters.length) {
      return false;
    } else {
      for (int i = 0; i < method.getParameters().size(); i++) {
        if (!method.getParameters().get(i).asType().toString().equals(parameters[i].getName())) {

          return false;
        }
      }
    }

    return true;
  }

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

  /**
   * Given an annotation name, return true if the element has the annotation of that name.
   *
   * @param element the element
   * @param annotName name of the annotation
   * @return true if the element has the annotation of that name
   */
  public static boolean hasAnnotation(Element element, String annotName) {
    for (AnnotationMirror anm : element.getAnnotationMirrors()) {
      if (AnnotationUtils.areSameByName(anm, annotName)) {
        return true;
      }
    }
    return false;
  }

  /**
   * Returns the TypeElement for the given class.
   *
   * @param processingEnv the processing environment
   * @param clazz a class
   * @return the TypeElement for the class
   */
  public static TypeElement getTypeElement(ProcessingEnvironment processingEnv, Class<?> clazz) {
    @CanonicalName String className = clazz.getCanonicalName();
    if (className == null) {
      throw new Error("Anonymous class " + clazz + " has no canonical name");
    }
    return processingEnv.getElementUtils().getTypeElement(className);
  }

  /**
   * Get all the supertypes of a given type, including the type itself. The result includes both
   * superclasses and implemented interfaces.
   *
   * @param type a type
   * @param env the processing environment
   * @return list including the type and all its supertypes, with a guarantee that direct supertypes
   *     (i.e. those that appear in extends or implements clauses) appear before indirect supertypes
   */
  public static List<TypeElement> getAllSupertypes(TypeElement type, ProcessingEnvironment env) {
    Context ctx = ((JavacProcessingEnvironment) env).getContext();
    com.sun.tools.javac.code.Types javacTypes = com.sun.tools.javac.code.Types.instance(ctx);
    return CollectionsPlume.<Type, TypeElement>mapList(
        t -> (TypeElement) t.tsym, javacTypes.closure(((Symbol) type).type));
  }

  /**
   * Returns the methods that are overriden or implemented by a given method.
   *
   * @param m a method
   * @param types the type utilities
   * @return the methods that {@code m} overrides or implements
   */
  public static Set<? extends ExecutableElement> getOverriddenMethods(
      ExecutableElement m, Types types) {
    JavacTypes t = (JavacTypes) types;
    return t.getOverriddenMethods(m);
  }

  /**
   * Returns true if the two elements are in the same class. The two elements should be class
   * members, such as methods or fields.
   *
   * @param e1 an element
   * @param e2 an element
   * @return true if the two elements are in the same class
   */
  public static boolean inSameClass(Element e1, Element e2) {
    return e1.getEnclosingElement().equals(e2.getEnclosingElement());
  }
}
