From f1ba94989e86a956fff1505f39cd41c8b605f9d8 Mon Sep 17 00:00:00 2001 From: Oliver Drotbohm Date: Thu, 12 Dec 2024 00:07:14 +0100 Subject: [PATCH] GH-992 - Upgrade to APTK 0.29. --- spring-modulith-apt/pom.xml | 2 +- .../tools/wrapper/TypeElementWrapper.java | 395 ------------------ 2 files changed, 1 insertion(+), 396 deletions(-) delete mode 100644 spring-modulith-apt/src/main/java/io/toolisticon/aptk/tools/wrapper/TypeElementWrapper.java diff --git a/spring-modulith-apt/pom.xml b/spring-modulith-apt/pom.xml index 9eb26002..89bc4089 100644 --- a/spring-modulith-apt/pom.xml +++ b/spring-modulith-apt/pom.xml @@ -19,7 +19,7 @@ io.toolisticon.aptk aptk-tools - 0.28.0 + 0.29.0 diff --git a/spring-modulith-apt/src/main/java/io/toolisticon/aptk/tools/wrapper/TypeElementWrapper.java b/spring-modulith-apt/src/main/java/io/toolisticon/aptk/tools/wrapper/TypeElementWrapper.java deleted file mode 100644 index 6b650ba7..00000000 --- a/spring-modulith-apt/src/main/java/io/toolisticon/aptk/tools/wrapper/TypeElementWrapper.java +++ /dev/null @@ -1,395 +0,0 @@ -package io.toolisticon.aptk.tools.wrapper; - -import io.toolisticon.aptk.tools.ElementUtils; -import io.toolisticon.aptk.tools.TypeMirrorWrapper; -import io.toolisticon.aptk.tools.corematcher.AptkCoreMatchers; -import io.toolisticon.aptk.tools.fluentfilter.FluentElementFilter; - -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Optional; -import java.util.Set; -import java.util.stream.Collectors; - -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.NestingKind; -import javax.lang.model.element.TypeElement; -import javax.lang.model.element.VariableElement; -import javax.lang.model.type.TypeMirror; - -/** - * Copy of the original {@link TypeElementWrapper} of the Toolisticon APTK project located - * here. Tweaks {@link #getOuterType()} to include - * {@link ElementKind#INTERFACE} in the outer class lookup to fix the issue reported - * here.
- * Wraps a TypeElement to provide some convenience functionality - */ -public class TypeElementWrapper extends ElementWrapper { - - private final static String TYPE_ELEMENT_CLASS_NAME = "javax.lang.model.element.TypeElement"; - - /** - * Hidden constructor. - * - * @param typeElement The TypeElement to wrap - */ - private TypeElementWrapper(TypeElement typeElement) { - super(typeElement); - } - - // methods inherited from TypeElement - - /** - * Returns the NestingKind. - * - * @return the NestingKind. - */ - public NestingKind getNestingKind() { - return this.element.getNestingKind(); - } - - public boolean hasNestingKind(NestingKind nestingKind) { - return nestingKind != null && getNestingKind().equals(nestingKind); - } - - public boolean isNested() { - return getNestingKind().isNested(); - } - - /** - * Gets the nested name of the element. If the TypeElement isn't a nested type the simple name will be returned. - * - * @return the nested name of the element - */ - public String getNestedName() { - - String name = getSimpleName(); - - TypeElementWrapper current = this; - - while (current.isNested()) { - - current = current.getOuterType().get(); - name = current.getSimpleName() + "." + name; - - } - - return name; - } - - /** - * Returns the qualified name. - * - * @return the qualified name. - */ - public String getQualifiedName() { - return this.element.getQualifiedName().toString(); - } - - /** - * Check for qualified name. - * - * @param name the name to check for - * @return true if qualified name matches passed name, otherwise false - */ - public boolean hasQualifiedName(String name) { - return name != null && getQualifiedName().equals(name); - } - - /** - * Gets the binary name for the type element. - */ - public String getBinaryName() { - - // According to https://docs.oracle.com/javase/specs/jls/se8/html/jls-13.html the binary name looks like: - // -- The binary name of a top level type (§7.6) is its canonical name (§6.7). - // -- The binary name of a member type (§8.5, §9.5) consists of the binary name of its immediately enclosing type, - // followed by $, followed by the simple name of the member. - - if (this.isNested()) { - // Safe to call since its of nested kind - TypeElementWrapper enclosingTypeElement = this.getOuterType().get(); - return enclosingTypeElement.getBinaryName() + "$" + this.getSimpleName(); - } else { - return this.getQualifiedName(); - } - - } - - /** - * Gets the direct superclass - * - * @return a TypeMirrorWrapper of the direct superclass - */ - public TypeMirrorWrapper getSuperclass() { - return TypeMirrorWrapper.wrap(this.element.getSuperclass()); - } - - /** - * Returns list of TypeMirrorWrapper containing all directly implemented interfaces. Doesn't return interfaces - * implemented by superclasses. - * - * @return list of TypeMirrorWrapper containing all directly implemented interfaces - */ - public List getInterfaces() { - return this.element.getInterfaces().stream().map(TypeMirrorWrapper::wrap).collect(Collectors.toList()); - } - - /** - * Returns Set of TypeMirrorWrapper containing all implemented interfaces (including those of superclasses). - * - * @return Set of TypeMirrorWrapper containing all implemented interfaces - */ - public Set getAllInterfaces() { - - // Add own interfaces - Set result = new HashSet<>(this.getInterfaces()); - - // recursively add those of superclasses. - Optional superClass = getSuperclass().getTypeElement(); - superClass.ifPresent(typeElementWrapper -> result.addAll(typeElementWrapper.getAllInterfaces())); - - return result; - } - - /** - * Returns list of TypeParameterElementWrapper instances describing all TypeParameters. - * - * @return list of TypeParameterElementWrapper instances describing all TypeParameters, or an empty list - */ - public List getTypeParameters() { - return this.element.getTypeParameters().stream().map(TypeParameterElementWrapper::wrap) - .collect(Collectors.toList()); - } - - /** - * Checks if wrapped TypeElement has type parameters. - * - * @return true, if TypeElement has type parameters, otherwise false. - */ - public boolean hasTypeParameters() { - return getTypeParameters().size() > 0; - } - - /** - * Returns an enclosed method. Works only if all parameter types are already compiled. - * - * @param name the method name - * @param parameterTypes The parameter types - * @return the wrapped ExecutableElement instance if method is found, otherwise null - */ - public Optional getMethod(String name, Class... parameterTypes) { - List filterResult = FluentElementFilter - .createFluentElementFilter(this.element.getEnclosedElements()) - .applyFilter(AptkCoreMatchers.IS_METHOD) - .applyFilter(AptkCoreMatchers.BY_NAME).filterByOneOf(name) - .applyFilter(AptkCoreMatchers.BY_PARAMETER_TYPE).filterByOneOf(parameterTypes) - .getResult(); - return Optional.ofNullable(filterResult.size() > 0 ? ExecutableElementWrapper.wrap(filterResult.get(0)) : null); - } - - /** - * Returns list of ExecutableElementWrapper for all methods in wrapped TypeElement, filtered by modifiers. - * - * @param modifier modifiers used for filtering - * @return list of ExecutableElementWrapper for all methods in wrapped TypeElement, or empty list - */ - public List getMethods(Modifier... modifier) { - return FluentElementFilter.createFluentElementFilter( - this.element.getEnclosedElements()).applyFilter(AptkCoreMatchers.IS_METHOD) - .applyFilter(AptkCoreMatchers.BY_MODIFIER).filterByAllOf(modifier) - .getResult() - .stream().map(ExecutableElementWrapper::wrap).collect(Collectors.toList()); - } - - /** - * Returns list of VariableElementWrapper for all fields in wrapped TypeElement, filtered by modifiers. - * - * @param modifier modifiers used for filtering - * @return list of VariableElementWrapper for all fields in wrapped TypeElement, or empty list - */ - public List getFields(Modifier... modifier) { - return FluentElementFilter.createFluentElementFilter( - this.element.getEnclosedElements()).applyFilter(AptkCoreMatchers.IS_FIELD) - .applyFilter(AptkCoreMatchers.BY_MODIFIER).filterByAllOf(modifier) - .getResult() - .stream().map(VariableElementWrapper::wrap).collect(Collectors.toList()); - } - - /** - * Returns Optional of VariableElementWrapper of field with passed name in wrapped TypeElement. - * - * @param name Name of the field - * @return Optional of ExecutableElementWrapper of field with passed name in wrapped TypeElement, or empty list - */ - public Optional getFieldByName(String name) { - List fields = FluentElementFilter.createFluentElementFilter( - this.element.getEnclosedElements()).applyFilter(AptkCoreMatchers.IS_FIELD) - .applyFilter(AptkCoreMatchers.BY_NAME).filterByOneOf(name) - .getResult() - .stream().map(VariableElementWrapper::wrap).collect(Collectors.toList()); - - return Optional.ofNullable(fields.size() > 0 ? fields.get(0) : null); - } - - /** - * Returns list of VariableElementWrapper for all constructors in wrapped TypeElement, filtered by modifiers. - * - * @param modifier modifiers used for filtering - * @return list of ExecutableElementWrapper for all constructors in wrapped TypeElement, or empty list - */ - public List getConstructors(Modifier... modifier) { - return FluentElementFilter.createFluentElementFilter( - this.element.getEnclosedElements()).applyFilter(AptkCoreMatchers.IS_CONSTRUCTOR) - .applyFilter(AptkCoreMatchers.BY_MODIFIER).filterByAllOf(modifier) - .getResult() - .stream().map(ExecutableElementWrapper::wrap).collect(Collectors.toList()); - } - - /** - * Returns list of VariableElementWrapper for all inner types in wrapped TypeElement, filtered by modifiers. - * - * @param modifier modifiers used for filtering - * @return list of ExecutableElementWrapper for all inner types in wrapped TypeElement, or empty list - */ - public List getInnerTypes(Modifier... modifier) { - return FluentElementFilter.createFluentElementFilter( - this.element.getEnclosedElements()).applyFilter(AptkCoreMatchers.IS_CLASS) - .applyFilter(AptkCoreMatchers.BY_MODIFIER).filterByAllOf(modifier) - .getResult() - .stream().map(TypeElementWrapper::wrap).collect(Collectors.toList()); - } - - /** - * Returns the direct outer type for nested classes. Returned type may not be a top level type, since java allows - * nested classes in nested classes. - * - * @return an Optional containing the outer type of nested classes, if present. - */ - public Optional getOuterType() { - if (this.element.getNestingKind() != NestingKind.MEMBER) { - return Optional.empty(); - } - - return Optional.of(TypeElementWrapper.wrap(ElementUtils.AccessEnclosingElements - . getFirstEnclosingElementOfKind(this.element, ElementKind.CLASS, ElementKind.INTERFACE))); - } - - /** - * Returns the direct outer type for nested classes. - * - * @return an Optional containing the outer type of nested classes, if present. - */ - public Optional getOuterTopLevelType() { - if (this.element.getNestingKind() != NestingKind.MEMBER) { - return Optional.empty(); - } - - return Optional.of(this.getAllEnclosingElements().stream() - .filter(ElementWrapper::isTypeElement) - .map(ElementWrapper::toTypeElement) - .filter(e -> e.hasNestingKind(NestingKind.TOP_LEVEL)).collect(Collectors.toList()).get(0)); - - } - - /** - * Gets all enum constant names of enum as VariableElements. - * - * @return A list containing all enum constant names or null if wrapped TypeElement is no enum. - */ - public List getEnumValues() { - return isEnum() ? this.filterEnclosedElements() - .applyFilter(AptkCoreMatchers.BY_ELEMENT_KIND) - .filterByOneOf(ElementKind.ENUM_CONSTANT) - .getResult() - .stream().map(e -> VariableElementWrapper.wrap((VariableElement) e)) - .collect(Collectors.toList()) - : null; - } - - /** - * Returns the record components of this class or interface element in declaration order. - * - * @return the record components, or an empty list if there are none - */ - public List getRecordComponents() { - - // This method is available from Java 16 - the introduction of records, so this check is sufficient to prevent - // reflective calling of method - if (!isRecord()) { - return Collections.EMPTY_LIST; - } - List recordComponentElements = this - .> invokeParameterlessMethodOfElement(TYPE_ELEMENT_CLASS_NAME, "getRecordComponents"); - - return recordComponentElements.stream().map(RecordComponentElementWrapper::wrap).collect(Collectors.toList()); - - } - - /** - * Returns the permitted classes of this class or interface element in declaration order. - * - * @return the permitted classes, or an empty list if there are none - */ - public List getPermittedSubclasses() { - - // must make sure that method exists, otherwise return the default value - if (!hasMethod(TYPE_ELEMENT_CLASS_NAME, "getPermittedSubclasses")) { - // TODO MUST CHECK WHAT SHOULD BE RETURNED FOR NON SEALED CLASSES! - return Collections.EMPTY_LIST; - } - - List typeMirrors = this.> invokeParameterlessMethodOfElement(TYPE_ELEMENT_CLASS_NAME, - "getPermittedSubclasses"); - return typeMirrors.stream().map(TypeMirrorWrapper::wrap).collect(Collectors.toList()); - } - - /** - * Wraps a TypeElement. - * - * @param element the TypeElement to wrap - * @return a wrapper instance - */ - public static TypeElementWrapper wrap(TypeElement element) { - return new TypeElementWrapper(element); - } - - /** - * Retrieve TypeElementWrapper by fully qualified name. - * - * @param fqn the fully qualified name of the element - * @return an Optional that contains the wrapper instance, if TypeElement for fqn exists - */ - public static Optional getByFqn(String fqn) { - return getByTypeMirror(TypeMirrorWrapper.wrap(fqn)); - } - - /** - * Retrieve TypeElementWrapper by fully qualified name. - * - * @param clazz the class of the element - * @return an Optional that contains the wrapper instance, if TypeElement for class exists (only for DeclaredTypes) - */ - public static Optional getByClass(Class clazz) { - return getByTypeMirror(TypeMirrorWrapper.wrap(clazz)); - } - - /** - * Retrieve TypeElementWrapper by fully qualified name. - * - * @param typeMirror the TypeMirror of the element - * @return an Optional that contains the wrapper instance, if TypeElement for TypeMirror exists (only for - * DeclaredTypes) - */ - public static Optional getByTypeMirror(TypeMirror typeMirror) { - return getByTypeMirror(TypeMirrorWrapper.wrap(typeMirror)); - } - - public static Optional getByTypeMirror(TypeMirrorWrapper typeMirror) { - return typeMirror.getTypeElement(); - } -}