-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[#148] Add proper support for records introduced with Java 16
- Loading branch information
1 parent
6425ee9
commit f7e45bc
Showing
15 changed files
with
477 additions
and
41 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<artifactId>aptk-tools-java16</artifactId> | ||
<packaging>jar</packaging> | ||
|
||
<parent> | ||
<groupId>io.toolisticon.aptk</groupId> | ||
<artifactId>extension-parent</artifactId> | ||
<version>0.24.1-148_records-SNAPSHOT</version> | ||
</parent> | ||
|
||
<name>aptk-tools-java16</name> | ||
|
||
|
||
<dependencies> | ||
|
||
<!-- Should transitively bind all extensions for lesser java versions --> | ||
<dependency> | ||
<groupId>io.toolisticon.aptk</groupId> | ||
<artifactId>aptk-tools-java9</artifactId> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>io.toolisticon.aptk</groupId> | ||
<artifactId>aptk-tools</artifactId> | ||
</dependency> | ||
|
||
</dependencies> | ||
|
||
|
||
<build> | ||
|
||
<plugins> | ||
|
||
<plugin> | ||
<artifactId>maven-enforcer-plugin</artifactId> | ||
<executions> | ||
<execution> | ||
<id>enforce</id> | ||
<goals> | ||
<goal>enforce</goal> | ||
</goals> | ||
<configuration> | ||
<rules> | ||
<requireMavenVersion> | ||
<version>[3.0.4,)</version> | ||
</requireMavenVersion> | ||
<requireJavaVersion> | ||
<version>9</version> | ||
</requireJavaVersion> | ||
<bannedDependencies> | ||
<searchTransitive>false</searchTransitive> | ||
<excludes> | ||
<exclude>*</exclude> | ||
</excludes> | ||
<includes> | ||
<include>io.toolisticon.aptk:aptk-tools:*</include> | ||
<include>io.toolisticon.aptk:aptk-tools-java9:*</include> | ||
<include>*:*:*:*:test:*</include> | ||
<include>*:*:*:*:provided:*</include> | ||
</includes> | ||
</bannedDependencies> | ||
</rules> | ||
</configuration> | ||
</execution> | ||
</executions> | ||
</plugin> | ||
|
||
<plugin> | ||
<artifactId>maven-compiler-plugin</artifactId> | ||
<configuration> | ||
<source>16</source> | ||
<target>16</target> | ||
</configuration> | ||
</plugin> | ||
|
||
<plugin> | ||
<groupId>org.codehaus.mojo</groupId> | ||
<artifactId>animal-sniffer-maven-plugin</artifactId> | ||
<configuration> | ||
<skip>true</skip> | ||
</configuration> | ||
</plugin> | ||
|
||
|
||
</plugins> | ||
|
||
|
||
</build> | ||
|
||
</project> |
72 changes: 72 additions & 0 deletions
72
...java16/src/main/java/io/toolisticon/aptk/tools/wrapper/RecordComponentElementWrapper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
package io.toolisticon.aptk.tools.wrapper; | ||
|
||
import javax.lang.model.element.Element; | ||
import javax.lang.model.element.RecordComponentElement; | ||
import javax.lang.model.element.TypeElement; | ||
import java.util.Collections; | ||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
|
||
/** | ||
* Wrapper class for RecordComponentElementWrapper. | ||
*/ | ||
public class RecordComponentElementWrapper extends ElementWrapper<RecordComponentElement> { | ||
private RecordComponentElementWrapper(RecordComponentElement recordComponentElement) { | ||
super(recordComponentElement); | ||
} | ||
|
||
/** | ||
* Gets the enclosing records TypeElement | ||
* @return the wrapped enclosing records TypeElement | ||
*/ | ||
public TypeElementWrapper getEnclosingRecordTypeElement() { | ||
return TypeElementWrapper.wrap((TypeElement) element.getEnclosingElement()); | ||
} | ||
|
||
/** | ||
* Wraps the getAccessor method, but returns a ExecutableElementWrapper | ||
* @return the accessors wrapped ExecutableElement | ||
*/ | ||
public ExecutableElementWrapper getAccessor() { | ||
return ExecutableElementWrapper.wrap(element.getAccessor()); | ||
} | ||
|
||
/** | ||
* Gets the record components for a TypeElementWrapper. | ||
* @param typeElement the type element wrapper to get the record components for | ||
* @return A list containing the wrapped RecordComponentElement if they exist, otherwise an empty list. | ||
*/ | ||
public static List<RecordComponentElementWrapper> getRecordComponents(TypeElementWrapper typeElement) { | ||
if (typeElement == null) { | ||
return Collections.EMPTY_LIST; | ||
} | ||
return getRecordComponents(typeElement.unwrap()); | ||
} | ||
|
||
/** | ||
* Gets the record components for a TypeElement. | ||
* @param typeElement the type element wrapper to get the record components for | ||
* @return A list containing the wrapped RecordComponentElement if they exist, otherwise an empty list. | ||
*/ | ||
public static List<RecordComponentElementWrapper> getRecordComponents(TypeElement typeElement) { | ||
if (typeElement == null) { | ||
return Collections.EMPTY_LIST; | ||
} | ||
|
||
return typeElement.getRecordComponents().stream().map(RecordComponentElementWrapper::wrap).toList(); | ||
|
||
} | ||
|
||
public static RecordComponentElementWrapper toRecordComponentElement(Element element) { | ||
return RecordComponentElementWrapper.wrap((RecordComponentElement) element); | ||
} | ||
|
||
public static RecordComponentElementWrapper wrap(RecordComponentElement moduleElement) { | ||
return new RecordComponentElementWrapper(moduleElement); | ||
} | ||
|
||
public static List<RecordComponentElementWrapper> wrapList(List<RecordComponentElement> moduleElements) { | ||
return moduleElements.stream().map(RecordComponentElementWrapper::new).collect(Collectors.toList()); | ||
} | ||
|
||
} |
165 changes: 165 additions & 0 deletions
165
extensions/java16/src/test/java/io/toolisticon/aptk/tools/wrapper/Java16Tests.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,165 @@ | ||
package io.toolisticon.aptk.tools.wrapper; | ||
|
||
import io.toolisticon.aptk.common.ToolingProvider; | ||
import io.toolisticon.aptk.tools.corematcher.AptkCoreMatchers; | ||
import io.toolisticon.cute.Cute; | ||
import io.toolisticon.cute.PassIn; | ||
import org.hamcrest.MatcherAssert; | ||
import org.hamcrest.Matchers; | ||
import org.junit.Test; | ||
|
||
import javax.lang.model.element.TypeElement; | ||
import java.util.Set; | ||
import java.util.stream.Collectors; | ||
|
||
public class Java16Tests { | ||
|
||
@PassIn | ||
record MyRecord(String name, String surname){} | ||
|
||
@Test | ||
public void test_records_isRecord() { | ||
Cute.unitTest().when().passInElement().fromClass(MyRecord.class).intoUnitTest( (processingEnvironment, element) -> { | ||
try { | ||
ToolingProvider.setTooling(processingEnvironment); | ||
|
||
ElementWrapper<?> elementWrapper = ElementWrapper.wrap(element); | ||
|
||
MatcherAssert.assertThat("Should detect record ", elementWrapper.isRecord()); | ||
MatcherAssert.assertThat("Should not detect record ", !TypeElementWrapper.getByClass(Java16Tests.class).get().isRecord()); | ||
|
||
} finally { | ||
ToolingProvider.clearTooling(); | ||
} | ||
|
||
}).thenExpectThat().compilationSucceeds().executeTest(); | ||
|
||
} | ||
|
||
@Test | ||
public void test_records_isTypeElement() { | ||
Cute.unitTest().when().passInElement().fromClass(MyRecord.class).intoUnitTest( (processingEnvironment, element) -> { | ||
try { | ||
ToolingProvider.setTooling(processingEnvironment); | ||
|
||
ElementWrapper<?> elementWrapper = ElementWrapper.wrap(element); | ||
|
||
MatcherAssert.assertThat("Should detect record ", elementWrapper.isTypeElement()); | ||
MatcherAssert.assertThat("Should return false", !elementWrapper.isExecutableElement()); | ||
MatcherAssert.assertThat("Should return false ", !elementWrapper.isVariableElement()); | ||
MatcherAssert.assertThat("Should return false ", !elementWrapper.isTypeParameterElement()); | ||
MatcherAssert.assertThat("Should return false", !elementWrapper.isModuleElement()); | ||
|
||
} finally { | ||
ToolingProvider.clearTooling(); | ||
} | ||
|
||
}).thenExpectThat().compilationSucceeds().executeTest(); | ||
|
||
} | ||
|
||
|
||
@Test | ||
public void test_recordComponent_isRecordComponent() { | ||
Cute.unitTest().when().passInElement().fromClass(MyRecord.class).intoUnitTest( (processingEnvironment, element) -> { | ||
try { | ||
ToolingProvider.setTooling(processingEnvironment); | ||
|
||
TypeElement typeElement = (TypeElement) element; | ||
|
||
ElementWrapper<?> elementWrapper = ElementWrapper.wrap(typeElement.getRecordComponents().get(0)); | ||
|
||
MatcherAssert.assertThat("Should detect record ", elementWrapper.isRecordComponent()); | ||
MatcherAssert.assertThat("Should not detect record ", !TypeElementWrapper.getByClass(Java16Tests.class).get().isRecordComponent()); | ||
|
||
} finally { | ||
ToolingProvider.clearTooling(); | ||
} | ||
|
||
}).thenExpectThat().compilationSucceeds().executeTest(); | ||
|
||
} | ||
|
||
@Test | ||
public void test_recordComponent_isTypeElement() { | ||
Cute.unitTest().when().passInElement().fromClass(MyRecord.class).intoUnitTest( (processingEnvironment, element) -> { | ||
try { | ||
ToolingProvider.setTooling(processingEnvironment); | ||
|
||
TypeElement typeElement = (TypeElement) element; | ||
|
||
ElementWrapper<?> elementWrapper = ElementWrapper.wrap(typeElement.getRecordComponents().get(0)); | ||
|
||
MatcherAssert.assertThat("Should detect RecordComponentElement ", elementWrapper.isRecordComponentElement()); | ||
MatcherAssert.assertThat("Should detect false ", !elementWrapper.isTypeElement()); | ||
MatcherAssert.assertThat("Should return false", !elementWrapper.isExecutableElement()); | ||
MatcherAssert.assertThat("Should return false ", !elementWrapper.isVariableElement()); | ||
MatcherAssert.assertThat("Should return false ", !elementWrapper.isTypeParameterElement()); | ||
MatcherAssert.assertThat("Should return false", !elementWrapper.isModuleElement()); | ||
|
||
} finally { | ||
ToolingProvider.clearTooling(); | ||
} | ||
|
||
}).thenExpectThat().compilationSucceeds().executeTest(); | ||
|
||
} | ||
|
||
|
||
public void test_recordComponent_simpleName() { | ||
Cute.unitTest().when().passInElement().fromClass(MyRecord.class).intoUnitTest( (processingEnvironment, element) -> { | ||
try { | ||
ToolingProvider.setTooling(processingEnvironment); | ||
TypeElement typeElement = (TypeElement) element; | ||
|
||
RecordComponentElementWrapper elementWrapper = RecordComponentElementWrapper.wrap(typeElement.getRecordComponents().get(0)); | ||
MatcherAssert.assertThat( elementWrapper.getSimpleName(), Matchers.is("name")); | ||
|
||
} finally { | ||
ToolingProvider.clearTooling(); | ||
} | ||
|
||
}).thenExpectThat().compilationSucceeds().executeTest(); | ||
|
||
} | ||
|
||
@Test | ||
public void test_recordComponent_filtering_byTypeElement() { | ||
Cute.unitTest().when( (processingEnvironment) -> { | ||
try { | ||
ToolingProvider.setTooling(processingEnvironment); | ||
TypeElementWrapper typeElement = TypeElementWrapper.getByClass(Java16Tests.class).get(); | ||
|
||
Set<String> enclosedTypeElements = typeElement.filterFlattenedEnclosedElementTree().applyFilter(AptkCoreMatchers.IS_TYPE_ELEMENT).getResult().stream().map(e -> e.getQualifiedName().toString()).collect(Collectors.toSet()); | ||
|
||
MatcherAssert.assertThat( enclosedTypeElements, Matchers.contains(MyRecord.class.getCanonicalName())); | ||
|
||
} finally { | ||
ToolingProvider.clearTooling(); | ||
} | ||
|
||
}).thenExpectThat().compilationSucceeds().executeTest(); | ||
|
||
} | ||
|
||
@Test | ||
public void test_recordComponent_filtering_byRecord() { | ||
Cute.unitTest().when( (processingEnvironment) -> { | ||
try { | ||
ToolingProvider.setTooling(processingEnvironment); | ||
TypeElementWrapper typeElement = TypeElementWrapper.getByClass(Java16Tests.class).get(); | ||
|
||
Set<String> enclosedTypeElements = typeElement.filterFlattenedEnclosedElementTree().applyFilter(AptkCoreMatchers.IS_RECORD).getResult().stream().map(e -> e.getQualifiedName().toString()).collect(Collectors.toSet()); | ||
|
||
MatcherAssert.assertThat(enclosedTypeElements, Matchers.hasSize(1)); | ||
MatcherAssert.assertThat( enclosedTypeElements, Matchers.contains(MyRecord.class.getCanonicalName())); | ||
|
||
} finally { | ||
ToolingProvider.clearTooling(); | ||
} | ||
|
||
}).thenExpectThat().compilationSucceeds().executeTest(); | ||
|
||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.