All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.toolisticon.aptk.tools.wrapper.ExecutableElementWrapper Maven / Gradle / Ivy

package io.toolisticon.aptk.tools.wrapper;

import io.toolisticon.aptk.tools.TypeMirrorWrapper;

import javax.lang.model.element.ExecutableElement;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * Wraps an ExecutableElement to provide some convenience functionality
 */
public class ExecutableElementWrapper extends ElementWrapper {


    /**
     * Hidden constructor.
     *
     * @param executableElement the ExecutableElement to wrap
     */
    protected ExecutableElementWrapper(ExecutableElement executableElement) {
        super(executableElement);
    }


    /**
     * Gets the method signature String for an ExecutableElement.
     * 

* This is useful for implementing of interfaces in generated classes. *

* This method works perfectly well for ExecutableElements of classes and interfaces in compilation, * but will have some limitations for precompiled classes. *

* Keep in mind that javac doesn't store parameter names in bytecode out of the box. * So passing in an ExecutableElement of a precompiled class will have arg0,arg1,.. as parameter names. * This can be changed if class is compiled with "-parameters" compiler option. *

* Annotations won't be part of the method signature. * * @return the method signature */ public String getMethodSignature() { StringBuilder builder = new StringBuilder(); // Add throws if present if (!this.getTypeParameters().isEmpty()) { builder.append("<"); builder.append( this.getTypeParameters().stream().map( tp -> tp.getSimpleName() + " extends " + tp.getBounds().stream().map(tm -> tm.getTypeDeclaration()).collect(Collectors.joining(" & ")) ).collect(Collectors.joining(", ")) ); builder.append("> "); } // return type and method name builder.append(this.getReturnType().getTypeDeclaration()).append(" ").append(this.getSimpleName()); // add parameters builder.append("("); if (this.isVarArgs()) { if (this.getParameters().size() > 1) { List nonVarargParameters = this.getParameters().subList(0, this.getParameters().size() - 1); builder.append(nonVarargParameters.stream().map(element -> element.asType().getTypeDeclaration() + " " + element.getSimpleName()).collect(Collectors.joining(", "))); builder.append(", "); } VariableElementWrapper lastVariableElement = this.getParameters().get(this.getParameters().size() - 1); builder.append( lastVariableElement.asType().getWrappedComponentType().getTypeDeclaration()) .append("... ") .append(lastVariableElement.getSimpleName() ); } else { builder.append(element.getParameters().stream().map(element -> TypeMirrorWrapper.wrap(element.asType()).getTypeDeclaration() + " " + element.getSimpleName()).collect(Collectors.joining(", "))); } builder.append(")"); // Add throws if present if (!this.getThrownTypes().isEmpty()) { builder.append(" throws "); builder.append(this.getThrownTypes().stream().map(TypeMirrorWrapper::getSimpleName).collect(Collectors.joining(", "))); } return builder.toString(); } /** * Gets imports needed by method signature. * Doesn't include annotation types. * * @return a set containing all imports needed by the method signature */ public Set getImports() { Set imports = new HashSet<>(); // Type Parameters imports.addAll( this.getTypeParameters().stream() .flatMap(tp -> tp.getBounds().stream()) .flatMap(tm -> tm.getImports().stream()) .collect(Collectors.toList())); // Return value imports.addAll(this.getReturnType().getImports()); // parameters for (VariableElementWrapper typeParameterElement : this.getParameters()) { imports.addAll(typeParameterElement.asType().getImports()); } // thrown exception types for (TypeMirrorWrapper thrownTypes : this.getThrownTypes()) { imports.addAll(thrownTypes.getImports()); } return imports; } /** * Returns all Type Parameters of the wrapped Executable Element. * * @return a list containing all wrapped TypeParameters, or an empty list if none are present. */ public List getTypeParameters() { return this.element.getTypeParameters().stream().map(TypeParameterElementWrapper::wrap).collect(Collectors.toList()); } /** * Returns the return type of the Executable Element. * Wraps a NoType with kind VOID if this executable is not a method, or is a method that does not return a value. * * @return a TypeMirrorWrapper instance */ public TypeMirrorWrapper getReturnType() { return TypeMirrorWrapper.wrap(this.element.getReturnType()); } /** * Returns all Parameters as a List. * * @return a List of parameters, or empty list */ public List getParameters() { return this.element.getParameters().stream().map(VariableElementWrapper::wrap).collect(Collectors.toList()); } /** * Returns the receiver type of this executable, or NoType with kind NONE if the executable has no receiver type. An executable which is an instance method, or a constructor of an inner class, has a receiver type derived from the declaring type. An executable which is a static method, or a constructor of a non-inner class, or an initializer (static or instance), has no receiver type. * * @return the receiver type of this executable */ public TypeMirrorWrapper getReceiverType() { return TypeMirrorWrapper.wrap(this.element.getReceiverType()); } /** * Returns if wrapped ExecutableElement has a vararg parameter. * * @return true if wrapped ExecutableElement has a vararg parameter, otherwise false. */ public boolean isVarArgs() { return this.element.isVarArgs(); } /** * Returns if wrapped ExecutableElement is a default implementation. * * @return true if wrapped ExecutableElement is a default implementation, otherwise false */ public boolean isDefault() { return this.element.isDefault(); } /** * Returns the exceptions and other throwables listed in this method or constructor's throws clause in declaration order. * * @return the exceptions and other throwables listed in the throws clause, or an empty list if there are none */ public List getThrownTypes() { return this.element.getThrownTypes().stream().map(TypeMirrorWrapper::wrap).collect(Collectors.toList()); } /** * Returns an Optional containing the default value if this executable is an annotation type element and if a default value is present. * * @return the Optional containing the default value if present */ public Optional getDefaultValue() { return this.element.getDefaultValue() != null ? Optional.of(AnnotationValueWrapper.wrap(element.getDefaultValue())) : Optional.empty(); } /** * Wraps an ExecutableElement. * Throws IllegalArgumentException if passed executableElement is null * * @param executableElement the element to wrap, must not be null * @return the wrapper instance */ public static ExecutableElementWrapper wrap(ExecutableElement executableElement) { return new ExecutableElementWrapper(executableElement); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy