Skip to content

Commit

Permalink
fix: 🚑 [BUG] Annotation parameters are not passed to generated record (
Browse files Browse the repository at this point in the history
…#157)

* fix: Copy values in class and parameter annotations

* feat: List of annotation mirrors added to Context

---------

Co-authored-by: create-issue-branch[bot] <53036503+create-issue-branch[bot]@users.noreply.github.com>
Co-authored-by: Pawel_Labaj <[email protected]>
  • Loading branch information
create-issue-branch[bot] and pawellabaj authored Jan 23, 2024
1 parent 491e6ee commit bbbc24b
Show file tree
Hide file tree
Showing 8 changed files with 59 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.apiguardian.api.API;
import pl.com.labaj.autorecord.AutoRecord;

import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.TypeParameterElement;
import javax.lang.model.type.TypeMirror;
import java.util.List;
Expand Down Expand Up @@ -70,6 +71,14 @@ public interface Context {
*/
boolean isRecordPublic();

/**
* Gets annotations of the annotated interface.
*
* @return annotations of the annotated interface.
* @see AnnotationMirror
*/
List<AnnotationMirror> interfaceAnnotations();

/**
* Gets the type of the annotated interface.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@
import static java.util.Objects.isNull;

@AutoRecord
@SuppressWarnings("onClass")
interface AnnotationWithValue {
@Nullable
@SuppressWarnings("onField")
Integer id();

@SourceProperty
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,15 @@
import pl.com.labaj.autorecord.memoizer.Memoizer;

@Generated("pl.com.labaj.autorecord.AutoRecord")
@SuppressWarnings({"onClass"})
@GeneratedWithAutoRecord
record AnnotationWithValueRecord(@Nullable Integer id,
record AnnotationWithValueRecord(@Nullable @SuppressWarnings({"onField"}) Integer id,
@SourceProperty @ClassProperty(priority = 9) @Nullable Memoizer<String> idToStringMemoizer) implements AnnotationWithValue {
AnnotationWithValueRecord {
idToStringMemoizer = requireNonNullElseGet(idToStringMemoizer, Memoizer::new);
}

AnnotationWithValueRecord(@Nullable Integer id) {
AnnotationWithValueRecord(@Nullable @SuppressWarnings({"onField"}) Integer id) {
this(id, new Memoizer<>());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

import javax.annotation.Nullable;
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.TypeParameterElement;
Expand All @@ -41,6 +42,9 @@ public class ContextBuilder {
"useImmutableCollections", false,
"useUnmodifiableCollections", false
);
private static final String PL_COM_LABAJ_AUTORECORD = "pl.com.labaj.autorecord";
private static final String PL_COM_LABAJ_AUTORECORD_EXTENSION = "pl.com.labaj.autorecord.extension";
private static final String IO_SOABASE_RECORDBUILDER_CORE = "io.soabase.recordbuilder.core";

private final ProcessingEnvironment processingEnv;
private final MemoizationFinder memoizationFinder = new MemoizationFinder();
Expand Down Expand Up @@ -69,6 +73,7 @@ public ProcessorContext buildContext(TypeElement sourceInterface,
.toList();

boolean isPublic = sourceInterface.getModifiers().contains(PUBLIC);
var interfaceAnnotations = getInterfaceAnnotations(sourceInterface);
var typeParameters = getTypeParameters(sourceInterface);

var specialMethodAnnotations = specialMethodsFinder.findSpecialMethods(allMethods);
Expand All @@ -80,6 +85,7 @@ public ProcessorContext buildContext(TypeElement sourceInterface,
nonNullRecordOptions,
nonNullBuilderOptions,
isPublic,
interfaceAnnotations,
sourceInterface.asType(),
getInterfaceName(sourceInterface),
components,
Expand All @@ -100,6 +106,24 @@ private Map<String, Object> getBuilderOptionsEnforcedValues(List<AutoRecordExten
WITH_IMMUTABLE_COLLECTIONS_BUILDER_OPTIONS_ENFORCED_VALUES : DEFAULT_BUILDER_OPTIONS_ENFORCED_VALUES;
}

private List<AnnotationMirror> getInterfaceAnnotations(TypeElement sourceInterface) {
var elementUtils = processingEnv.getElementUtils();

return elementUtils.getAllAnnotationMirrors(sourceInterface).stream()
.filter(annotationMirror -> hasPackageDifferentThan(annotationMirror, PL_COM_LABAJ_AUTORECORD))
.filter(annotationMirror -> hasPackageDifferentThan(annotationMirror, PL_COM_LABAJ_AUTORECORD_EXTENSION))
.filter(annotationMirror -> hasPackageDifferentThan(annotationMirror, IO_SOABASE_RECORDBUILDER_CORE))
.map(AnnotationMirror.class::cast)
.toList();
}

private boolean hasPackageDifferentThan(AnnotationMirror annotationMirror, String packageName) {
var elementUtils = processingEnv.getElementUtils();
var annotationPackage = elementUtils.getPackageOf(annotationMirror.getAnnotationType().asElement());

return !annotationPackage.getQualifiedName().contentEquals(packageName);
}

private List<TypeParameterElement> getTypeParameters(TypeElement sourceInterface) {
return sourceInterface.getTypeParameters().stream()
.map(TypeParameterElement.class::cast)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public record ProcessorContext(ProcessingEnvironment processingEnv,
AutoRecord.Options recordOptions,
RecordBuilder.Options builderOptions,
boolean isRecordPublic,
List<AnnotationMirror> interfaceAnnotations,
TypeMirror interfaceType,
String interfaceName,
List<RecordComponent> components,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import javax.annotation.Nullable;
import javax.annotation.processing.Generated;
import javax.lang.model.element.Modifier;
import java.lang.annotation.ElementType;
import java.util.List;
import java.util.Set;
import java.util.stream.Stream;
Expand All @@ -44,13 +45,13 @@
import static java.util.stream.Collectors.joining;
import static javax.lang.model.element.Modifier.PUBLIC;
import static pl.com.labaj.autorecord.processor.utils.Annotations.createAnnotationSpecs;
import static pl.com.labaj.autorecord.processor.utils.Annotations.createParameterAnnotationSpecs;
import static pl.com.labaj.autorecord.processor.utils.Extensions.typedExtensions;

class BasicGenerator extends RecordGenerator {
private static final AnnotationSpec GENERATED_ANNOTATION = AnnotationSpec.builder(Generated.class)
.addMember("value", "$S", AutoRecord.class.getName())
.build();
private static final AnnotationSpec GENERATED_WITH_AUTO_RECORD_ANNOTATION = AnnotationSpec.builder(GeneratedWithAutoRecord.class).build();

private final CompactConstructorSubGenerator compactConstructorSubGenerator;

Expand All @@ -63,21 +64,31 @@ class BasicGenerator extends RecordGenerator {
public void generate(TypeSpec.Builder recordBuilder, StaticImports staticImports) {
recordBuilder
.addAnnotation(GENERATED_ANNOTATION)
.addAnnotation(GENERATED_WITH_AUTO_RECORD_ANNOTATION)
.addModifiers(getMainModifiers(context))
.addSuperinterface(context.interfaceType());

var recordComponentParameters = context.components().stream()
.map(this::toParameterSpec)
.toList();

generateAnnotations(recordBuilder);
generateTypeVariables(recordBuilder);
generateComponents(recordBuilder, recordComponentParameters);
createAdditionalConstructor(recordBuilder, recordComponentParameters);

compactConstructorSubGenerator.generate(recordBuilder, staticImports);
}

private void generateAnnotations(TypeSpec.Builder recordBuilder) {
var annotationSpecs = createAnnotationSpecs(context.interfaceAnnotations(),
Set.of(ElementType.TYPE),
List.of(GeneratedWithAutoRecord.class),
List.of());

annotationSpecs
.forEach(recordBuilder::addAnnotation);
}

private void generateComponents(TypeSpec.Builder recordBuilder, List<ParameterSpec> recordComponentParameters) {
recordBuilder.addRecordComponents(recordComponentParameters);

Expand Down Expand Up @@ -116,7 +127,7 @@ private void createAdditionalConstructor(TypeSpec.Builder recordBuilder, List<Pa

private ParameterSpec toParameterSpec(RecordComponent recordComponent) {
var type = TypeName.get(recordComponent.type());
var annotations = createAnnotationSpecs(recordComponent.annotations());
var annotations = createParameterAnnotationSpecs(recordComponent.annotations());

return ParameterSpec.builder(type, recordComponent.name())
.addAnnotations(annotations)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import static java.util.stream.Collectors.joining;
import static javax.lang.model.element.Modifier.PUBLIC;
import static pl.com.labaj.autorecord.processor.utils.Annotations.createAnnotationSpecs;
import static pl.com.labaj.autorecord.processor.utils.Annotations.createParameterAnnotationSpecs;

class MemoizationGenerator extends RecordGenerator {

Expand Down Expand Up @@ -69,7 +70,7 @@ private MethodSpec toMemoizedMethodSpec(Memoization.Item item) {
item.parameters().stream()
.map(parameter -> {
var type = TypeName.get(parameter.type());
var parameterAnnotations = createAnnotationSpecs(parameter.annotations());
var parameterAnnotations = createParameterAnnotationSpecs(parameter.annotations());

return ParameterSpec.builder(type, parameter.name())
.addAnnotations(parameterAnnotations)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
import javax.lang.model.element.AnnotationValue;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.DeclaredType;
import java.lang.annotation.Annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Repeatable;
Expand Down Expand Up @@ -61,14 +60,11 @@ public static <A extends Annotation> List<A> getAnnotations(TypeElement element,
return List.of(element.getAnnotationsByType(annotationClass));
}

public static List<AnnotationSpec> createAnnotationSpecs(List<AnnotationMirror> annotations) {
public static List<AnnotationSpec> createParameterAnnotationSpecs(List<AnnotationMirror> annotations) {
return annotations.stream()
.map(AnnotationMirror::getAnnotationType)
.map(DeclaredType::asElement)
.map(TypeElement.class::cast)
.map(ClassName::get)
.map(AnnotationSpec::builder)
.map(AnnotationSpec.Builder::build)
.map(annotationMirror -> AnnotationDetails.toAnnotationDetails(annotationMirror, Set.of(ElementType.PARAMETER)))
.filter(Objects::nonNull)
.map(AnnotationDetails::toAnnotationSpec)
.toList();
}

Expand Down

0 comments on commit bbbc24b

Please sign in to comment.