Various clean ups (#150)

This commit is contained in:
Jordan Zimmerman
2023-03-29 08:07:59 +01:00
committed by GitHub
parent f3303c2386
commit 685a31b56b
88 changed files with 857 additions and 1068 deletions

26
pom.xml
View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- <!--
Copyright 2019 Jordan Zimmerman Copyright 2019 The original author or authors
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@@ -52,6 +52,7 @@
<maven-surefire-plugin-version>3.0.0-M5</maven-surefire-plugin-version> <maven-surefire-plugin-version>3.0.0-M5</maven-surefire-plugin-version>
<jacoco-maven-plugin-version>0.8.7</jacoco-maven-plugin-version> <jacoco-maven-plugin-version>0.8.7</jacoco-maven-plugin-version>
<formatter-maven-plugin-version>2.22.0</formatter-maven-plugin-version>
<license-file-path>src/etc/header.txt</license-file-path> <license-file-path>src/etc/header.txt</license-file-path>
@@ -353,6 +354,24 @@
<artifactId>jacoco-maven-plugin</artifactId> <artifactId>jacoco-maven-plugin</artifactId>
<version>${jacoco-maven-plugin-version}</version> <version>${jacoco-maven-plugin-version}</version>
</plugin> </plugin>
<plugin>
<groupId>net.revelc.code.formatter</groupId>
<artifactId>formatter-maven-plugin</artifactId>
<version>${formatter-maven-plugin-version}</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>format</goal>
</goals>
<configuration>
<compilerCompliance>17</compilerCompliance>
<compilerSource>17</compilerSource>
</configuration>
</execution>
</executions>
</plugin>
</plugins> </plugins>
</pluginManagement> </pluginManagement>
@@ -391,6 +410,11 @@
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId> <artifactId>maven-surefire-plugin</artifactId>
</plugin> </plugin>
<plugin>
<groupId>net.revelc.code.formatter</groupId>
<artifactId>formatter-maven-plugin</artifactId>
</plugin>
</plugins> </plugins>
</build> </build>

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- <!--
Copyright 2019 Jordan Zimmerman Copyright 2019 The original author or authors
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -22,7 +22,7 @@ import java.lang.annotation.*;
@Target(ElementType.TYPE) @Target(ElementType.TYPE)
@Inherited @Inherited
public @interface RecordBuilder { public @interface RecordBuilder {
@Target({ElementType.TYPE, ElementType.PACKAGE}) @Target({ ElementType.TYPE, ElementType.PACKAGE })
@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE)
@Inherited @Inherited
@interface Include { @interface Include {
@@ -32,27 +32,25 @@ public @interface RecordBuilder {
Class<?>[] value() default {}; Class<?>[] value() default {};
/** /**
* Synonym for {@code value()}. When using the other attributes it maybe clearer to * Synonym for {@code value()}. When using the other attributes it maybe clearer to use {@code classes()}
* use {@code classes()} instead of {@code value()}. Note: both attributes are applied * instead of {@code value()}. Note: both attributes are applied (i.e. a union of classes from both attributes).
* (i.e. a union of classes from both attributes).
* *
* @return collection of classes * @return collection of classes
*/ */
Class<?>[] classes() default {}; Class<?>[] classes() default {};
/** /**
* Optional list of package names. All records in the packages will get processed as * Optional list of package names. All records in the packages will get processed as if they were listed as
* if they were listed as classes to include. * classes to include.
* *
* @return collection of package names * @return collection of package names
*/ */
String[] packages() default {}; String[] packages() default {};
/** /**
* Pattern used to generate the package for the generated class. The value * Pattern used to generate the package for the generated class. The value is the literal package name however
* is the literal package name however two replacement values can be used. '@' * two replacement values can be used. '@' is replaced with the package of the {@code Include} annotation. '*'
* is replaced with the package of the {@code Include} annotation. '*' is replaced with * is replaced with the package of the included class.
* the package of the included class.
* *
* @return package pattern * @return package pattern
*/ */
@@ -64,14 +62,14 @@ public @interface RecordBuilder {
@Inherited @Inherited
@interface Options { @interface Options {
/** /**
* The builder class name will be the name of the record (prefixed with any enclosing class) plus this suffix. E.g. * The builder class name will be the name of the record (prefixed with any enclosing class) plus this suffix.
* if the record name is "Foo", the builder will be named "FooBuilder". * E.g. if the record name is "Foo", the builder will be named "FooBuilder".
*/ */
String suffix() default "Builder"; String suffix() default "Builder";
/** /**
* Used by {@code RecordInterface}. The generated record will have the same name as the annotated interface * Used by {@code RecordInterface}. The generated record will have the same name as the annotated interface plus
* plus this suffix. E.g. if the interface name is "Foo", the record will be named "FooRecord". * this suffix. E.g. if the interface name is "Foo", the record will be named "FooRecord".
*/ */
String interfaceSuffix() default "Record"; String interfaceSuffix() default "Record";
@@ -126,22 +124,20 @@ public @interface RecordBuilder {
String fileIndent() default " "; String fileIndent() default " ";
/** /**
* If the record is declared inside another class, the outer class's name will * If the record is declared inside another class, the outer class's name will be prefixed to the builder name
* be prefixed to the builder name if this returns true. * if this returns true.
*/ */
boolean prefixEnclosingClassNames() default true; boolean prefixEnclosingClassNames() default true;
/** /**
* If true, any annotations (if applicable) on record components are copied * If true, any annotations (if applicable) on record components are copied to the builder methods
* to the builder methods
* *
* @return true/false * @return true/false
*/ */
boolean inheritComponentAnnotations() default true; boolean inheritComponentAnnotations() default true;
/** /**
* Set the default value of {@code Optional} record components to * Set the default value of {@code Optional} record components to {@code Optional.empty()}
* {@code Optional.empty()}
*/ */
boolean emptyDefaultForOptional() default true; boolean emptyDefaultForOptional() default true;
@@ -151,8 +147,8 @@ public @interface RecordBuilder {
boolean addConcreteSettersForOptional() default false; boolean addConcreteSettersForOptional() default false;
/** /**
* Add not-null checks for record components annotated with any annotation named either "NotNull", * Add not-null checks for record components annotated with any annotation named either "NotNull", "NoNull", or
* "NoNull", or "NonNull" (see {@link #interpretNotNullsPattern()} for the actual regex matching pattern). * "NonNull" (see {@link #interpretNotNullsPattern()} for the actual regex matching pattern).
*/ */
boolean interpretNotNulls() default false; boolean interpretNotNulls() default false;
@@ -163,29 +159,33 @@ public @interface RecordBuilder {
String interpretNotNullsPattern() default "(?i)((notnull)|(nonnull)|(nonull))"; String interpretNotNullsPattern() default "(?i)((notnull)|(nonnull)|(nonull))";
/** /**
* <p>Pass built records through the Java Validation API if it's available in the classpath.</p> * <p>
* Pass built records through the Java Validation API if it's available in the classpath.
* </p>
* *
* <p>IMPORTANT: * <p>
* if this option is enabled you must include the {@code record-builder-validator} dependency in addition * IMPORTANT: if this option is enabled you must include the {@code record-builder-validator} dependency in
* to {@code record-builder-core}. {@code record-builder-validator} is implemented completely via reflection and * addition to {@code record-builder-core}. {@code record-builder-validator} is implemented completely via
* does not require other dependencies. Alternatively, you can define your own class with the package {@code package io.soabase.recordbuilder.validator;} * reflection and does not require other dependencies. Alternatively, you can define your own class with the
* named {@code RecordBuilderValidator} which has a public static method: {@code public static <T> T validate(T o)}.</p> * package {@code package io.soabase.recordbuilder.validator;} named {@code RecordBuilderValidator} which has a
* public static method: {@code public static <T> T validate(T o)}.
* </p>
*/ */
boolean useValidationApi() default false; boolean useValidationApi() default false;
/** /**
* Adds special handling for record components of type {@link java.util.List}, {@link java.util.Set}, * Adds special handling for record components of type {@link java.util.List}, {@link java.util.Set},
* {@link java.util.Map} and {@link java.util.Collection}. When the record is built, any components * {@link java.util.Map} and {@link java.util.Collection}. When the record is built, any components of these
* of these types are passed through an added shim method that uses the corresponding immutable collection * types are passed through an added shim method that uses the corresponding immutable collection (e.g.
* (e.g. {@code List.copyOf(o)}) or an empty immutable collection if the component is {@code null}. * {@code List.copyOf(o)}) or an empty immutable collection if the component is {@code null}.
*/ */
boolean useImmutableCollections() default false; boolean useImmutableCollections() default false;
/** /**
* When enabled, collection types ({@code List}, {@code Set} and {@code Map}) are handled specially. * When enabled, collection types ({@code List}, {@code Set} and {@code Map}) are handled specially. The setters
* The setters for these types now create an internal collection and items are added to that * for these types now create an internal collection and items are added to that collection. Additionally,
* collection. Additionally, "adder" methods prefixed with {@link #singleItemBuilderPrefix()} are created * "adder" methods prefixed with {@link #singleItemBuilderPrefix()} are created to add single items to these
* to add single items to these collections. * collections.
*/ */
boolean addSingleItemCollectionBuilders() default false; boolean addSingleItemCollectionBuilders() default false;
@@ -195,14 +195,14 @@ public @interface RecordBuilder {
String singleItemBuilderPrefix() default "add"; String singleItemBuilderPrefix() default "add";
/** /**
* When enabled, adds functional methods to the nested "With" class (such as {@code map()} and {@code accept()}). * When enabled, adds functional methods to the nested "With" class (such as {@code map()} and
* {@code accept()}).
*/ */
boolean addFunctionalMethodsToWith() default false; boolean addFunctionalMethodsToWith() default false;
/** /**
* If set, all builder setter methods will be prefixed with this string. Camel-casing will * If set, all builder setter methods will be prefixed with this string. Camel-casing will still be enforced, so
* still be enforced, so if this option is set to "set" a field named "myField" will get * if this option is set to "set" a field named "myField" will get a corresponding setter named "setMyField".
* a corresponding setter named "setMyField".
*/ */
String setterPrefix() default ""; String setterPrefix() default "";
@@ -212,44 +212,41 @@ public @interface RecordBuilder {
boolean enableGetters() default true; boolean enableGetters() default true;
/** /**
* If set, all builder getter methods will be prefixed with this string. Camel-casing will * If set, all builder getter methods will be prefixed with this string. Camel-casing will still be enforced, so
* still be enforced, so if this option is set to "get", a field named "myField" will get * if this option is set to "get", a field named "myField" will get a corresponding getter named "getMyField".
* a corresponding getter named "getMyField".
*/ */
String getterPrefix() default ""; String getterPrefix() default "";
/** /**
* If set, all boolean builder getter methods will be prefixed with this string. * If set, all boolean builder getter methods will be prefixed with this string. Camel-casing will still be
* Camel-casing will still be enforced, so if this option is set to "is", a field named * enforced, so if this option is set to "is", a field named "myField" will get a corresponding getter named
* "myField" will get a corresponding getter named "isMyField". * "isMyField".
*/ */
String booleanPrefix() default ""; String booleanPrefix() default "";
/** /**
* If set, the Builder will contain an internal interface with this name. This interface * If set, the Builder will contain an internal interface with this name. This interface contains getters for
* contains getters for all the fields in the Record prefixed with the value supplied in * all the fields in the Record prefixed with the value supplied in {@link this.getterPrefix} and
* {@link this.getterPrefix} and {@link this.booleanPrefix}. This interface can be * {@link this.booleanPrefix}. This interface can be implemented by the original Record to have proper
* implemented by the original Record to have proper bean-style prefixed getters. * bean-style prefixed getters. Please note that unless either of the aforementioned prefixes are set, this
* Please note that unless either of the aforementioned prefixes are set, * option does nothing.
* this option does nothing.
*/ */
String beanClassName() default ""; String beanClassName() default "";
/** /**
* If true, generated classes are annotated with {@code RecordBuilderGenerated} which has a retention * If true, generated classes are annotated with {@code RecordBuilderGenerated} which has a retention policy of
* policy of {@code CLASS}. This ensures that analyzers such as Jacoco will ignore the generated class. * {@code CLASS}. This ensures that analyzers such as Jacoco will ignore the generated class.
*/ */
boolean addClassRetainedGenerated() default false; boolean addClassRetainedGenerated() default false;
/** /**
* The {@link #fromMethodName} method instantiates an internal private class. This is the * The {@link #fromMethodName} method instantiates an internal private class. This is the name of that class.
* name of that class.
*/ */
String fromWithClassName() default "_FromWith"; String fromWithClassName() default "_FromWith";
/** /**
* If true, a functional-style builder is added so that record instances can be instantiated * If true, a functional-style builder is added so that record instances can be instantiated without
* without {@code new}. * {@code new}.
*/ */
boolean addStaticBuilder() default true; boolean addStaticBuilder() default true;
@@ -271,9 +268,8 @@ public @interface RecordBuilder {
*/ */
String mutableMapClassName() default "_MutableMap"; String mutableMapClassName() default "_MutableMap";
/** /**
* Any additional {@link javax.lang.model.element.Modifier} you wish to apply to the builder. For example to * Any additional {@link javax.lang.model.element.Modifier} you wish to apply to the builder. For example to
* make the builder public when the record is package protect. * make the builder public when the record is package protect.
*/ */
Modifier[] builderClassModifiers() default {}; Modifier[] builderClassModifiers() default {};

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -18,16 +18,9 @@ package io.soabase.recordbuilder.core;
import java.lang.annotation.*; import java.lang.annotation.*;
/** /**
* An alternate form of {@code @RecordBuilder} that has most * An alternate form of {@code @RecordBuilder} that has most optional features turned on
* optional features turned on
*/ */
@RecordBuilder.Template(options = @RecordBuilder.Options( @RecordBuilder.Template(options = @RecordBuilder.Options(interpretNotNulls = true, useImmutableCollections = true, addSingleItemCollectionBuilders = true, addFunctionalMethodsToWith = true, addClassRetainedGenerated = true))
interpretNotNulls = true,
useImmutableCollections = true,
addSingleItemCollectionBuilders = true,
addFunctionalMethodsToWith = true,
addClassRetainedGenerated = true
))
@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE)
@Target(ElementType.TYPE) @Target(ElementType.TYPE)
@Inherited @Inherited

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -24,7 +24,7 @@ import static java.lang.annotation.ElementType.*;
/** /**
* Jacoco ignores classes and methods annotated with `*Generated` * Jacoco ignores classes and methods annotated with `*Generated`
*/ */
@Target({PACKAGE, TYPE, METHOD, CONSTRUCTOR, FIELD, LOCAL_VARIABLE, PARAMETER}) @Target({ PACKAGE, TYPE, METHOD, CONSTRUCTOR, FIELD, LOCAL_VARIABLE, PARAMETER })
@Retention(RetentionPolicy.CLASS) @Retention(RetentionPolicy.CLASS)
public @interface RecordBuilderGenerated { public @interface RecordBuilderGenerated {
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -23,7 +23,7 @@ import java.lang.annotation.*;
public @interface RecordInterface { public @interface RecordInterface {
boolean addRecordBuilder() default true; boolean addRecordBuilder() default true;
@Target({ElementType.TYPE, ElementType.PACKAGE}) @Target({ ElementType.TYPE, ElementType.PACKAGE })
@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE)
@Inherited @Inherited
@interface Include { @interface Include {
@@ -33,9 +33,8 @@ public @interface RecordInterface {
Class<?>[] value() default {}; Class<?>[] value() default {};
/** /**
* Synonym for {@code value()}. When using the other attributes it maybe clearer to * Synonym for {@code value()}. When using the other attributes it maybe clearer to use {@code classes()}
* use {@code classes()} instead of {@code value()}. Note: both attributes are applied * instead of {@code value()}. Note: both attributes are applied (i.e. a union of classes from both attributes).
* (i.e. a union of classes from both attributes).
* *
* @return collection of classes * @return collection of classes
*/ */
@@ -49,10 +48,9 @@ public @interface RecordInterface {
boolean addRecordBuilder() default true; boolean addRecordBuilder() default true;
/** /**
* Pattern used to generate the package for the generated class. The value * Pattern used to generate the package for the generated class. The value is the literal package name however
* is the literal package name however two replacement values can be used. '@' * two replacement values can be used. '@' is replaced with the package of the {@code Include} annotation. '*'
* is replaced with the package of the {@code Include} annotation. '*' is replaced with * is replaced with the package of the included class.
* the package of the included class.
* *
* @return package pattern * @return package pattern
*/ */

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- <!--
Copyright 2019 Jordan Zimmerman Copyright 2019 The original author or authors
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -58,10 +58,14 @@ class CollectionBuilderUtils {
private static final TypeVariableName tType = TypeVariableName.get("T"); private static final TypeVariableName tType = TypeVariableName.get("T");
private static final TypeVariableName kType = TypeVariableName.get("K"); private static final TypeVariableName kType = TypeVariableName.get("K");
private static final TypeVariableName vType = TypeVariableName.get("V"); private static final TypeVariableName vType = TypeVariableName.get("V");
private static final ParameterizedTypeName parameterizedListType = ParameterizedTypeName.get(ClassName.get(List.class), tType); private static final ParameterizedTypeName parameterizedListType = ParameterizedTypeName
private static final ParameterizedTypeName parameterizedMapType = ParameterizedTypeName.get(ClassName.get(Map.class), kType, vType); .get(ClassName.get(List.class), tType);
private static final ParameterizedTypeName parameterizedSetType = ParameterizedTypeName.get(ClassName.get(Set.class), tType); private static final ParameterizedTypeName parameterizedMapType = ParameterizedTypeName
private static final ParameterizedTypeName parameterizedCollectionType = ParameterizedTypeName.get(ClassName.get(Collection.class), tType); .get(ClassName.get(Map.class), kType, vType);
private static final ParameterizedTypeName parameterizedSetType = ParameterizedTypeName
.get(ClassName.get(Set.class), tType);
private static final ParameterizedTypeName parameterizedCollectionType = ParameterizedTypeName
.get(ClassName.get(Collection.class), tType);
private static final Class<?> mutableListType = ArrayList.class; private static final Class<?> mutableListType = ArrayList.class;
private static final Class<?> mutableMapType = HashMap.class; private static final Class<?> mutableMapType = HashMap.class;
@@ -87,22 +91,24 @@ class CollectionBuilderUtils {
setMakerMethodName = disambiguateGeneratedMethodName(recordComponents, "__ensureSetMutable", 0); setMakerMethodName = disambiguateGeneratedMethodName(recordComponents, "__ensureSetMutable", 0);
mapMakerMethodName = disambiguateGeneratedMethodName(recordComponents, "__ensureMapMutable", 0); mapMakerMethodName = disambiguateGeneratedMethodName(recordComponents, "__ensureMapMutable", 0);
mutableListSpec = buildMutableCollectionSubType(metaData.mutableListClassName(), mutableListTypeName, parameterizedListType, tType); mutableListSpec = buildMutableCollectionSubType(metaData.mutableListClassName(), mutableListTypeName,
mutableSetSpec = buildMutableCollectionSubType(metaData.mutableSetClassName(), mutableSetTypeName, parameterizedSetType, tType); parameterizedListType, tType);
mutableMapSpec = buildMutableCollectionSubType(metaData.mutableMapClassName(), mutableMapTypeName, parameterizedMapType, kType, vType); mutableSetSpec = buildMutableCollectionSubType(metaData.mutableSetClassName(), mutableSetTypeName,
parameterizedSetType, tType);
mutableMapSpec = buildMutableCollectionSubType(metaData.mutableMapClassName(), mutableMapTypeName,
parameterizedMapType, kType, vType);
} }
enum SingleItemsMetaDataMode { enum SingleItemsMetaDataMode {
STANDARD, STANDARD, STANDARD_FOR_SETTER, EXCLUDE_WILDCARD_TYPES
STANDARD_FOR_SETTER,
EXCLUDE_WILDCARD_TYPES
} }
record SingleItemsMetaData(Class<?> singleItemCollectionClass, List<TypeName> typeArguments, TypeName wildType) { record SingleItemsMetaData(Class<?> singleItemCollectionClass, List<TypeName> typeArguments, TypeName wildType) {
} }
Optional<SingleItemsMetaData> singleItemsMetaData(RecordClassType component, SingleItemsMetaDataMode mode) { Optional<SingleItemsMetaData> singleItemsMetaData(RecordClassType component, SingleItemsMetaDataMode mode) {
if (addSingleItemCollectionBuilders && (component.typeName() instanceof ParameterizedTypeName parameterizedTypeName)) { if (addSingleItemCollectionBuilders
&& (component.typeName() instanceof ParameterizedTypeName parameterizedTypeName)) {
Class<?> collectionClass = null; Class<?> collectionClass = null;
ClassName wildcardClass = null; ClassName wildcardClass = null;
int typeArgumentQty = 0; int typeArgumentQty = 0;
@@ -122,21 +128,25 @@ class CollectionBuilderUtils {
var hasWildcardTypeArguments = hasWildcardTypeArguments(parameterizedTypeName, typeArgumentQty); var hasWildcardTypeArguments = hasWildcardTypeArguments(parameterizedTypeName, typeArgumentQty);
if (collectionClass != null) { if (collectionClass != null) {
return switch (mode) { return switch (mode) {
case STANDARD -> singleItemsMetaDataWithWildType(parameterizedTypeName, collectionClass, wildcardClass, typeArgumentQty); case STANDARD -> singleItemsMetaDataWithWildType(parameterizedTypeName, collectionClass, wildcardClass,
typeArgumentQty);
case STANDARD_FOR_SETTER -> { case STANDARD_FOR_SETTER -> {
if (hasWildcardTypeArguments) { if (hasWildcardTypeArguments) {
yield Optional.of(new SingleItemsMetaData(collectionClass, parameterizedTypeName.typeArguments, component.typeName())); yield Optional.of(new SingleItemsMetaData(collectionClass, parameterizedTypeName.typeArguments,
} component.typeName()));
yield singleItemsMetaDataWithWildType(parameterizedTypeName, collectionClass, wildcardClass, typeArgumentQty);
} }
yield singleItemsMetaDataWithWildType(parameterizedTypeName, collectionClass, wildcardClass,
typeArgumentQty);
}
case EXCLUDE_WILDCARD_TYPES -> { case EXCLUDE_WILDCARD_TYPES -> {
if (hasWildcardTypeArguments) { if (hasWildcardTypeArguments) {
yield Optional.empty(); yield Optional.empty();
}
yield singleItemsMetaDataWithWildType(parameterizedTypeName, collectionClass, wildcardClass, typeArgumentQty);
} }
yield singleItemsMetaDataWithWildType(parameterizedTypeName, collectionClass, wildcardClass,
typeArgumentQty);
}
}; };
} }
} }
@@ -144,7 +154,8 @@ class CollectionBuilderUtils {
} }
boolean isImmutableCollection(RecordClassType component) { boolean isImmutableCollection(RecordClassType component) {
return useImmutableCollections && (isList(component) || isMap(component) || isSet(component) || component.rawTypeName().equals(collectionTypeName)); return useImmutableCollections && (isList(component) || isMap(component) || isSet(component)
|| component.rawTypeName().equals(collectionTypeName));
} }
boolean isList(RecordClassType component) { boolean isList(RecordClassType component) {
@@ -216,7 +227,8 @@ class CollectionBuilderUtils {
} }
if (needsListShim) { if (needsListShim) {
builder.addMethod(buildShimMethod(listShimName, listTypeName, collectionType, parameterizedListType, tType)); builder.addMethod(
buildShimMethod(listShimName, listTypeName, collectionType, parameterizedListType, tType));
} }
if (needsSetShim) { if (needsSetShim) {
builder.addMethod(buildShimMethod(setShimName, setTypeName, collectionType, parameterizedSetType, tType)); builder.addMethod(buildShimMethod(setShimName, setTypeName, collectionType, parameterizedSetType, tType));
@@ -235,25 +247,32 @@ class CollectionBuilderUtils {
} }
if (needsListMutableMaker) { if (needsListMutableMaker) {
builder.addMethod(buildMutableMakerMethod(listMakerMethodName, mutableListSpec.name, parameterizedListType, tType)); builder.addMethod(
buildMutableMakerMethod(listMakerMethodName, mutableListSpec.name, parameterizedListType, tType));
builder.addType(mutableListSpec); builder.addType(mutableListSpec);
} }
if (needsSetMutableMaker) { if (needsSetMutableMaker) {
builder.addMethod(buildMutableMakerMethod(setMakerMethodName, mutableSetSpec.name, parameterizedSetType, tType)); builder.addMethod(
buildMutableMakerMethod(setMakerMethodName, mutableSetSpec.name, parameterizedSetType, tType));
builder.addType(mutableSetSpec); builder.addType(mutableSetSpec);
} }
if (needsMapMutableMaker) { if (needsMapMutableMaker) {
builder.addMethod(buildMutableMakerMethod(mapMakerMethodName, mutableMapSpec.name, parameterizedMapType, kType, vType)); builder.addMethod(buildMutableMakerMethod(mapMakerMethodName, mutableMapSpec.name, parameterizedMapType,
kType, vType));
builder.addType(mutableMapSpec); builder.addType(mutableMapSpec);
} }
} }
private Optional<SingleItemsMetaData> singleItemsMetaDataWithWildType(ParameterizedTypeName parameterizedTypeName, Class<?> collectionClass, ClassName wildcardClass, int typeArgumentQty) { private Optional<SingleItemsMetaData> singleItemsMetaDataWithWildType(ParameterizedTypeName parameterizedTypeName,
Class<?> collectionClass, ClassName wildcardClass, int typeArgumentQty) {
TypeName wildType; TypeName wildType;
if (typeArgumentQty == 1) { if (typeArgumentQty == 1) {
wildType = ParameterizedTypeName.get(wildcardClass, WildcardTypeName.subtypeOf(parameterizedTypeName.typeArguments.get(0))); wildType = ParameterizedTypeName.get(wildcardClass,
WildcardTypeName.subtypeOf(parameterizedTypeName.typeArguments.get(0)));
} else { // if (typeArgumentQty == 2) } else { // if (typeArgumentQty == 2)
wildType = ParameterizedTypeName.get(wildcardClass, WildcardTypeName.subtypeOf(parameterizedTypeName.typeArguments.get(0)), WildcardTypeName.subtypeOf(parameterizedTypeName.typeArguments.get(1))); wildType = ParameterizedTypeName.get(wildcardClass,
WildcardTypeName.subtypeOf(parameterizedTypeName.typeArguments.get(0)),
WildcardTypeName.subtypeOf(parameterizedTypeName.typeArguments.get(1)));
} }
return Optional.of(new SingleItemsMetaData(collectionClass, parameterizedTypeName.typeArguments, wildType)); return Optional.of(new SingleItemsMetaData(collectionClass, parameterizedTypeName.typeArguments, wildType));
} }
@@ -277,47 +296,41 @@ class CollectionBuilderUtils {
return name; return name;
} }
private MethodSpec buildShimMethod(String name, TypeName mainType, Class<?> abstractType, ParameterizedTypeName parameterizedType, TypeVariableName... typeVariables) { private MethodSpec buildShimMethod(String name, TypeName mainType, Class<?> abstractType,
ParameterizedTypeName parameterizedType, TypeVariableName... typeVariables) {
var code = CodeBlock.of("return (o != null) ? $T.copyOf(o) : $T.of()", mainType, mainType); var code = CodeBlock.of("return (o != null) ? $T.copyOf(o) : $T.of()", mainType, mainType);
TypeName[] wildCardTypeArguments = parameterizedType.typeArguments.stream().map(WildcardTypeName::subtypeOf).toList().toArray(new TypeName[0]); TypeName[] wildCardTypeArguments = parameterizedType.typeArguments.stream().map(WildcardTypeName::subtypeOf)
.toList().toArray(new TypeName[0]);
var extendedParameterizedType = ParameterizedTypeName.get(ClassName.get(abstractType), wildCardTypeArguments); var extendedParameterizedType = ParameterizedTypeName.get(ClassName.get(abstractType), wildCardTypeArguments);
return MethodSpec.methodBuilder(name) return MethodSpec.methodBuilder(name).addAnnotation(generatedRecordBuilderAnnotation)
.addAnnotation(generatedRecordBuilderAnnotation) .addModifiers(Modifier.PRIVATE, Modifier.STATIC).addTypeVariables(Arrays.asList(typeVariables))
.addModifiers(Modifier.PRIVATE, Modifier.STATIC) .returns(parameterizedType).addParameter(extendedParameterizedType, "o").addStatement(code).build();
.addTypeVariables(Arrays.asList(typeVariables))
.returns(parameterizedType)
.addParameter(extendedParameterizedType, "o")
.addStatement(code)
.build();
} }
private MethodSpec buildMutableMakerMethod(String name, String mutableCollectionType, ParameterizedTypeName parameterizedType, TypeVariableName... typeVariables) { private MethodSpec buildMutableMakerMethod(String name, String mutableCollectionType,
ParameterizedTypeName parameterizedType, TypeVariableName... typeVariables) {
var nullCase = CodeBlock.of("if (o == null) return new $L<>()", mutableCollectionType); var nullCase = CodeBlock.of("if (o == null) return new $L<>()", mutableCollectionType);
var isMutableCase = CodeBlock.of("if (o instanceof $L) return o", mutableCollectionType); var isMutableCase = CodeBlock.of("if (o instanceof $L) return o", mutableCollectionType);
var defaultCase = CodeBlock.of("return new $L<>(o)", mutableCollectionType); var defaultCase = CodeBlock.of("return new $L<>(o)", mutableCollectionType);
return MethodSpec.methodBuilder(name) return MethodSpec.methodBuilder(name).addAnnotation(generatedRecordBuilderAnnotation)
.addAnnotation(generatedRecordBuilderAnnotation) .addModifiers(Modifier.PRIVATE, Modifier.STATIC).addTypeVariables(Arrays.asList(typeVariables))
.addModifiers(Modifier.PRIVATE, Modifier.STATIC) .returns(parameterizedType).addParameter(parameterizedType, "o").addStatement(nullCase)
.addTypeVariables(Arrays.asList(typeVariables)) .addStatement(isMutableCase).addStatement(defaultCase).build();
.returns(parameterizedType)
.addParameter(parameterizedType, "o")
.addStatement(nullCase)
.addStatement(isMutableCase)
.addStatement(defaultCase)
.build();
} }
private TypeSpec buildMutableCollectionSubType(String className, ClassName mutableCollectionType, ParameterizedTypeName parameterizedType, TypeVariableName... typeVariables) { private TypeSpec buildMutableCollectionSubType(String className, ClassName mutableCollectionType,
TypeName[] typeArguments = new TypeName[]{}; ParameterizedTypeName parameterizedType, TypeVariableName... typeVariables) {
TypeName[] typeArguments = new TypeName[] {};
typeArguments = Arrays.stream(typeVariables).toList().toArray(typeArguments); typeArguments = Arrays.stream(typeVariables).toList().toArray(typeArguments);
TypeSpec.Builder builder = TypeSpec.classBuilder(className) TypeSpec.Builder builder = TypeSpec.classBuilder(className).addAnnotation(generatedRecordBuilderAnnotation)
.addAnnotation(generatedRecordBuilderAnnotation)
.addModifiers(Modifier.PRIVATE, Modifier.STATIC) .addModifiers(Modifier.PRIVATE, Modifier.STATIC)
.superclass(ParameterizedTypeName.get(mutableCollectionType, typeArguments)) .superclass(ParameterizedTypeName.get(mutableCollectionType, typeArguments))
.addTypeVariables(Arrays.asList(typeVariables)) .addTypeVariables(Arrays.asList(typeVariables))
.addMethod(MethodSpec.constructorBuilder().addAnnotation(generatedRecordBuilderAnnotation).addStatement("super()").build()) .addMethod(MethodSpec.constructorBuilder().addAnnotation(generatedRecordBuilderAnnotation)
.addMethod(MethodSpec.constructorBuilder().addAnnotation(generatedRecordBuilderAnnotation).addParameter(parameterizedType, "o").addStatement("super(o)").build()); .addStatement("super()").build())
.addMethod(MethodSpec.constructorBuilder().addAnnotation(generatedRecordBuilderAnnotation)
.addParameter(parameterizedType, "o").addStatement("super(o)").build());
if (addClassRetainedGenerated) { if (addClassRetainedGenerated) {
builder.addAnnotation(recordBuilderGeneratedAnnotation); builder.addAnnotation(recordBuilderGeneratedAnnotation);
@@ -327,21 +340,12 @@ class CollectionBuilderUtils {
} }
private MethodSpec buildCollectionsShimMethod() { private MethodSpec buildCollectionsShimMethod() {
var code = CodeBlock.builder() var code = CodeBlock.builder().add("if (o instanceof Set) {\n").indent()
.add("if (o instanceof Set) {\n") .addStatement("return $T.copyOf(o)", setTypeName).unindent().addStatement("}")
.indent() .addStatement("return (o != null) ? $T.copyOf(o) : $T.of()", listTypeName, listTypeName).build();
.addStatement("return $T.copyOf(o)", setTypeName) return MethodSpec.methodBuilder(collectionShimName).addAnnotation(generatedRecordBuilderAnnotation)
.unindent() .addModifiers(Modifier.PRIVATE, Modifier.STATIC).addTypeVariable(tType)
.addStatement("}") .returns(parameterizedCollectionType).addParameter(parameterizedCollectionType, "o").addCode(code)
.addStatement("return (o != null) ? $T.copyOf(o) : $T.of()", listTypeName, listTypeName)
.build();
return MethodSpec.methodBuilder(collectionShimName)
.addAnnotation(generatedRecordBuilderAnnotation)
.addModifiers(Modifier.PRIVATE, Modifier.STATIC)
.addTypeVariable(tType)
.returns(parameterizedCollectionType)
.addParameter(parameterizedCollectionType, "o")
.addCode(code)
.build(); .build();
} }
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -37,49 +37,43 @@ import java.util.Optional;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class ElementUtils { public class ElementUtils {
public static Optional<? extends AnnotationMirror> findAnnotationMirror(ProcessingEnvironment processingEnv, Element element, String annotationClass) { public static Optional<? extends AnnotationMirror> findAnnotationMirror(ProcessingEnvironment processingEnv,
Element element, String annotationClass) {
return processingEnv.getElementUtils().getAllAnnotationMirrors(element).stream() return processingEnv.getElementUtils().getAllAnnotationMirrors(element).stream()
.filter(e -> e.getAnnotationType().toString().equals(annotationClass)) .filter(e -> e.getAnnotationType().toString().equals(annotationClass)).findFirst();
.findFirst();
} }
public static Optional<? extends AnnotationValue> getAnnotationValue(Map<? extends ExecutableElement, ? extends AnnotationValue> values, String name) { public static Optional<? extends AnnotationValue> getAnnotationValue(
return values.entrySet() Map<? extends ExecutableElement, ? extends AnnotationValue> values, String name) {
.stream() return values.entrySet().stream().filter(e -> e.getKey().getSimpleName().toString().equals(name))
.filter(e -> e.getKey().getSimpleName().toString().equals(name)) .map(Map.Entry::getValue).findFirst();
.map(Map.Entry::getValue)
.findFirst();
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static List<TypeMirror> getAttributeTypeMirrorList(AnnotationValue attribute) public static List<TypeMirror> getAttributeTypeMirrorList(AnnotationValue attribute) {
{ List<? extends AnnotationValue> values = (attribute != null)
List<? extends AnnotationValue> values = (attribute != null) ? (List<? extends AnnotationValue>)attribute.getValue() : Collections.emptyList(); ? (List<? extends AnnotationValue>) attribute.getValue() : Collections.emptyList();
return values.stream().map(v -> (TypeMirror)v.getValue()).collect(Collectors.toList()); return values.stream().map(v -> (TypeMirror) v.getValue()).collect(Collectors.toList());
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static List<String> getAttributeStringList(AnnotationValue attribute) public static List<String> getAttributeStringList(AnnotationValue attribute) {
{ List<? extends AnnotationValue> values = (attribute != null)
List<? extends AnnotationValue> values = (attribute != null) ? (List<? extends AnnotationValue>)attribute.getValue() : Collections.emptyList(); ? (List<? extends AnnotationValue>) attribute.getValue() : Collections.emptyList();
return values.stream().map(v -> (String)v.getValue()).collect(Collectors.toList()); return values.stream().map(v -> (String) v.getValue()).collect(Collectors.toList());
} }
public static boolean getBooleanAttribute(AnnotationValue attribute) public static boolean getBooleanAttribute(AnnotationValue attribute) {
{
Object value = (attribute != null) ? attribute.getValue() : null; Object value = (attribute != null) ? attribute.getValue() : null;
if ( value != null ) if (value != null) {
{
return Boolean.parseBoolean(String.valueOf(value)); return Boolean.parseBoolean(String.valueOf(value));
} }
return false; return false;
} }
public static String getStringAttribute(AnnotationValue attribute, String defaultValue) public static String getStringAttribute(AnnotationValue attribute, String defaultValue) {
{
Object value = (attribute != null) ? attribute.getValue() : null; Object value = (attribute != null) ? attribute.getValue() : null;
if ( value != null ) if (value != null) {
{
return String.valueOf(value); return String.valueOf(value);
} }
return defaultValue; return defaultValue;
@@ -99,7 +93,8 @@ public class ElementUtils {
return (index > -1) ? name.substring(0, index) : ""; return (index > -1) ? name.substring(0, index) : "";
} }
public static ClassType getClassType(String packageName, String simpleName, List<? extends TypeParameterElement> typeParameters) { public static ClassType getClassType(String packageName, String simpleName,
List<? extends TypeParameterElement> typeParameters) {
return getClassType(ClassName.get(packageName, simpleName), typeParameters); return getClassType(ClassName.get(packageName, simpleName), typeParameters);
} }
@@ -107,7 +102,8 @@ public class ElementUtils {
return getClassType(ClassName.get(typeElement), typeParameters); return getClassType(ClassName.get(typeElement), typeParameters);
} }
public static ClassType getClassType(ClassName builderClassName, List<? extends TypeParameterElement> typeParameters) { public static ClassType getClassType(ClassName builderClassName,
List<? extends TypeParameterElement> typeParameters) {
if (typeParameters.isEmpty()) { if (typeParameters.isEmpty()) {
return new ClassType(builderClassName, builderClassName.simpleName()); return new ClassType(builderClassName, builderClassName.simpleName());
} }
@@ -115,10 +111,13 @@ public class ElementUtils {
return new ClassType(ParameterizedTypeName.get(builderClassName, typeNames), builderClassName.simpleName()); return new ClassType(ParameterizedTypeName.get(builderClassName, typeNames), builderClassName.simpleName());
} }
public static RecordClassType getRecordClassType(ProcessingEnvironment processingEnv, RecordComponentElement recordComponent, List<? extends AnnotationMirror> accessorAnnotations, List<? extends AnnotationMirror> canonicalConstructorAnnotations) { public static RecordClassType getRecordClassType(ProcessingEnvironment processingEnv,
RecordComponentElement recordComponent, List<? extends AnnotationMirror> accessorAnnotations,
List<? extends AnnotationMirror> canonicalConstructorAnnotations) {
var typeName = TypeName.get(recordComponent.asType()); var typeName = TypeName.get(recordComponent.asType());
var rawTypeName = TypeName.get(processingEnv.getTypeUtils().erasure(recordComponent.asType())); var rawTypeName = TypeName.get(processingEnv.getTypeUtils().erasure(recordComponent.asType()));
return new RecordClassType(typeName, rawTypeName, recordComponent.getSimpleName().toString(), accessorAnnotations, canonicalConstructorAnnotations); return new RecordClassType(typeName, rawTypeName, recordComponent.getSimpleName().toString(),
accessorAnnotations, canonicalConstructorAnnotations);
} }
public static String getWithMethodName(ClassType component, String prefix) { public static String getWithMethodName(ClassType component, String prefix) {
@@ -129,27 +128,30 @@ public class ElementUtils {
return prefix + Character.toUpperCase(name.charAt(0)) + name.substring(1); return prefix + Character.toUpperCase(name.charAt(0)) + name.substring(1);
} }
public static String getBuilderName(TypeElement element, RecordBuilder.Options metaData, ClassType classType, String suffix) { public static String getBuilderName(TypeElement element, RecordBuilder.Options metaData, ClassType classType,
String suffix) {
// generate the class name // generate the class name
var baseName = classType.name() + suffix; var baseName = classType.name() + suffix;
return metaData.prefixEnclosingClassNames() ? (getBuilderNamePrefix(element.getEnclosingElement()) + baseName) : baseName; return metaData.prefixEnclosingClassNames() ? (getBuilderNamePrefix(element.getEnclosingElement()) + baseName)
: baseName;
} }
public static Optional<? extends Element> findCanonicalConstructor(TypeElement record) { public static Optional<? extends Element> findCanonicalConstructor(TypeElement record) {
if ( record.getKind() != ElementKind.RECORD ) { if (record.getKind() != ElementKind.RECORD) {
return Optional.empty(); return Optional.empty();
} }
// based on https://github.com/openjdk/jdk/pull/3556/files#diff-a6270f4b50989abe733607c69038b2036306d13f77276af005d023b7fc57f1a2R2368 // based on
var componentList = record.getRecordComponents().stream().map(e -> e.asType().toString()).collect(Collectors.toList()); // https://github.com/openjdk/jdk/pull/3556/files#diff-a6270f4b50989abe733607c69038b2036306d13f77276af005d023b7fc57f1a2R2368
return record.getEnclosedElements().stream() var componentList = record.getRecordComponents().stream().map(e -> e.asType().toString())
.filter(element -> element.getKind() == ElementKind.CONSTRUCTOR) .collect(Collectors.toList());
.filter(element -> { return record.getEnclosedElements().stream().filter(element -> element.getKind() == ElementKind.CONSTRUCTOR)
var parameters = ((ExecutableElement)element).getParameters(); .filter(element -> {
var parametersList = parameters.stream().map(e -> e.asType().toString()).collect(Collectors.toList()); var parameters = ((ExecutableElement) element).getParameters();
return componentList.equals(parametersList); var parametersList = parameters.stream().map(e -> e.asType().toString())
}) .collect(Collectors.toList());
.findFirst(); return componentList.equals(parametersList);
}).findFirst();
} }
private static String getBuilderNamePrefix(Element element) { private static String getBuilderNamePrefix(Element element) {

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -28,7 +28,8 @@ class IncludeHelper {
private final List<TypeElement> classTypeElements; private final List<TypeElement> classTypeElements;
private final Map<? extends ExecutableElement, ? extends AnnotationValue> annotationValues; private final Map<? extends ExecutableElement, ? extends AnnotationValue> annotationValues;
IncludeHelper(ProcessingEnvironment processingEnv, Element element, AnnotationMirror annotationMirror, boolean packagesSupported) { IncludeHelper(ProcessingEnvironment processingEnv, Element element, AnnotationMirror annotationMirror,
boolean packagesSupported) {
annotationValues = processingEnv.getElementUtils().getElementValuesWithDefaults(annotationMirror); annotationValues = processingEnv.getElementUtils().getElementValuesWithDefaults(annotationMirror);
var value = ElementUtils.getAnnotationValue(annotationValues, "value"); var value = ElementUtils.getAnnotationValue(annotationValues, "value");
var classes = ElementUtils.getAnnotationValue(annotationValues, "classes"); var classes = ElementUtils.getAnnotationValue(annotationValues, "classes");
@@ -41,9 +42,11 @@ class IncludeHelper {
var packagesList = packages.map(ElementUtils::getAttributeStringList).orElseGet(List::of); var packagesList = packages.map(ElementUtils::getAttributeStringList).orElseGet(List::of);
if (valueList.isEmpty() && classesList.isEmpty() && packagesList.isEmpty()) { if (valueList.isEmpty() && classesList.isEmpty() && packagesList.isEmpty()) {
if (packagesSupported) { if (packagesSupported) {
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "At least one of \"value\", \"classes\" or \"packages\" required", element); processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,
"At least one of \"value\", \"classes\" or \"packages\" required", element);
} else { } else {
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "At least one of \"value\" or \"classes\" required", element); processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,
"At least one of \"value\" or \"classes\" required", element);
} }
isValid = false; isValid = false;
} }
@@ -51,7 +54,8 @@ class IncludeHelper {
isValid = processList(processingEnv, isValid, element, classesList, classTypeElements); isValid = processList(processingEnv, isValid, element, classesList, classTypeElements);
packages.ifPresent(annotationValue -> processPackages(processingEnv, classTypeElements, packagesList)); packages.ifPresent(annotationValue -> processPackages(processingEnv, classTypeElements, packagesList));
} else { } else {
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Could not read attribute for annotation", element); processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Could not read attribute for annotation",
element);
isValid = false; isValid = false;
} }
this.isValid = isValid; this.isValid = isValid;
@@ -70,11 +74,13 @@ class IncludeHelper {
return classTypeElements; return classTypeElements;
} }
private boolean processList(ProcessingEnvironment processingEnv, boolean isValid, Element element, List<TypeMirror> list, ArrayList<TypeElement> classTypeElements) { private boolean processList(ProcessingEnvironment processingEnv, boolean isValid, Element element,
List<TypeMirror> list, ArrayList<TypeElement> classTypeElements) {
for (var typeMirror : list) { for (var typeMirror : list) {
TypeElement typeElement = (TypeElement) processingEnv.getTypeUtils().asElement(typeMirror); TypeElement typeElement = (TypeElement) processingEnv.getTypeUtils().asElement(typeMirror);
if (typeElement == null) { if (typeElement == null) {
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Could not get element for: " + typeMirror, element); processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,
"Could not get element for: " + typeMirror, element);
isValid = false; isValid = false;
} else { } else {
classTypeElements.add(typeElement); classTypeElements.add(typeElement);
@@ -83,7 +89,8 @@ class IncludeHelper {
return isValid; return isValid;
} }
private void processPackages(ProcessingEnvironment processingEnv, List<TypeElement> classTypeElements, List<String> packagesList) { private void processPackages(ProcessingEnvironment processingEnv, List<TypeElement> classTypeElements,
List<String> packagesList) {
for (var packageName : packagesList) { for (var packageName : packagesList) {
var packageElement = processingEnv.getElementUtils().getPackageElement(packageName); var packageElement = processingEnv.getElementUtils().getPackageElement(packageName);
for (var child : packageElement.getEnclosedElements()) { for (var child : packageElement.getEnclosedElements()) {

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -51,30 +51,33 @@ class InternalRecordInterfaceProcessor {
private record Component(ExecutableElement element, Optional<String> alternateName) { private record Component(ExecutableElement element, Optional<String> alternateName) {
} }
InternalRecordInterfaceProcessor(ProcessingEnvironment processingEnv, TypeElement iface, boolean addRecordBuilder, RecordBuilder.Options metaData, Optional<String> packageNameOpt, boolean fromTemplate) { InternalRecordInterfaceProcessor(ProcessingEnvironment processingEnv, TypeElement iface, boolean addRecordBuilder,
RecordBuilder.Options metaData, Optional<String> packageNameOpt, boolean fromTemplate) {
this.processingEnv = processingEnv; this.processingEnv = processingEnv;
packageName = packageNameOpt.orElseGet(() -> ElementUtils.getPackageName(iface)); packageName = packageNameOpt.orElseGet(() -> ElementUtils.getPackageName(iface));
recordComponents = getRecordComponents(iface); recordComponents = getRecordComponents(iface);
this.iface = iface; this.iface = iface;
ClassType ifaceClassType = ElementUtils.getClassType(iface, iface.getTypeParameters()); ClassType ifaceClassType = ElementUtils.getClassType(iface, iface.getTypeParameters());
recordClassType = ElementUtils.getClassType(packageName, getBuilderName(iface, metaData, ifaceClassType, metaData.interfaceSuffix()), iface.getTypeParameters()); recordClassType = ElementUtils.getClassType(packageName,
List<TypeVariableName> typeVariables = iface.getTypeParameters().stream().map(TypeVariableName::get).collect(Collectors.toList()); getBuilderName(iface, metaData, ifaceClassType, metaData.interfaceSuffix()), iface.getTypeParameters());
List<TypeVariableName> typeVariables = iface.getTypeParameters().stream().map(TypeVariableName::get)
.collect(Collectors.toList());
MethodSpec methodSpec = generateArgumentList(); MethodSpec methodSpec = generateArgumentList();
TypeSpec.Builder builder = TypeSpec.classBuilder(recordClassType.name()) TypeSpec.Builder builder = TypeSpec.classBuilder(recordClassType.name()).addSuperinterface(iface.asType())
.addSuperinterface(iface.asType()) .addMethod(methodSpec).addModifiers(Modifier.PUBLIC).addAnnotation(generatedRecordInterfaceAnnotation)
.addMethod(methodSpec)
.addModifiers(Modifier.PUBLIC)
.addAnnotation(generatedRecordInterfaceAnnotation)
.addTypeVariables(typeVariables); .addTypeVariables(typeVariables);
if (metaData.addClassRetainedGenerated()) { if (metaData.addClassRetainedGenerated()) {
builder.addAnnotation(recordBuilderGeneratedAnnotation); builder.addAnnotation(recordBuilderGeneratedAnnotation);
} }
if (addRecordBuilder) { if (addRecordBuilder) {
ClassType builderClassType = ElementUtils.getClassType(packageName, getBuilderName(iface, metaData, recordClassType, metaData.suffix()) + "." + metaData.withClassName(), iface.getTypeParameters()); ClassType builderClassType = ElementUtils.getClassType(packageName,
getBuilderName(iface, metaData, recordClassType, metaData.suffix()) + "."
+ metaData.withClassName(),
iface.getTypeParameters());
builder.addAnnotation(RecordBuilder.class); builder.addAnnotation(RecordBuilder.class);
builder.addSuperinterface(builderClassType.typeName()); builder.addSuperinterface(builderClassType.typeName());
if (fromTemplate) { if (fromTemplate) {
@@ -112,30 +115,29 @@ class InternalRecordInterfaceProcessor {
// javapoet does yet support records - so a class was created and we can reshape it // javapoet does yet support records - so a class was created and we can reshape it
// The class will look something like this: // The class will look something like this:
/* /*
// Auto generated by io.soabase.recordbuilder.core.RecordBuilder: https://github.com/Randgalt/record-builder * // Auto generated by io.soabase.recordbuilder.core.RecordBuilder: https://github.com/Randgalt/record-builder
package io.soabase.recordbuilder.test; * package io.soabase.recordbuilder.test;
*
import io.soabase.recordbuilder.core.RecordBuilder; * import io.soabase.recordbuilder.core.RecordBuilder; import javax.annotation.processing.Generated;
import javax.annotation.processing.Generated; *
* @Generated("io.soabase.recordbuilder.core.RecordInterface")
@Generated("io.soabase.recordbuilder.core.RecordInterface") *
@RecordBuilder * @RecordBuilder public class MyRecord implements MyInterface { void __FAKE__(String name, int age) { } }
public class MyRecord implements MyInterface { */
void __FAKE__(String name, int age) { Pattern pattern = Pattern.compile("(.*)(implements.*)(\\{)(.*" + FAKE_METHOD_NAME + ")(\\(.*\\))(.*)",
} Pattern.MULTILINE | Pattern.DOTALL);
}
*/
Pattern pattern = Pattern.compile("(.*)(implements.*)(\\{)(.*" + FAKE_METHOD_NAME + ")(\\(.*\\))(.*)", Pattern.MULTILINE | Pattern.DOTALL);
Matcher matcher = pattern.matcher(classSource); Matcher matcher = pattern.matcher(classSource);
if (!matcher.find() || matcher.groupCount() != 6) { if (!matcher.find() || matcher.groupCount() != 6) {
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Internal error generating record. Group count: " + matcher.groupCount(), iface); processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,
"Internal error generating record. Group count: " + matcher.groupCount(), iface);
} }
String declaration = matcher.group(1).trim().replace("class", "record"); String declaration = matcher.group(1).trim().replace("class", "record");
String implementsSection = matcher.group(2).trim(); String implementsSection = matcher.group(2).trim();
String argumentList = matcher.group(5).trim(); String argumentList = matcher.group(5).trim();
StringBuilder fixedRecord = new StringBuilder(declaration).append(argumentList).append(' ').append(implementsSection).append(" {"); StringBuilder fixedRecord = new StringBuilder(declaration).append(argumentList).append(' ')
.append(implementsSection).append(" {");
alternateMethods.forEach(method -> fixedRecord.append('\n').append(method)); alternateMethods.forEach(method -> fixedRecord.append('\n').append(method));
fixedRecord.append('}'); fixedRecord.append('}');
return fixedRecord.toString(); return fixedRecord.toString();
@@ -145,27 +147,23 @@ class InternalRecordInterfaceProcessor {
MethodSpec.Builder builder = MethodSpec.methodBuilder(FAKE_METHOD_NAME); MethodSpec.Builder builder = MethodSpec.methodBuilder(FAKE_METHOD_NAME);
recordComponents.forEach(component -> { recordComponents.forEach(component -> {
String name = component.alternateName.orElseGet(() -> component.element.getSimpleName().toString()); String name = component.alternateName.orElseGet(() -> component.element.getSimpleName().toString());
ParameterSpec parameterSpec = ParameterSpec.builder(ClassName.get(component.element.getReturnType()), name).build(); ParameterSpec parameterSpec = ParameterSpec.builder(ClassName.get(component.element.getReturnType()), name)
builder.addTypeVariables(component.element.getTypeParameters().stream().map(TypeVariableName::get).collect(Collectors.toList())); .build();
builder.addTypeVariables(component.element.getTypeParameters().stream().map(TypeVariableName::get)
.collect(Collectors.toList()));
builder.addParameter(parameterSpec); builder.addParameter(parameterSpec);
}); });
return builder.build(); return builder.build();
} }
private List<String> buildAlternateMethods(List<Component> recordComponents) { private List<String> buildAlternateMethods(List<Component> recordComponents) {
return recordComponents.stream() return recordComponents.stream().filter(component -> component.alternateName.isPresent()).map(component -> {
.filter(component -> component.alternateName.isPresent()) var method = MethodSpec.methodBuilder(component.element.getSimpleName().toString())
.map(component -> { .addAnnotation(Override.class).addAnnotation(generatedRecordInterfaceAnnotation)
var method = MethodSpec.methodBuilder(component.element.getSimpleName().toString()) .returns(ClassName.get(component.element.getReturnType())).addModifiers(Modifier.PUBLIC)
.addAnnotation(Override.class) .addCode("return $L();", component.alternateName.get()).build();
.addAnnotation(generatedRecordInterfaceAnnotation) return method.toString();
.returns(ClassName.get(component.element.getReturnType())) }).collect(Collectors.toList());
.addModifiers(Modifier.PUBLIC)
.addCode("return $L();", component.alternateName.get())
.build();
return method.toString();
})
.collect(Collectors.toList());
} }
private List<Component> getRecordComponents(TypeElement iface) { private List<Component> getRecordComponents(TypeElement iface) {
@@ -173,7 +171,8 @@ class InternalRecordInterfaceProcessor {
try { try {
getRecordComponents(iface, components, new HashSet<>(), new HashSet<>()); getRecordComponents(iface, components, new HashSet<>(), new HashSet<>());
if (components.isEmpty()) { if (components.isEmpty()) {
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Annotated interface has no component methods", iface); processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,
"Annotated interface has no component methods", iface);
} }
} catch (IllegalInterface e) { } catch (IllegalInterface e) {
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.getMessage(), iface); processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.getMessage(), iface);
@@ -189,29 +188,32 @@ class InternalRecordInterfaceProcessor {
} }
private void getRecordComponents(TypeElement iface, Collection<Component> components, Set<String> visitedSet, Set<String> usedNames) { private void getRecordComponents(TypeElement iface, Collection<Component> components, Set<String> visitedSet,
Set<String> usedNames) {
if (!visitedSet.add(iface.getQualifiedName().toString())) { if (!visitedSet.add(iface.getQualifiedName().toString())) {
return; return;
} }
iface.getEnclosedElements().stream() iface.getEnclosedElements().stream()
.filter(element -> (element.getKind() == ElementKind.METHOD) && !(element.getModifiers().contains(Modifier.STATIC))) .filter(element -> (element.getKind() == ElementKind.METHOD)
.map(element -> ((ExecutableElement) element)) && !(element.getModifiers().contains(Modifier.STATIC)))
.filter(element -> { .map(element -> ((ExecutableElement) element)).filter(element -> {
if (element.isDefault()) { if (element.isDefault()) {
return element.getAnnotation(IgnoreDefaultMethod.class) == null; return element.getAnnotation(IgnoreDefaultMethod.class) == null;
} }
return true; return true;
}) }).peek(element -> {
.peek(element -> {
if (!element.getParameters().isEmpty() || element.getReturnType().getKind() == TypeKind.VOID) { if (!element.getParameters().isEmpty() || element.getReturnType().getKind() == TypeKind.VOID) {
throw new IllegalInterface(String.format("Non-static, non-default methods must take no arguments and must return a value. Bad method: %s.%s()", iface.getSimpleName(), element.getSimpleName())); throw new IllegalInterface(String.format(
"Non-static, non-default methods must take no arguments and must return a value. Bad method: %s.%s()",
iface.getSimpleName(), element.getSimpleName()));
} }
if (!element.getTypeParameters().isEmpty()) { if (!element.getTypeParameters().isEmpty()) {
throw new IllegalInterface(String.format("Interface methods cannot have type parameters. Bad method: %s.%s()", iface.getSimpleName(), element.getSimpleName())); throw new IllegalInterface(
String.format("Interface methods cannot have type parameters. Bad method: %s.%s()",
iface.getSimpleName(), element.getSimpleName()));
} }
}) }).filter(element -> usedNames.add(element.getSimpleName().toString()))
.filter(element -> usedNames.add(element.getSimpleName().toString()))
.map(element -> new Component(element, stripBeanPrefix(element.getSimpleName().toString()))) .map(element -> new Component(element, stripBeanPrefix(element.getSimpleName().toString())))
.collect(Collectors.toCollection(() -> components)); .collect(Collectors.toCollection(() -> components));
iface.getInterfaces().forEach(parentIface -> { iface.getInterfaces().forEach(parentIface -> {
@@ -221,10 +223,8 @@ class InternalRecordInterfaceProcessor {
} }
private Optional<String> stripBeanPrefix(String name) { private Optional<String> stripBeanPrefix(String name) {
return javaBeanPrefixes.stream() return javaBeanPrefixes.stream().filter(prefix -> name.startsWith(prefix) && (name.length() > prefix.length()))
.filter(prefix -> name.startsWith(prefix) && (name.length() > prefix.length())) .findFirst().map(prefix -> {
.findFirst()
.map(prefix -> {
var stripped = name.substring(prefix.length()); var stripped = name.substring(prefix.length());
return Character.toLowerCase(stripped.charAt(0)) + stripped.substring(1); return Character.toLowerCase(stripped.charAt(0)) + stripped.substring(1);
}); });

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -43,8 +43,7 @@ public record OptionalType(TypeName typeName, TypeName valueType) {
if (!(component.typeName() instanceof ParameterizedTypeName parameterizedType)) { if (!(component.typeName() instanceof ParameterizedTypeName parameterizedType)) {
return Optional.of(new OptionalType(optionalType, TypeName.get(Object.class))); return Optional.of(new OptionalType(optionalType, TypeName.get(Object.class)));
} }
final TypeName containingType = parameterizedType.typeArguments.isEmpty() final TypeName containingType = parameterizedType.typeArguments.isEmpty() ? TypeName.get(Object.class)
? TypeName.get(Object.class)
: parameterizedType.typeArguments.get(0); : parameterizedType.typeArguments.get(0);
return Optional.of(new OptionalType(optionalType, containingType)); return Optional.of(new OptionalType(optionalType, containingType));
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -25,35 +25,36 @@ class RecordBuilderOptions {
private static final Map<String, Object> defaultValues = buildDefaultValues(); private static final Map<String, Object> defaultValues = buildDefaultValues();
static RecordBuilder.Options build(Map<String, String> options) { static RecordBuilder.Options build(Map<String, String> options) {
return (RecordBuilder.Options)Proxy.newProxyInstance(RecordBuilderOptions.class.getClassLoader(), new Class[]{RecordBuilder.Options.class}, (proxy, method, args) -> { return (RecordBuilder.Options) Proxy.newProxyInstance(RecordBuilderOptions.class.getClassLoader(),
var name = method.getName(); new Class[] { RecordBuilder.Options.class }, (proxy, method, args) -> {
var defaultValue = defaultValues.get(name); var name = method.getName();
var option = options.get(name); var defaultValue = defaultValues.get(name);
if (option != null) { var option = options.get(name);
if (defaultValue instanceof String) { if (option != null) {
return option; if (defaultValue instanceof String) {
} return option;
if (defaultValue instanceof Boolean) { }
return Boolean.parseBoolean(option); if (defaultValue instanceof Boolean) {
} return Boolean.parseBoolean(option);
if (defaultValue instanceof Integer) { }
return Integer.parseInt(option); if (defaultValue instanceof Integer) {
} return Integer.parseInt(option);
if (defaultValue instanceof Long) { }
return Long.parseLong(option); if (defaultValue instanceof Long) {
} return Long.parseLong(option);
if (defaultValue instanceof Double) { }
return Double.parseDouble(option); if (defaultValue instanceof Double) {
} return Double.parseDouble(option);
throw new IllegalArgumentException("Unhandled option type: " + defaultValue.getClass()); }
} throw new IllegalArgumentException("Unhandled option type: " + defaultValue.getClass());
return defaultValue; }
}); return defaultValue;
});
} }
private static Map<String, Object> buildDefaultValues() { private static Map<String, Object> buildDefaultValues() {
var workMap = new HashMap<String, Object>(); var workMap = new HashMap<String, Object>();
for ( Method method : RecordBuilder.Options.class.getDeclaredMethods()) { for (Method method : RecordBuilder.Options.class.getDeclaredMethods()) {
workMap.put(method.getName(), method.getDefaultValue()); workMap.put(method.getName(), method.getDefaultValue());
} }
workMap.put("toString", "Generated RecordBuilder.Options"); workMap.put("toString", "Generated RecordBuilder.Options");

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -38,20 +38,23 @@ import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.function.Function; import java.util.function.Function;
public class RecordBuilderProcessor public class RecordBuilderProcessor extends AbstractProcessor {
extends AbstractProcessor {
private static final String RECORD_BUILDER = RecordBuilder.class.getName(); private static final String RECORD_BUILDER = RecordBuilder.class.getName();
private static final String RECORD_BUILDER_INCLUDE = RecordBuilder.Include.class.getName().replace('$', '.'); private static final String RECORD_BUILDER_INCLUDE = RecordBuilder.Include.class.getName().replace('$', '.');
private static final String RECORD_INTERFACE = RecordInterface.class.getName(); private static final String RECORD_INTERFACE = RecordInterface.class.getName();
private static final String RECORD_INTERFACE_INCLUDE = RecordInterface.Include.class.getName().replace('$', '.'); private static final String RECORD_INTERFACE_INCLUDE = RecordInterface.Include.class.getName().replace('$', '.');
static final AnnotationSpec generatedRecordBuilderAnnotation = AnnotationSpec.builder(Generated.class).addMember("value", "$S", RecordBuilder.class.getName()).build(); static final AnnotationSpec generatedRecordBuilderAnnotation = AnnotationSpec.builder(Generated.class)
static final AnnotationSpec generatedRecordInterfaceAnnotation = AnnotationSpec.builder(Generated.class).addMember("value", "$S", RecordInterface.class.getName()).build(); .addMember("value", "$S", RecordBuilder.class.getName()).build();
static final AnnotationSpec recordBuilderGeneratedAnnotation = AnnotationSpec.builder(RecordBuilderGenerated.class).build(); static final AnnotationSpec generatedRecordInterfaceAnnotation = AnnotationSpec.builder(Generated.class)
.addMember("value", "$S", RecordInterface.class.getName()).build();
static final AnnotationSpec recordBuilderGeneratedAnnotation = AnnotationSpec.builder(RecordBuilderGenerated.class)
.build();
@Override @Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
annotations.forEach(annotation -> roundEnv.getElementsAnnotatedWith(annotation).forEach(element -> process(annotation, element))); annotations.forEach(annotation -> roundEnv.getElementsAnnotatedWith(annotation)
.forEach(element -> process(annotation, element)));
return false; return false;
} }
@@ -62,7 +65,7 @@ public class RecordBuilderProcessor
@Override @Override
public SourceVersion getSupportedSourceVersion() { public SourceVersion getSupportedSourceVersion() {
// we don't directly return RELEASE_14 as that may // we don't directly return RELEASE_14 as that may
// not exist in prior releases // not exist in prior releases
// if we're running on an older release, returning latest() // if we're running on an older release, returning latest()
// is fine as we won't encounter any records anyway // is fine as we won't encounter any records anyway
@@ -76,14 +79,16 @@ public class RecordBuilderProcessor
processRecordBuilder(typeElement, getMetaData(typeElement), Optional.empty()); processRecordBuilder(typeElement, getMetaData(typeElement), Optional.empty());
} else if (annotationClass.equals(RECORD_INTERFACE)) { } else if (annotationClass.equals(RECORD_INTERFACE)) {
var typeElement = (TypeElement) element; var typeElement = (TypeElement) element;
processRecordInterface(typeElement, element.getAnnotation(RecordInterface.class).addRecordBuilder(), getMetaData(typeElement), Optional.empty(), false); processRecordInterface(typeElement, element.getAnnotation(RecordInterface.class).addRecordBuilder(),
getMetaData(typeElement), Optional.empty(), false);
} else if (annotationClass.equals(RECORD_BUILDER_INCLUDE) || annotationClass.equals(RECORD_INTERFACE_INCLUDE)) { } else if (annotationClass.equals(RECORD_BUILDER_INCLUDE) || annotationClass.equals(RECORD_INTERFACE_INCLUDE)) {
processIncludes(element, getMetaData(element), annotationClass); processIncludes(element, getMetaData(element), annotationClass);
} else { } else {
var recordBuilderTemplate = annotation.getAnnotation(RecordBuilder.Template.class); var recordBuilderTemplate = annotation.getAnnotation(RecordBuilder.Template.class);
if (recordBuilderTemplate != null) { if (recordBuilderTemplate != null) {
if (recordBuilderTemplate.asRecordInterface()) { if (recordBuilderTemplate.asRecordInterface()) {
processRecordInterface((TypeElement) element, true, recordBuilderTemplate.options(), Optional.empty(), true); processRecordInterface((TypeElement) element, true, recordBuilderTemplate.options(),
Optional.empty(), true);
} else { } else {
processRecordBuilder((TypeElement) element, recordBuilderTemplate.options(), Optional.empty()); processRecordBuilder((TypeElement) element, recordBuilderTemplate.options(), Optional.empty());
} }
@@ -93,27 +98,34 @@ public class RecordBuilderProcessor
private RecordBuilder.Options getMetaData(Element element) { private RecordBuilder.Options getMetaData(Element element) {
var recordSpecificMetaData = element.getAnnotation(RecordBuilder.Options.class); var recordSpecificMetaData = element.getAnnotation(RecordBuilder.Options.class);
return (recordSpecificMetaData != null) ? recordSpecificMetaData : RecordBuilderOptions.build(processingEnv.getOptions()); return (recordSpecificMetaData != null) ? recordSpecificMetaData
: RecordBuilderOptions.build(processingEnv.getOptions());
} }
private void processIncludes(Element element, RecordBuilder.Options metaData, String annotationClass) { private void processIncludes(Element element, RecordBuilder.Options metaData, String annotationClass) {
var isRecordBuilderInclude = annotationClass.equals(RECORD_BUILDER_INCLUDE); var isRecordBuilderInclude = annotationClass.equals(RECORD_BUILDER_INCLUDE);
var annotationMirrorOpt = ElementUtils.findAnnotationMirror(processingEnv, element, annotationClass); var annotationMirrorOpt = ElementUtils.findAnnotationMirror(processingEnv, element, annotationClass);
if (annotationMirrorOpt.isEmpty()) { if (annotationMirrorOpt.isEmpty()) {
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Could not get annotation mirror for: " + annotationClass, element); processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,
"Could not get annotation mirror for: " + annotationClass, element);
} else { } else {
var includeHelper = new IncludeHelper(processingEnv, element, annotationMirrorOpt.get(), isRecordBuilderInclude); var includeHelper = new IncludeHelper(processingEnv, element, annotationMirrorOpt.get(),
isRecordBuilderInclude);
if (includeHelper.isValid()) { if (includeHelper.isValid()) {
var packagePattern = ElementUtils.getStringAttribute(ElementUtils.getAnnotationValue(includeHelper.getAnnotationValues(), "packagePattern").orElse(null), "*"); var packagePattern = ElementUtils.getStringAttribute(ElementUtils
.getAnnotationValue(includeHelper.getAnnotationValues(), "packagePattern").orElse(null), "*");
for (var typeElement : includeHelper.getClassTypeElements()) { for (var typeElement : includeHelper.getClassTypeElements()) {
var packageName = buildPackageName(packagePattern, element, typeElement); var packageName = buildPackageName(packagePattern, element, typeElement);
if (packageName != null) { if (packageName != null) {
if (isRecordBuilderInclude) { if (isRecordBuilderInclude) {
processRecordBuilder(typeElement, metaData, Optional.of(packageName)); processRecordBuilder(typeElement, metaData, Optional.of(packageName));
} else { } else {
var addRecordBuilderOpt = ElementUtils.getAnnotationValue(includeHelper.getAnnotationValues(), "addRecordBuilder"); var addRecordBuilderOpt = ElementUtils
var addRecordBuilder = addRecordBuilderOpt.map(ElementUtils::getBooleanAttribute).orElse(true); .getAnnotationValue(includeHelper.getAnnotationValues(), "addRecordBuilder");
processRecordInterface(typeElement, addRecordBuilder, metaData, Optional.of(packageName), false); var addRecordBuilder = addRecordBuilderOpt.map(ElementUtils::getBooleanAttribute)
.orElse(true);
processRecordInterface(typeElement, addRecordBuilder, metaData, Optional.of(packageName),
false);
} }
} }
} }
@@ -130,7 +142,8 @@ public class RecordBuilderProcessor
if (builderElement instanceof PackageElement) { if (builderElement instanceof PackageElement) {
return replaced.replace("@", ((PackageElement) builderElement).getQualifiedName().toString()); return replaced.replace("@", ((PackageElement) builderElement).getQualifiedName().toString());
} }
return replaced.replace("@", ((PackageElement) builderElement.getEnclosingElement()).getQualifiedName().toString()); return replaced.replace("@",
((PackageElement) builderElement.getEnclosingElement()).getQualifiedName().toString());
} }
private PackageElement findPackageElement(Element actualElement, Element includedClass) { private PackageElement findPackageElement(Element actualElement, Element includedClass) {
@@ -144,37 +157,46 @@ public class RecordBuilderProcessor
return findPackageElement(actualElement, includedClass.getEnclosingElement()); return findPackageElement(actualElement, includedClass.getEnclosingElement());
} }
private void processRecordInterface(TypeElement element, boolean addRecordBuilder, RecordBuilder.Options metaData, Optional<String> packageName, boolean fromTemplate) { private void processRecordInterface(TypeElement element, boolean addRecordBuilder, RecordBuilder.Options metaData,
Optional<String> packageName, boolean fromTemplate) {
if (!element.getKind().isInterface()) { if (!element.getKind().isInterface()) {
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "RecordInterface only valid for interfaces.", element); processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,
"RecordInterface only valid for interfaces.", element);
return; return;
} }
var internalProcessor = new InternalRecordInterfaceProcessor(processingEnv, element, addRecordBuilder, metaData, packageName, fromTemplate); var internalProcessor = new InternalRecordInterfaceProcessor(processingEnv, element, addRecordBuilder, metaData,
packageName, fromTemplate);
if (!internalProcessor.isValid()) { if (!internalProcessor.isValid()) {
return; return;
} }
writeRecordInterfaceJavaFile(element, internalProcessor.packageName(), internalProcessor.recordClassType(), internalProcessor.recordType(), metaData, internalProcessor::toRecord); writeRecordInterfaceJavaFile(element, internalProcessor.packageName(), internalProcessor.recordClassType(),
internalProcessor.recordType(), metaData, internalProcessor::toRecord);
} }
private void processRecordBuilder(TypeElement record, RecordBuilder.Options metaData, Optional<String> packageName) { private void processRecordBuilder(TypeElement record, RecordBuilder.Options metaData,
Optional<String> packageName) {
// we use string based name comparison for the element kind, // we use string based name comparison for the element kind,
// as the ElementKind.RECORD enum doesn't exist on JRE releases // as the ElementKind.RECORD enum doesn't exist on JRE releases
// older than Java 14, and we don't want to throw unexpected // older than Java 14, and we don't want to throw unexpected
// NoSuchFieldErrors // NoSuchFieldErrors
if (!"RECORD".equals(record.getKind().name())) { if (!"RECORD".equals(record.getKind().name())) {
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "RecordBuilder only valid for records.", record); processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "RecordBuilder only valid for records.",
record);
return; return;
} }
var internalProcessor = new InternalRecordBuilderProcessor(processingEnv, record, metaData, packageName); var internalProcessor = new InternalRecordBuilderProcessor(processingEnv, record, metaData, packageName);
writeRecordBuilderJavaFile(record, internalProcessor.packageName(), internalProcessor.builderClassType(), internalProcessor.builderType(), metaData); writeRecordBuilderJavaFile(record, internalProcessor.packageName(), internalProcessor.builderClassType(),
internalProcessor.builderType(), metaData);
} }
private void writeRecordBuilderJavaFile(TypeElement record, String packageName, ClassType builderClassType, TypeSpec builderType, RecordBuilder.Options metaData) { private void writeRecordBuilderJavaFile(TypeElement record, String packageName, ClassType builderClassType,
TypeSpec builderType, RecordBuilder.Options metaData) {
// produces the Java file // produces the Java file
JavaFile javaFile = javaFileBuilder(packageName, builderType, metaData); JavaFile javaFile = javaFileBuilder(packageName, builderType, metaData);
Filer filer = processingEnv.getFiler(); Filer filer = processingEnv.getFiler();
try { try {
String fullyQualifiedName = packageName.isEmpty() ? builderClassType.name() : (packageName + "." + builderClassType.name()); String fullyQualifiedName = packageName.isEmpty() ? builderClassType.name()
: (packageName + "." + builderClassType.name());
JavaFileObject sourceFile = filer.createSourceFile(fullyQualifiedName); JavaFileObject sourceFile = filer.createSourceFile(fullyQualifiedName);
try (Writer writer = sourceFile.openWriter()) { try (Writer writer = sourceFile.openWriter()) {
javaFile.writeTo(writer); javaFile.writeTo(writer);
@@ -184,7 +206,8 @@ public class RecordBuilderProcessor
} }
} }
private void writeRecordInterfaceJavaFile(TypeElement element, String packageName, ClassType classType, TypeSpec type, RecordBuilder.Options metaData, Function<String, String> toRecordProc) { private void writeRecordInterfaceJavaFile(TypeElement element, String packageName, ClassType classType,
TypeSpec type, RecordBuilder.Options metaData, Function<String, String> toRecordProc) {
JavaFile javaFile = javaFileBuilder(packageName, type, metaData); JavaFile javaFile = javaFileBuilder(packageName, type, metaData);
String classSourceCode = javaFile.toString(); String classSourceCode = javaFile.toString();
@@ -193,7 +216,8 @@ public class RecordBuilderProcessor
Filer filer = processingEnv.getFiler(); Filer filer = processingEnv.getFiler();
try { try {
String fullyQualifiedName = packageName.isEmpty() ? classType.name() : (packageName + "." + classType.name()); String fullyQualifiedName = packageName.isEmpty() ? classType.name()
: (packageName + "." + classType.name());
JavaFileObject sourceFile = filer.createSourceFile(fullyQualifiedName); JavaFileObject sourceFile = filer.createSourceFile(fullyQualifiedName);
try (Writer writer = sourceFile.openWriter()) { try (Writer writer = sourceFile.openWriter()) {
writer.write(recordSourceCode); writer.write(recordSourceCode);
@@ -204,7 +228,8 @@ public class RecordBuilderProcessor
} }
private JavaFile javaFileBuilder(String packageName, TypeSpec type, RecordBuilder.Options metaData) { private JavaFile javaFileBuilder(String packageName, TypeSpec type, RecordBuilder.Options metaData) {
var javaFileBuilder = JavaFile.builder(packageName, type).skipJavaLangImports(true).indent(metaData.fileIndent()); var javaFileBuilder = JavaFile.builder(packageName, type).skipJavaLangImports(true)
.indent(metaData.fileIndent());
var comment = metaData.fileComment(); var comment = metaData.fileComment();
if ((comment != null) && !comment.isEmpty()) { if ((comment != null) && !comment.isEmpty()) {
javaFileBuilder.addFileComment(comment); javaFileBuilder.addFileComment(comment);

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -25,7 +25,9 @@ public class RecordClassType extends ClassType {
private final List<? extends AnnotationMirror> accessorAnnotations; private final List<? extends AnnotationMirror> accessorAnnotations;
private final List<? extends AnnotationMirror> canonicalConstructorAnnotations; private final List<? extends AnnotationMirror> canonicalConstructorAnnotations;
public RecordClassType(TypeName typeName, TypeName rawTypeName, String name, List<? extends AnnotationMirror> accessorAnnotations, List<? extends AnnotationMirror> canonicalConstructorAnnotations) { public RecordClassType(TypeName typeName, TypeName rawTypeName, String name,
List<? extends AnnotationMirror> accessorAnnotations,
List<? extends AnnotationMirror> canonicalConstructorAnnotations) {
super(typeName, name); super(typeName, name);
this.rawTypeName = rawTypeName; this.rawTypeName = rawTypeName;
this.accessorAnnotations = accessorAnnotations; this.accessorAnnotations = accessorAnnotations;

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- <!--
Copyright 2019 Jordan Zimmerman Copyright 2019 The original author or authors
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -18,11 +18,7 @@ package io.soabase.recordbuilder.test;
import io.soabase.recordbuilder.core.RecordBuilder; import io.soabase.recordbuilder.core.RecordBuilder;
import io.soabase.recordbuilder.core.RecordInterface; import io.soabase.recordbuilder.core.RecordInterface;
@RecordInterface.Include({ @RecordInterface.Include({ Thingy.class })
Thingy.class @RecordBuilder.Include({ Nested.NestedRecord.class })
})
@RecordBuilder.Include({
Nested.NestedRecord.class
})
public class Builder { public class Builder {
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -24,11 +24,7 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
@RecordBuilder @RecordBuilder
@RecordBuilder.Options( @RecordBuilder.Options(addSingleItemCollectionBuilders = true, useImmutableCollections = true, mutableListClassName = "PersonalizedMutableList")
addSingleItemCollectionBuilders = true,
useImmutableCollections = true,
mutableListClassName = "PersonalizedMutableList"
)
public record CollectionCopying<T>(List<String> list, Set<T> set, Map<Instant, T> map, Collection<T> collection, public record CollectionCopying<T>(List<String> list, Set<T> set, Map<Instant, T> map, Collection<T> collection,
int count) implements CollectionCopyingBuilder.With<T> { int count) implements CollectionCopyingBuilder.With<T> {
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -25,10 +25,11 @@ import java.util.Set;
@RecordBuilder @RecordBuilder
@RecordBuilder.Options(useImmutableCollections = true, addFunctionalMethodsToWith = true) @RecordBuilder.Options(useImmutableCollections = true, addFunctionalMethodsToWith = true)
public record CollectionRecord<T, X extends Point>(List<T> l, Set<T> s, Map<T, X> m, public record CollectionRecord<T, X extends Point>(List<T> l, Set<T> s, Map<T, X> m, Collection<X> c)
Collection<X> c) implements CollectionRecordBuilder.With<T, X> { implements CollectionRecordBuilder.With<T, X> {
public static void main(String[] args) { public static void main(String[] args) {
var r = new CollectionRecord<>(List.of("hey"), Set.of("there"), Map.of("one", new Point(10, 20)), Set.of(new Point(30, 40))); var r = new CollectionRecord<>(List.of("hey"), Set.of("there"), Map.of("one", new Point(10, 20)),
Set.of(new Point(30, 40)));
Instant now = r.map((l1, s1, m1, c1) -> Instant.now()); Instant now = r.map((l1, s1, m1, c1) -> Instant.now());
r.accept((l1, s1, m1, c1) -> { r.accept((l1, s1, m1, c1) -> {
}); });

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -24,5 +24,6 @@ import java.util.Set;
@RecordBuilder @RecordBuilder
@RecordBuilder.Options(useImmutableCollections = true) @RecordBuilder.Options(useImmutableCollections = true)
public record CollectionRecordConflicts(List<String> __list, Set<String> __set, Map<String, String> __map, Collection<String> __collection) implements CollectionRecordConflictsBuilder.With { public record CollectionRecordConflicts(List<String> __list, Set<String> __set, Map<String, String> __map,
Collection<String> __collection) implements CollectionRecordConflictsBuilder.With {
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -20,10 +20,6 @@ import io.soabase.recordbuilder.core.RecordBuilder;
import io.soabase.recordbuilder.test.CustomMethodNamesBuilder.Bean; import io.soabase.recordbuilder.test.CustomMethodNamesBuilder.Bean;
@RecordBuilder @RecordBuilder
@RecordBuilder.Options( @RecordBuilder.Options(setterPrefix = "set", getterPrefix = "get", booleanPrefix = "is", beanClassName = "Bean")
setterPrefix = "set", getterPrefix = "get", booleanPrefix = "is", beanClassName = "Bean") public record CustomMethodNames(int theValue, List<Integer> theList, boolean theBoolean) implements Bean {
public record CustomMethodNames(
int theValue,
List<Integer> theList,
boolean theBoolean) implements Bean {
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -21,10 +21,8 @@ import javax.lang.model.type.ErrorType;
import java.util.List; import java.util.List;
@RecordBuilder @RecordBuilder
public record ExceptionDetails( public record ExceptionDetails(String internalMessage, String endUserMessage, String httpStatus, ErrorType errorType,
String internalMessage, String endUserMessage, String httpStatus, List<String> jsonProblems, Throwable cause) {
ErrorType errorType, List<String> jsonProblems, Throwable cause
) {
@Override @Override
public List<String> jsonProblems() { public List<String> jsonProblems() {
if (jsonProblems == null) { if (jsonProblems == null) {

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -22,5 +22,6 @@ import java.util.List;
import java.util.Map; import java.util.Map;
@RecordBuilderFull @RecordBuilderFull
public record FullRecord(@NotNull List<Number> numbers, @NotNull Map<Number, FullRecord> fullRecords, @NotNull String justAString) { public record FullRecord(@NotNull List<Number> numbers, @NotNull Map<Number, FullRecord> fullRecords,
@NotNull String justAString) {
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -20,5 +20,6 @@ import io.soabase.recordbuilder.core.RecordBuilder;
@RecordBuilder.Options(prefixEnclosingClassNames = false) @RecordBuilder.Options(prefixEnclosingClassNames = false)
@RecordBuilder.Include(IncludeWithOption.Hey.class) @RecordBuilder.Include(IncludeWithOption.Hey.class)
public class IncludeWithOption { public class IncludeWithOption {
public static record Hey(String s){} public static record Hey(String s) {
}
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -17,10 +17,6 @@ package io.soabase.recordbuilder.test;
import io.soabase.recordbuilder.core.RecordBuilder; import io.soabase.recordbuilder.core.RecordBuilder;
@RecordBuilder.Template(options = @RecordBuilder.Options( @RecordBuilder.Template(options = @RecordBuilder.Options(fileComment = "This is a test", withClassName = "Com"), asRecordInterface = true)
fileComment = "This is a test",
withClassName = "Com"),
asRecordInterface = true
)
public @interface MyInterfaceTemplate { public @interface MyInterfaceTemplate {
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -17,10 +17,6 @@ package io.soabase.recordbuilder.test;
import io.soabase.recordbuilder.core.RecordBuilder; import io.soabase.recordbuilder.core.RecordBuilder;
@RecordBuilder.Template(options = @RecordBuilder.Options( @RecordBuilder.Template(options = @RecordBuilder.Options(fileComment = "This is a test", withClassName = "Com"))
fileComment = "This is a test", public @interface MyTemplate {
withClassName = "Com"
))
public @interface MyTemplate
{
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -16,5 +16,6 @@
package io.soabase.recordbuilder.test; package io.soabase.recordbuilder.test;
public class Nested { public class Nested {
record NestedRecord(int x, int y){} record NestedRecord(int x, int y) {
}
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -20,17 +20,14 @@ import io.soabase.recordbuilder.core.RecordBuilder;
/** /**
* Copyright 2019 Jordan Zimmerman * Copyright 2019 Jordan Zimmerman
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* you may not use this file except in compliance with the License. * the License. You may obtain a copy of the License at
* You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* distributed under the License is distributed on an "AS IS" BASIS, * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * specific language governing permissions and limitations under the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
@RecordBuilder.Options(addStaticBuilder = false) @RecordBuilder.Options(addStaticBuilder = false)
@RecordBuilder @RecordBuilder

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -15,4 +15,5 @@
*/ */
package io.soabase.recordbuilder.test; package io.soabase.recordbuilder.test;
public record Pair<T, U>(T t, U u) {} public record Pair<T, U>(T t, U u) {
}

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -15,4 +15,5 @@
*/ */
package io.soabase.recordbuilder.test; package io.soabase.recordbuilder.test;
public record Point(int x, int y) {} public record Point(int x, int y) {
}

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -18,4 +18,5 @@ package io.soabase.recordbuilder.test;
import io.soabase.recordbuilder.core.RecordBuilder; import io.soabase.recordbuilder.core.RecordBuilder;
@RecordBuilder @RecordBuilder
public record RecordWithAnR(int r, String b) {} public record RecordWithAnR(int r, String b) {
}

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -26,4 +26,6 @@ import java.util.OptionalLong;
@RecordBuilder.Options(emptyDefaultForOptional = true, addConcreteSettersForOptional = true) @RecordBuilder.Options(emptyDefaultForOptional = true, addConcreteSettersForOptional = true)
@RecordBuilder @RecordBuilder
public record RecordWithOptional(@NotNull Optional<String> value, Optional raw, OptionalInt i, OptionalLong l, OptionalDouble d) {} public record RecordWithOptional(@NotNull Optional<String> value, Optional raw, OptionalInt i, OptionalLong l,
OptionalDouble d) {
}

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -23,4 +23,6 @@ import io.soabase.recordbuilder.core.RecordBuilder;
@RecordBuilder.Options(emptyDefaultForOptional = true) @RecordBuilder.Options(emptyDefaultForOptional = true)
@RecordBuilder @RecordBuilder
public record RecordWithOptional2(Optional<String> value, Optional raw, OptionalInt i, OptionalLong l, OptionalDouble d) {} public record RecordWithOptional2(Optional<String> value, Optional raw, OptionalInt i, OptionalLong l,
OptionalDouble d) {
}

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -24,5 +24,6 @@ import javax.validation.constraints.NotNull;
@RecordBuilder @RecordBuilder
@RecordBuilder.Options(useValidationApi = true) @RecordBuilder.Options(useValidationApi = true)
public record RequestWithValid(@NotNull @Valid Part part) implements RequestWithValidBuilder.With { public record RequestWithValid(@NotNull @Valid Part part) implements RequestWithValidBuilder.With {
public record Part(@NotBlank String name) {} public record Part(@NotBlank String name) {
}
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -22,5 +22,6 @@ import java.util.List;
@RecordBuilder.Options(interpretNotNulls = true) @RecordBuilder.Options(interpretNotNulls = true)
@RecordBuilder @RecordBuilder
public record RequiredRecord(@NotNull String hey, @NotNull int i, @NotNull List<String> l) implements RequiredRecordBuilder.With { public record RequiredRecord(@NotNull String hey, @NotNull int i, @NotNull List<String> l)
implements RequiredRecordBuilder.With {
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -24,11 +24,7 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
@RecordBuilder @RecordBuilder
@RecordBuilder.Options( @RecordBuilder.Options(addSingleItemCollectionBuilders = true, singleItemBuilderPrefix = "add1", useImmutableCollections = true, addFunctionalMethodsToWith = true)
addSingleItemCollectionBuilders = true, public record SingleItems<T>(List<String> strings, Set<List<T>> sets, Map<Instant, T> map, Collection<T> collection)
singleItemBuilderPrefix = "add1", implements SingleItemsBuilder.With<T> {
useImmutableCollections = true,
addFunctionalMethodsToWith = true
)
public record SingleItems<T>(List<String> strings, Set<List<T>> sets, Map<Instant, T> map, Collection<T> collection) implements SingleItemsBuilder.With<T> {
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -18,8 +18,6 @@ package io.soabase.recordbuilder.test;
import io.soabase.recordbuilder.core.RecordBuilder; import io.soabase.recordbuilder.core.RecordBuilder;
@RecordBuilder @RecordBuilder
@RecordBuilder.Options( @RecordBuilder.Options(enableGetters = false, enableWither = false)
enableGetters = false, public record StrippedFeaturesRecord(int aField) {
enableWither = false }
)
public record StrippedFeaturesRecord(int aField) {}

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -18,6 +18,5 @@ package io.soabase.recordbuilder.test;
import java.time.Instant; import java.time.Instant;
@MyTemplate @MyTemplate
public record TemplateTest(String text, Instant date) implements TemplateTestBuilder.Com public record TemplateTest(String text, Instant date) implements TemplateTestBuilder.Com {
{
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -24,9 +24,8 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
@RecordBuilder @RecordBuilder
@RecordBuilder.Options( @RecordBuilder.Options(addSingleItemCollectionBuilders = true, useImmutableCollections = true)
addSingleItemCollectionBuilders = true, public record WildcardSingleItems<T>(List<? extends String> strings, Set<? extends List<? extends T>> sets,
useImmutableCollections = true Map<? extends Instant, ? extends T> map, Collection<? extends T> collection)
) implements WildcardSingleItemsBuilder.With<T> {
public record WildcardSingleItems<T>(List<? extends String> strings, Set<? extends List<? extends T>> sets, Map<? extends Instant, ? extends T> map, Collection<? extends T> collection) implements WildcardSingleItemsBuilder.With<T> {
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -17,9 +17,6 @@ package io.soabase.recordbuilder.test.includes;
import io.soabase.recordbuilder.core.RecordBuilder; import io.soabase.recordbuilder.core.RecordBuilder;
@RecordBuilder.Include( @RecordBuilder.Include(packages = "io.soabase.recordbuilder.test.includes.pack", classes = JustATest.class)
packages = "io.soabase.recordbuilder.test.includes.pack",
classes = JustATest.class
)
public class IncludeFactory { public class IncludeFactory {
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -24,5 +24,6 @@ import java.util.Map;
@RecordBuilderFull @RecordBuilderFull
@RecordBuilderGenerated @RecordBuilderGenerated
public record FullRecordForJacoco(@NotNull List<Number> numbers, @NotNull Map<Number, FullRecordForJacoco> fullRecords, @NotNull String justAString) { public record FullRecordForJacoco(@NotNull List<Number> numbers, @NotNull Map<Number, FullRecordForJacoco> fullRecords,
@NotNull String justAString) {
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
@RecordBuilder.Include(value = {Point.class, Pair.class}, packagePattern = "*.foo") @RecordBuilder.Include(value = { Point.class, Pair.class }, packagePattern = "*.foo")
@RecordInterface.Include(value = Customer.class, addRecordBuilder = false, packagePattern = "*.bar") @RecordInterface.Include(value = Customer.class, addRecordBuilder = false, packagePattern = "*.bar")
package io.soabase.recordbuilder.test; package io.soabase.recordbuilder.test;

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -19,8 +19,7 @@ import io.soabase.recordbuilder.core.RecordBuilder;
import javax.lang.model.element.Modifier; import javax.lang.model.element.Modifier;
@RecordBuilder.Options(builderClassModifiers = { Modifier.PUBLIC })
@RecordBuilder.Options(builderClassModifiers = {Modifier.PUBLIC})
@RecordBuilder @RecordBuilder
record PackagePrivateRecordWithPublicBuilder(String value) { record PackagePrivateRecordWithPublicBuilder(String value) {
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -52,30 +52,20 @@ class TestCollections {
map.put("one", Point(10, 20)); map.put("one", Point(10, 20));
var collectionAsSet = new HashSet<Point>(); var collectionAsSet = new HashSet<Point>();
collectionAsSet.add(Point(30, 40)); collectionAsSet.add(Point(30, 40));
var r = CollectionRecordBuilder.<String, Point>builder() var r = CollectionRecordBuilder.<String, Point> builder().l(list).s(set).m(map).c(collectionAsSet).build();
.l(list)
.s(set)
.m(map)
.c(collectionAsSet)
.build();
assertValues(r, list, set, map, collectionAsSet); assertValues(r, list, set, map, collectionAsSet);
assertValueChanges(r, list, set, map, collectionAsSet); assertValueChanges(r, list, set, map, collectionAsSet);
assertImmutable(r); assertImmutable(r);
var collectionAsList = new ArrayList<Point>(); var collectionAsList = new ArrayList<Point>();
var x = CollectionRecordBuilder.<String, Point>builder() var x = CollectionRecordBuilder.<String, Point> builder().l(list).s(set).m(map).c(collectionAsList).build();
.l(list)
.s(set)
.m(map)
.c(collectionAsList)
.build();
assertTrue(x.c() instanceof List); assertTrue(x.c() instanceof List);
} }
@Test @Test
void testCollectionRecordImmutableWithers() { void testCollectionRecordImmutableWithers() {
var r = CollectionRecordBuilder.<String, Point>builder().build(); var r = CollectionRecordBuilder.<String, Point> builder().build();
var list = new ArrayList<String>(); var list = new ArrayList<String>();
list.add("one"); list.add("one");
@@ -113,7 +103,8 @@ class TestCollections {
assertThrows(UnsupportedOperationException.class, () -> r.c().add(Point(1, 2))); assertThrows(UnsupportedOperationException.class, () -> r.c().add(Point(1, 2)));
} }
private void assertValueChanges(CollectionRecord<String, Point> r, ArrayList<String> list, HashSet<String> set, HashMap<String, Point> map, HashSet<Point> collectionAsSet) { private void assertValueChanges(CollectionRecord<String, Point> r, ArrayList<String> list, HashSet<String> set,
HashMap<String, Point> map, HashSet<Point> collectionAsSet) {
list.add("two"); list.add("two");
set.add("two"); set.add("two");
map.put("two", Point(50, 60)); map.put("two", Point(50, 60));
@@ -125,7 +116,8 @@ class TestCollections {
assertNotEquals(r.c(), collectionAsSet); assertNotEquals(r.c(), collectionAsSet);
} }
private void assertValues(CollectionRecord<String, Point> r, ArrayList<String> list, HashSet<String> set, HashMap<String, Point> map, HashSet<Point> collectionAsSet) { private void assertValues(CollectionRecord<String, Point> r, ArrayList<String> list, HashSet<String> set,
HashMap<String, Point> map, HashSet<Point> collectionAsSet) {
assertEquals(r.l(), list); assertEquals(r.l(), list);
assertEquals(r.s(), set); assertEquals(r.s(), set);
assertEquals(r.m(), map); assertEquals(r.m(), map);

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -24,91 +24,65 @@ import java.util.*;
public class TestImmutableCollections { public class TestImmutableCollections {
@Test @Test
public void testImmutableListNotCopiedWhenNotChanged() { public void testImmutableListNotCopiedWhenNotChanged() {
var item = CollectionCopyingBuilder.<String>builder() var item = CollectionCopyingBuilder.<String> builder().addList("a").addList("b").addList("c").build();
.addList("a")
.addList("b")
.addList("c")
.build();
Assertions.assertEquals(item.list(), List.of("a", "b", "c")); Assertions.assertEquals(item.list(), List.of("a", "b", "c"));
var oldList = item.list(); var oldList = item.list();
var copy = item.with() var copy = item.with().count(1).build();
.count(1)
.build();
Assertions.assertSame(oldList, copy.list()); Assertions.assertSame(oldList, copy.list());
var otherCopy = item.with() var otherCopy = item.with().count(2).build();
.count(2)
.build();
Assertions.assertSame(oldList, otherCopy.list()); Assertions.assertSame(oldList, otherCopy.list());
} }
@Test @Test
public void testImmutableSetNotCopiedWhenNotChanged() { public void testImmutableSetNotCopiedWhenNotChanged() {
var item = CollectionCopyingBuilder.<String>builder() var item = CollectionCopyingBuilder.<String> builder().addSet(Arrays.asList("1", "2", "3")).build();
.addSet(Arrays.asList("1", "2", "3"))
.build();
Assertions.assertEquals(item.set(), Set.of("1", "2", "3")); Assertions.assertEquals(item.set(), Set.of("1", "2", "3"));
var oldSet = item.set(); var oldSet = item.set();
var copy = item.with() var copy = item.with().count(1).build();
.count(1)
.build();
Assertions.assertSame(oldSet, copy.set()); Assertions.assertSame(oldSet, copy.set());
var otherCopy = item.with() var otherCopy = item.with().count(2).build();
.count(2)
.build();
Assertions.assertSame(oldSet, otherCopy.set()); Assertions.assertSame(oldSet, otherCopy.set());
} }
@Test @Test
public void testImmutableCollectionNotCopiedWhenNotChanged() { public void testImmutableCollectionNotCopiedWhenNotChanged() {
var item = CollectionCopyingBuilder.<String>builder() var item = CollectionCopyingBuilder.<String> builder().collection(List.of("foo", "bar", "baz")).build();
.collection(List.of("foo", "bar", "baz"))
.build();
Assertions.assertEquals(item.collection(), List.of("foo", "bar", "baz")); Assertions.assertEquals(item.collection(), List.of("foo", "bar", "baz"));
var oldCollection = item.collection(); var oldCollection = item.collection();
var copy = item.with() var copy = item.with().count(1).build();
.count(1)
.build();
Assertions.assertSame(oldCollection, copy.collection()); Assertions.assertSame(oldCollection, copy.collection());
var otherCopy = item.with() var otherCopy = item.with().count(2).build();
.count(2)
.build();
Assertions.assertSame(oldCollection, otherCopy.collection()); Assertions.assertSame(oldCollection, otherCopy.collection());
} }
@Test @Test
public void testImmutableMapNotCopiedWhenNotChanged() { public void testImmutableMapNotCopiedWhenNotChanged() {
var item = CollectionCopyingBuilder.<String>builder() var item = CollectionCopyingBuilder.<String> builder().addMap(Instant.MAX, "future")
.addMap(Instant.MAX, "future") .addMap(Instant.MIN, "before").build();
.addMap(Instant.MIN, "before")
.build();
Assertions.assertEquals(item.map(), Map.of(Instant.MAX, "future", Instant.MIN, "before")); Assertions.assertEquals(item.map(), Map.of(Instant.MAX, "future", Instant.MIN, "before"));
var oldMap = item.map(); var oldMap = item.map();
var copy = item.with() var copy = item.with().count(1).build();
.count(1)
.build();
Assertions.assertSame(oldMap, copy.map()); Assertions.assertSame(oldMap, copy.map());
var otherCopy = item.with() var otherCopy = item.with().count(2).build();
.count(2)
.build();
Assertions.assertSame(oldMap, otherCopy.map()); Assertions.assertSame(oldMap, otherCopy.map());
} }
@@ -116,9 +90,7 @@ public class TestImmutableCollections {
@Test @Test
void testSourceListNotModified() { void testSourceListNotModified() {
var item = new CollectionCopying<>(new ArrayList<>(), null, null, null, 0); var item = new CollectionCopying<>(new ArrayList<>(), null, null, null, 0);
var modifiedItem = CollectionCopyingBuilder.builder(item) var modifiedItem = CollectionCopyingBuilder.builder(item).addList("a").build();
.addList("a")
.build();
Assertions.assertEquals(modifiedItem.list(), List.of("a")); Assertions.assertEquals(modifiedItem.list(), List.of("a"));
Assertions.assertTrue(item.list().isEmpty()); Assertions.assertTrue(item.list().isEmpty());
@@ -127,9 +99,7 @@ public class TestImmutableCollections {
@Test @Test
void testSourceSetNotModified() { void testSourceSetNotModified() {
var item = new CollectionCopying<>(null, new HashSet<>(), null, null, 0); var item = new CollectionCopying<>(null, new HashSet<>(), null, null, 0);
var modifiedItem = CollectionCopyingBuilder.builder(item) var modifiedItem = CollectionCopyingBuilder.builder(item).addSet("a").build();
.addSet("a")
.build();
Assertions.assertEquals(modifiedItem.set(), Set.of("a")); Assertions.assertEquals(modifiedItem.set(), Set.of("a"));
Assertions.assertTrue(item.set().isEmpty()); Assertions.assertTrue(item.set().isEmpty());
@@ -138,9 +108,7 @@ public class TestImmutableCollections {
@Test @Test
void testSourceMapNotModified() { void testSourceMapNotModified() {
var item = new CollectionCopying<>(null, null, new HashMap<>(), null, 0); var item = new CollectionCopying<>(null, null, new HashMap<>(), null, 0);
var modifiedItem = CollectionCopyingBuilder.builder(item) var modifiedItem = CollectionCopyingBuilder.builder(item).addMap(Instant.MIN, "a").build();
.addMap(Instant.MIN, "a")
.build();
Assertions.assertEquals(modifiedItem.map(), Map.of(Instant.MIN, "a")); Assertions.assertEquals(modifiedItem.map(), Map.of(Instant.MIN, "a"));
Assertions.assertTrue(item.map().isEmpty()); Assertions.assertTrue(item.map().isEmpty());

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -36,12 +36,7 @@ class TestOptional {
@Test @Test
void testRawSetters() { void testRawSetters() {
var record = RecordWithOptionalBuilder.builder() var record = RecordWithOptionalBuilder.builder().value("value").raw("rawValue").i(42).l(424242L).d(42.42)
.value("value")
.raw("rawValue")
.i(42)
.l(424242L)
.d(42.42)
.build(); .build();
Assertions.assertEquals(Optional.of("value"), record.value()); Assertions.assertEquals(Optional.of("value"), record.value());
Assertions.assertEquals(Optional.of("rawValue"), record.raw()); Assertions.assertEquals(Optional.of("rawValue"), record.raw());
@@ -52,13 +47,8 @@ class TestOptional {
@Test @Test
void testOptionalSetters() { void testOptionalSetters() {
var record = RecordWithOptional2Builder.builder() var record = RecordWithOptional2Builder.builder().value(Optional.of("value")).raw(Optional.of("rawValue"))
.value(Optional.of("value")) .i(OptionalInt.of(42)).l(OptionalLong.of(424242L)).d(OptionalDouble.of(42.42)).build();
.raw(Optional.of("rawValue"))
.i(OptionalInt.of(42))
.l(OptionalLong.of(424242L))
.d(OptionalDouble.of(42.42))
.build();
Assertions.assertEquals(Optional.of("value"), record.value()); Assertions.assertEquals(Optional.of("value"), record.value());
Assertions.assertEquals(Optional.of("rawValue"), record.raw()); Assertions.assertEquals(Optional.of("rawValue"), record.raw());
Assertions.assertEquals(OptionalInt.of(42), record.i()); Assertions.assertEquals(OptionalInt.of(42), record.i());
@@ -72,9 +62,7 @@ class TestOptional {
String value = null; String value = null;
// when // when
var record = RecordWithOptionalBuilder.builder() var record = RecordWithOptionalBuilder.builder().value(value).build();
.value(value)
.build();
// then // then
Assertions.assertEquals(Optional.empty(), record.value()); Assertions.assertEquals(Optional.empty(), record.value());

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -33,10 +33,7 @@ class TestRecordBuilderFull {
@Test @Test
void testImmutable() { void testImmutable() {
var record = FullRecordBuilder.builder() var record = FullRecordBuilder.builder().fullRecords(new HashMap<>()).numbers(new ArrayList<>()).justAString("")
.fullRecords(new HashMap<>())
.numbers(new ArrayList<>())
.justAString("")
.build(); .build();
Assertions.assertThrows(UnsupportedOperationException.class, () -> record.fullRecords().put(1, record)); Assertions.assertThrows(UnsupportedOperationException.class, () -> record.fullRecords().put(1, record));
Assertions.assertThrows(UnsupportedOperationException.class, () -> record.numbers().add(1)); Assertions.assertThrows(UnsupportedOperationException.class, () -> record.numbers().add(1));

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -26,11 +26,9 @@ import java.time.Instant;
import static io.soabase.recordbuilder.test.SimpleGenericRecordBuilder.SimpleGenericRecord; import static io.soabase.recordbuilder.test.SimpleGenericRecordBuilder.SimpleGenericRecord;
import static io.soabase.recordbuilder.test.SimpleRecordBuilder.SimpleRecord; import static io.soabase.recordbuilder.test.SimpleRecordBuilder.SimpleRecord;
public class TestRecordInterface public class TestRecordInterface {
{
@Test @Test
public void testHasDefaults() public void testHasDefaults() {
{
var r1 = new HasDefaultsRecord(Instant.MIN, Instant.MAX); var r1 = new HasDefaultsRecord(Instant.MIN, Instant.MAX);
var r2 = r1.with(b -> b.tomorrow(Instant.MIN)); var r2 = r1.with(b -> b.tomorrow(Instant.MIN));
Assertions.assertEquals(Instant.MIN, r1.time()); Assertions.assertEquals(Instant.MIN, r1.time());
@@ -40,9 +38,8 @@ public class TestRecordInterface
} }
@Test @Test
public void testStaticConstructor() public void testStaticConstructor() {
{ var simple = SimpleRecord(10, "hey");
var simple = SimpleRecord(10,"hey");
Assertions.assertEquals(simple.i(), 10); Assertions.assertEquals(simple.i(), 10);
Assertions.assertEquals(simple.s(), "hey"); Assertions.assertEquals(simple.s(), "hey");
@@ -53,26 +50,15 @@ public class TestRecordInterface
} }
@Test @Test
public void testBuilderStreamWithValues() public void testBuilderStreamWithValues() {
{ var stream = SimpleRecordBuilder.stream(SimpleRecordBuilder.builder().i(19).s("value").build()).toList();
var stream = SimpleRecordBuilder.stream(SimpleRecordBuilder.builder() Assertions.assertEquals(stream, List.of(Map.entry("i", 19), Map.entry("s", "value")));
.i(19)
.s("value")
.build())
.toList();
Assertions.assertEquals(stream, List.of(
Map.entry("i", 19),
Map.entry("s", "value")));
} }
@Test @Test
public void testBuilderStreamWithNulls() public void testBuilderStreamWithNulls() {
{ var stream = SimpleRecordBuilder.stream(SimpleRecordBuilder.builder().build()).toList();
var stream = SimpleRecordBuilder.stream(SimpleRecordBuilder.builder() Assertions.assertEquals(stream,
.build()) List.of(new SimpleImmutableEntry<>("i", 0), new SimpleImmutableEntry<>("s", null)));
.toList();
Assertions.assertEquals(stream, List.of(
new SimpleImmutableEntry<>("i", 0),
new SimpleImmutableEntry<>("s", null)));
} }
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -26,26 +26,16 @@ import java.util.Set;
public class TestSingleItems { public class TestSingleItems {
@Test @Test
public void testInternalCollections() public void testInternalCollections() {
{
var now = Instant.now(); var now = Instant.now();
var item = SingleItemsBuilder.<String>builder() var item = SingleItemsBuilder.<String> builder().add1Map(now, "now").add1Map(Instant.MIN, "before")
.add1Map(now, "now") .add1Sets(Arrays.asList("1", "2")).add1Sets(List.of("3")).add1Strings("a").add1Strings("b")
.add1Map(Instant.MIN, "before") .add1Strings("c").build();
.add1Sets(Arrays.asList("1", "2"))
.add1Sets(List.of("3"))
.add1Strings("a")
.add1Strings("b")
.add1Strings("c")
.build();
Assertions.assertEquals(item.map(), Map.of(now, "now", Instant.MIN, "before")); Assertions.assertEquals(item.map(), Map.of(now, "now", Instant.MIN, "before"));
Assertions.assertEquals(item.sets(), Set.of(List.of("1", "2"), List.of("3"))); Assertions.assertEquals(item.sets(), Set.of(List.of("1", "2"), List.of("3")));
Assertions.assertEquals(item.strings(), List.of("a", "b", "c")); Assertions.assertEquals(item.strings(), List.of("a", "b", "c"));
var copy = item.with() var copy = item.with().add1Strings("new").add1Map(Instant.MAX, "after").add1Sets(List.of("10", "20", "30"))
.add1Strings("new")
.add1Map(Instant.MAX, "after")
.add1Sets(List.of("10", "20", "30"))
.build(); .build();
Assertions.assertNotEquals(item, copy); Assertions.assertNotEquals(item, copy);
Assertions.assertEquals(copy.map(), Map.of(now, "now", Instant.MIN, "before", Instant.MAX, "after")); Assertions.assertEquals(copy.map(), Map.of(now, "now", Instant.MIN, "before", Instant.MAX, "after"));
@@ -55,20 +45,15 @@ public class TestSingleItems {
var stringsToAdd = Arrays.asList("x", "y", "z"); var stringsToAdd = Arrays.asList("x", "y", "z");
var listToAdd = Arrays.asList(List.of("aa", "bb"), List.of("cc")); var listToAdd = Arrays.asList(List.of("aa", "bb"), List.of("cc"));
var mapToAdd = Map.of(now.plusMillis(1), "now+1", now.plusMillis(2), "now+2"); var mapToAdd = Map.of(now.plusMillis(1), "now+1", now.plusMillis(2), "now+2");
var streamed = SingleItemsBuilder.builder(item) var streamed = SingleItemsBuilder.builder(item).add1Strings(stringsToAdd.stream()).add1Sets(listToAdd.stream())
.add1Strings(stringsToAdd.stream()) .add1Map(mapToAdd.entrySet().stream()).build();
.add1Sets(listToAdd.stream()) Assertions.assertEquals(streamed.map(),
.add1Map(mapToAdd.entrySet().stream()) Map.of(now, "now", Instant.MIN, "before", now.plusMillis(1), "now+1", now.plusMillis(2), "now+2"));
.build(); Assertions.assertEquals(streamed.sets(),
Assertions.assertEquals(streamed.map(), Map.of(now, "now", Instant.MIN, "before", now.plusMillis(1), "now+1", now.plusMillis(2), "now+2")); Set.of(List.of("1", "2"), List.of("3"), List.of("aa", "bb"), List.of("cc")));
Assertions.assertEquals(streamed.sets(), Set.of(List.of("1", "2"), List.of("3"), List.of("aa", "bb"), List.of("cc")));
Assertions.assertEquals(streamed.strings(), Arrays.asList("a", "b", "c", "x", "y", "z")); Assertions.assertEquals(streamed.strings(), Arrays.asList("a", "b", "c", "x", "y", "z"));
var nulls = SingleItemsBuilder.builder(item) var nulls = SingleItemsBuilder.builder(item).strings(null).sets(null).map(null).build();
.strings(null)
.sets(null)
.map(null)
.build();
Assertions.assertEquals(nulls.map(), Map.of()); Assertions.assertEquals(nulls.map(), Map.of());
Assertions.assertEquals(nulls.sets(), Set.of()); Assertions.assertEquals(nulls.sets(), Set.of());
Assertions.assertEquals(nulls.strings(), List.of()); Assertions.assertEquals(nulls.strings(), List.of());

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -46,11 +46,9 @@ class TestValidation {
@Test @Test
void testRequestWithValid() { void testRequestWithValid() {
Assertions.assertDoesNotThrow(() -> RequestWithValidBuilder.builder() Assertions.assertDoesNotThrow(
.part(new RequestWithValid.Part("jsfjsf")) () -> RequestWithValidBuilder.builder().part(new RequestWithValid.Part("jsfjsf")).build());
.build()); Assertions.assertThrows(ValidationException.class,
Assertions.assertThrows(ValidationException.class, () -> RequestWithValidBuilder.builder() () -> RequestWithValidBuilder.builder().part(new RequestWithValid.Part("")).build());
.part(new RequestWithValid.Part(""))
.build());
} }
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -24,46 +24,40 @@ import static org.junit.jupiter.api.Assertions.*;
public class TestVariousOptions { public class TestVariousOptions {
@Test @Test
public void builderGetsCustomSetterAndGetterNames() { public void builderGetsCustomSetterAndGetterNames() {
var obj = CustomMethodNamesBuilder.builder() var obj = CustomMethodNamesBuilder.builder().setTheValue(1).setTheList(List.of(2)).setTheBoolean(true);
.setTheValue(1) assertEquals(1, obj.getTheValue());
.setTheList(List.of(2)) assertEquals(List.of(2), obj.getTheList());
.setTheBoolean(true); assertTrue(obj.isTheBoolean());
assertEquals(1, obj.getTheValue()); assertEquals(new CustomMethodNames(1, List.of(2), true), obj.build());
assertEquals(List.of(2), obj.getTheList()); }
assertTrue(obj.isTheBoolean());
assertEquals(new CustomMethodNames(1, List.of(2), true), obj.build());
}
@Test @Test
public void withBuilderGetsCustomSetterAndGetterNames() { public void withBuilderGetsCustomSetterAndGetterNames() {
var obj = CustomMethodNamesBuilder.from(CustomMethodNamesBuilder.builder() var obj = CustomMethodNamesBuilder.from(
.setTheValue(1) CustomMethodNamesBuilder.builder().setTheValue(1).setTheList(List.of(2)).setTheBoolean(true).build());
.setTheList(List.of(2)) assertEquals(1, obj.getTheValue());
.setTheBoolean(true) assertEquals(List.of(2), obj.getTheList());
.build()); assertTrue(obj.isTheBoolean());
assertEquals(1, obj.getTheValue()); }
assertEquals(List.of(2), obj.getTheList());
assertTrue(obj.isTheBoolean());
}
@Test @Test
public void recordHasPrefixedGetters() { public void recordHasPrefixedGetters() {
var obj = new CustomMethodNames(1, List.of(2), true); var obj = new CustomMethodNames(1, List.of(2), true);
assertEquals(1, obj.getTheValue()); assertEquals(1, obj.getTheValue());
assertEquals(List.of(2), obj.getTheList()); assertEquals(List.of(2), obj.getTheList());
assertTrue(obj.isTheBoolean()); assertTrue(obj.isTheBoolean());
} }
@Test @Test
public void noStaticBuilder() { public void noStaticBuilder() {
boolean hasStaticBuilder = Stream.of(NoStaticBuilderBuilder.class.getDeclaredMethods()) boolean hasStaticBuilder = Stream.of(NoStaticBuilderBuilder.class.getDeclaredMethods())
.anyMatch(method -> method.getName().equals("NoStaticBuilder")); .anyMatch(method -> method.getName().equals("NoStaticBuilder"));
assertFalse(hasStaticBuilder); assertFalse(hasStaticBuilder);
hasStaticBuilder = Stream.of(SimpleRecordBuilder.class.getDeclaredMethods()) hasStaticBuilder = Stream.of(SimpleRecordBuilder.class.getDeclaredMethods())
.anyMatch(method -> method.getName().equals("SimpleRecord")); .anyMatch(method -> method.getName().equals("SimpleRecord"));
assertTrue(hasStaticBuilder); assertTrue(hasStaticBuilder);
} }
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -30,7 +30,6 @@ class TestVisibility {
Assertions.assertTrue(Modifier.isPublic(WrapperProtectedRecordBuilder.class.getModifiers())); Assertions.assertTrue(Modifier.isPublic(WrapperProtectedRecordBuilder.class.getModifiers()));
} }
@Test @Test
void testMatchesWithModifers() { void testMatchesWithModifers() {
Assertions.assertFalse(Modifier.isPublic(PackagePrivateRecordWithPublicBuilder.class.getModifiers())); Assertions.assertFalse(Modifier.isPublic(PackagePrivateRecordWithPublicBuilder.class.getModifiers()));

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- <!--
Copyright 2019 Jordan Zimmerman Copyright 2019 The original author or authors
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2019 Jordan Zimmerman * Copyright 2019 The original author or authors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
Copyright 2019 Jordan Zimmerman Copyright ${year} The original author or authors
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.