Options/changes so that Jacoco checks don't fail (#104)
- Added new optional Annotation `@RecordBuilderGenerated` - Jacoco ignores classes with any annotation names "*Generated*" but it needs to be class retained. For backward compatibility this annotation is not added by default (though it's been added to `@RecordBuilderFull`). There is a new option to enable it. - The from with method now uses an internal static class instead of an anonymous inner class so that the annotation can be on this as well. This new class's name is configurable in the options. Thanks to user @madisparn for initial PR and issue report. Fixes #87
This commit is contained in:
8
pom.xml
8
pom.xml
@@ -34,6 +34,8 @@
|
|||||||
<maven-jar-plugin-version>3.2.0</maven-jar-plugin-version>
|
<maven-jar-plugin-version>3.2.0</maven-jar-plugin-version>
|
||||||
<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>
|
||||||
|
|
||||||
<license-file-path>src/etc/header.txt</license-file-path>
|
<license-file-path>src/etc/header.txt</license-file-path>
|
||||||
|
|
||||||
<javapoet-version>1.12.1</javapoet-version>
|
<javapoet-version>1.12.1</javapoet-version>
|
||||||
@@ -326,6 +328,12 @@
|
|||||||
<artifactId>maven-gpg-plugin</artifactId>
|
<artifactId>maven-gpg-plugin</artifactId>
|
||||||
<version>${maven-gpg-plugin-version}</version>
|
<version>${maven-gpg-plugin-version}</version>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.jacoco</groupId>
|
||||||
|
<artifactId>jacoco-maven-plugin</artifactId>
|
||||||
|
<version>${jacoco-maven-plugin-version}</version>
|
||||||
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</pluginManagement>
|
</pluginManagement>
|
||||||
|
|
||||||
|
|||||||
@@ -234,6 +234,18 @@ public @interface RecordBuilder {
|
|||||||
* this 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
|
||||||
|
* policy of {@code CLASS}. This ensures that analyzers such as Jacoco will ignore the generated class.
|
||||||
|
*/
|
||||||
|
boolean addClassRetainedGenerated() default false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link #fromMethodName} method instantiates an internal private class. This is the
|
||||||
|
* name of that class.
|
||||||
|
*/
|
||||||
|
String fromWithClassName() default "_FromWith";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Retention(RetentionPolicy.CLASS)
|
@Retention(RetentionPolicy.CLASS)
|
||||||
|
|||||||
@@ -21,7 +21,8 @@ import java.lang.annotation.*;
|
|||||||
interpretNotNulls = true,
|
interpretNotNulls = true,
|
||||||
useImmutableCollections = true,
|
useImmutableCollections = true,
|
||||||
addSingleItemCollectionBuilders = true,
|
addSingleItemCollectionBuilders = true,
|
||||||
addFunctionalMethodsToWith = true
|
addFunctionalMethodsToWith = true,
|
||||||
|
addClassRetainedGenerated = true
|
||||||
))
|
))
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
@Target(ElementType.TYPE)
|
@Target(ElementType.TYPE)
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2019 Jordan Zimmerman
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package io.soabase.recordbuilder.core;
|
||||||
|
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
import static java.lang.annotation.ElementType.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Jacoco ignores classes and methods annotated with `*Generated`
|
||||||
|
*/
|
||||||
|
@Target({PACKAGE, TYPE, METHOD, CONSTRUCTOR, FIELD, LOCAL_VARIABLE, PARAMETER})
|
||||||
|
@Retention(RetentionPolicy.CLASS)
|
||||||
|
public @interface RecordBuilderGenerated {
|
||||||
|
}
|
||||||
@@ -33,6 +33,7 @@ import static io.soabase.recordbuilder.processor.CollectionBuilderUtils.SingleIt
|
|||||||
import static io.soabase.recordbuilder.processor.ElementUtils.getBuilderName;
|
import static io.soabase.recordbuilder.processor.ElementUtils.getBuilderName;
|
||||||
import static io.soabase.recordbuilder.processor.ElementUtils.getWithMethodName;
|
import static io.soabase.recordbuilder.processor.ElementUtils.getWithMethodName;
|
||||||
import static io.soabase.recordbuilder.processor.RecordBuilderProcessor.generatedRecordBuilderAnnotation;
|
import static io.soabase.recordbuilder.processor.RecordBuilderProcessor.generatedRecordBuilderAnnotation;
|
||||||
|
import static io.soabase.recordbuilder.processor.RecordBuilderProcessor.recordBuilderGeneratedAnnotation;
|
||||||
|
|
||||||
class InternalRecordBuilderProcessor {
|
class InternalRecordBuilderProcessor {
|
||||||
private final RecordBuilder.Options metaData;
|
private final RecordBuilder.Options metaData;
|
||||||
@@ -69,6 +70,9 @@ class InternalRecordBuilderProcessor {
|
|||||||
builder = TypeSpec.classBuilder(builderClassType.name())
|
builder = TypeSpec.classBuilder(builderClassType.name())
|
||||||
.addAnnotation(generatedRecordBuilderAnnotation)
|
.addAnnotation(generatedRecordBuilderAnnotation)
|
||||||
.addTypeVariables(typeVariables);
|
.addTypeVariables(typeVariables);
|
||||||
|
if (metaData.addClassRetainedGenerated()) {
|
||||||
|
builder.addAnnotation(recordBuilderGeneratedAnnotation);
|
||||||
|
}
|
||||||
addVisibility(recordActualPackage.equals(packageName), record.getModifiers());
|
addVisibility(recordActualPackage.equals(packageName), record.getModifiers());
|
||||||
if (metaData.enableWither()) {
|
if (metaData.enableWither()) {
|
||||||
addWithNestedClass();
|
addWithNestedClass();
|
||||||
@@ -158,6 +162,9 @@ class InternalRecordBuilderProcessor {
|
|||||||
.addJavadoc("Add withers to {@code $L}\n", recordClassType.name())
|
.addJavadoc("Add withers to {@code $L}\n", recordClassType.name())
|
||||||
.addModifiers(Modifier.PUBLIC)
|
.addModifiers(Modifier.PUBLIC)
|
||||||
.addTypeVariables(typeVariables);
|
.addTypeVariables(typeVariables);
|
||||||
|
if (metaData.addClassRetainedGenerated()) {
|
||||||
|
classBuilder.addAnnotation(recordBuilderGeneratedAnnotation);
|
||||||
|
}
|
||||||
recordComponents.forEach(component -> addNestedGetterMethod(classBuilder, component, prefixedName(component, true)));
|
recordComponents.forEach(component -> addNestedGetterMethod(classBuilder, component, prefixedName(component, true)));
|
||||||
addWithBuilderMethod(classBuilder);
|
addWithBuilderMethod(classBuilder);
|
||||||
addWithSuppliedBuilderMethod(classBuilder);
|
addWithSuppliedBuilderMethod(classBuilder);
|
||||||
@@ -560,63 +567,83 @@ class InternalRecordBuilderProcessor {
|
|||||||
return codeBuilder.build();
|
return codeBuilder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private TypeName buildWithTypeName()
|
||||||
|
{
|
||||||
|
ClassName rawTypeName = ClassName.get(packageName, builderClassType.name() + "." + metaData.withClassName());
|
||||||
|
if (typeVariables.isEmpty()) {
|
||||||
|
return rawTypeName;
|
||||||
|
}
|
||||||
|
return ParameterizedTypeName.get(rawTypeName, typeVariables.toArray(new TypeName[]{}));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addFromWithClass() {
|
||||||
|
/*
|
||||||
|
Adds static private class that implements/proxies the Wither
|
||||||
|
|
||||||
|
private static final class _FromWith implements MyRecordBuilder.With {
|
||||||
|
private final MyRecord from;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String p1() {
|
||||||
|
return from.p1();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String p2() {
|
||||||
|
return from.p2();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
var fromWithClassBuilder = TypeSpec.classBuilder(metaData.fromWithClassName())
|
||||||
|
.addModifiers(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL)
|
||||||
|
.addAnnotation(generatedRecordBuilderAnnotation)
|
||||||
|
.addTypeVariables(typeVariables)
|
||||||
|
.addSuperinterface(buildWithTypeName());
|
||||||
|
if (metaData.addClassRetainedGenerated()) {
|
||||||
|
fromWithClassBuilder.addAnnotation(recordBuilderGeneratedAnnotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
fromWithClassBuilder.addField(recordClassType.typeName(), "from", Modifier.PRIVATE, Modifier.FINAL);
|
||||||
|
MethodSpec constructorSpec = MethodSpec.constructorBuilder()
|
||||||
|
.addParameter(recordClassType.typeName(), "from")
|
||||||
|
.addStatement("this.from = from")
|
||||||
|
.addModifiers(Modifier.PRIVATE)
|
||||||
|
.build();
|
||||||
|
fromWithClassBuilder.addMethod(constructorSpec);
|
||||||
|
|
||||||
|
IntStream.range(0, recordComponents.size()).forEach(index -> {
|
||||||
|
var component = recordComponents.get(index);
|
||||||
|
MethodSpec methodSpec = MethodSpec.methodBuilder(prefixedName(component, true))
|
||||||
|
.returns(component.typeName())
|
||||||
|
.addAnnotation(Override.class)
|
||||||
|
.addModifiers(Modifier.PUBLIC)
|
||||||
|
.addStatement("return from.$L()", component.name())
|
||||||
|
.build();
|
||||||
|
fromWithClassBuilder.addMethod(methodSpec);
|
||||||
|
});
|
||||||
|
this.builder.addType(fromWithClassBuilder.build());
|
||||||
|
}
|
||||||
|
|
||||||
private void addStaticFromWithMethod() {
|
private void addStaticFromWithMethod() {
|
||||||
/*
|
/*
|
||||||
Adds static method that returns a "with"er view of an existing record.
|
Adds static method that returns a "with"er view of an existing record.
|
||||||
|
|
||||||
public static With from(MyRecord from) {
|
public static With from(MyRecord from) {
|
||||||
return new MyRecordBuilder.With() {
|
return new _FromWith(from);
|
||||||
@Override
|
|
||||||
public String p1() {
|
|
||||||
return from.p1();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String p2() {
|
|
||||||
return from.p2();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
var witherClassNameBuilder = CodeBlock.builder()
|
|
||||||
.add("$L.$L", builderClassType.name(), metaData.withClassName());
|
|
||||||
if (!typeVariables.isEmpty()) {
|
|
||||||
witherClassNameBuilder.add("<");
|
|
||||||
IntStream.range(0, typeVariables.size()).forEach(index -> {
|
|
||||||
if (index > 0) {
|
|
||||||
witherClassNameBuilder.add(", ");
|
|
||||||
}
|
|
||||||
witherClassNameBuilder.add(typeVariables.get(index).name);
|
|
||||||
});
|
|
||||||
witherClassNameBuilder.add(">");
|
|
||||||
}
|
|
||||||
var witherClassName = witherClassNameBuilder.build().toString();
|
|
||||||
var codeBuilder = CodeBlock.builder()
|
|
||||||
.add("return new $L", witherClassName)
|
|
||||||
.add("() {\n").indent();
|
|
||||||
IntStream.range(0, recordComponents.size()).forEach(index -> {
|
|
||||||
var component = recordComponents.get(index);
|
|
||||||
if (index > 0) {
|
|
||||||
codeBuilder.add("\n");
|
|
||||||
}
|
|
||||||
codeBuilder.add("@Override\n")
|
|
||||||
.add("public $T $L() {\n", component.typeName(), prefixedName(component, true))
|
|
||||||
.indent()
|
|
||||||
.addStatement("return from.$L()", component.name())
|
|
||||||
.unindent()
|
|
||||||
.add("}\n");
|
|
||||||
});
|
|
||||||
codeBuilder.unindent().addStatement("}");
|
|
||||||
|
|
||||||
var withType = ClassName.get("", witherClassName);
|
addFromWithClass();
|
||||||
var methodSpec = MethodSpec.methodBuilder("from")//metaData.copyMethodName())
|
|
||||||
|
var methodSpec = MethodSpec.methodBuilder(metaData.fromMethodName())
|
||||||
.addJavadoc("Return a \"with\"er for an existing record instance\n")
|
.addJavadoc("Return a \"with\"er for an existing record instance\n")
|
||||||
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
|
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
|
||||||
.addAnnotation(generatedRecordBuilderAnnotation)
|
.addAnnotation(generatedRecordBuilderAnnotation)
|
||||||
.addTypeVariables(typeVariables)
|
.addTypeVariables(typeVariables)
|
||||||
.addParameter(recordClassType.typeName(), metaData.fromMethodName())
|
.addParameter(recordClassType.typeName(), metaData.fromMethodName())
|
||||||
.returns(withType)
|
.returns(buildWithTypeName())
|
||||||
.addCode(codeBuilder.build())
|
.addStatement("return new $L$L(from)", metaData.fromWithClassName(), typeVariables.isEmpty() ? "" : "<>")
|
||||||
.build();
|
.build();
|
||||||
builder.addMethod(methodSpec);
|
builder.addMethod(methodSpec);
|
||||||
}
|
}
|
||||||
@@ -951,13 +978,13 @@ class InternalRecordBuilderProcessor {
|
|||||||
}
|
}
|
||||||
var type = optionalType.get();
|
var type = optionalType.get();
|
||||||
var methodSpec = MethodSpec.methodBuilder(prefixedName(component, false))
|
var methodSpec = MethodSpec.methodBuilder(prefixedName(component, false))
|
||||||
.addModifiers(Modifier.PUBLIC)
|
.addModifiers(Modifier.PUBLIC)
|
||||||
.addAnnotation(generatedRecordBuilderAnnotation)
|
.addAnnotation(generatedRecordBuilderAnnotation)
|
||||||
.returns(builderClassType.typeName());
|
.returns(builderClassType.typeName());
|
||||||
|
|
||||||
var parameterSpecBuilder = ParameterSpec.builder(type.valueType(), component.name());
|
var parameterSpecBuilder = ParameterSpec.builder(type.valueType(), component.name());
|
||||||
methodSpec.addJavadoc("Set a new value for the {@code $L} record component in the builder\n", component.name())
|
methodSpec.addJavadoc("Set a new value for the {@code $L} record component in the builder\n", component.name())
|
||||||
.addStatement("this.$L = $T.of($L)", component.name(), type.typeName(), component.name());
|
.addStatement("this.$L = $T.of($L)", component.name(), type.typeName(), component.name());
|
||||||
addConstructorAnnotations(component, parameterSpecBuilder);
|
addConstructorAnnotations(component, parameterSpecBuilder);
|
||||||
methodSpec.addStatement("return this").addParameter(parameterSpecBuilder.build());
|
methodSpec.addStatement("return this").addParameter(parameterSpecBuilder.build());
|
||||||
builder.addMethod(methodSpec.build());
|
builder.addMethod(methodSpec.build());
|
||||||
@@ -1030,7 +1057,7 @@ class InternalRecordBuilderProcessor {
|
|||||||
|
|
||||||
private String prefixedName(RecordClassType component, boolean isGetter) {
|
private String prefixedName(RecordClassType component, boolean isGetter) {
|
||||||
BiFunction<String, String, String> prefixer = (p, s) -> p.isEmpty()
|
BiFunction<String, String, String> prefixer = (p, s) -> p.isEmpty()
|
||||||
? s : p + Character.toUpperCase(s.charAt(0)) + s.substring(1);
|
? s : p + Character.toUpperCase(s.charAt(0)) + s.substring(1);
|
||||||
boolean isBool = component.typeName().toString().toLowerCase(Locale.ROOT).equals("boolean");
|
boolean isBool = component.typeName().toString().toLowerCase(Locale.ROOT).equals("boolean");
|
||||||
if (isGetter) {
|
if (isGetter) {
|
||||||
if (isBool) {
|
if (isBool) {
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import java.util.stream.Collectors;
|
|||||||
|
|
||||||
import static io.soabase.recordbuilder.processor.ElementUtils.getBuilderName;
|
import static io.soabase.recordbuilder.processor.ElementUtils.getBuilderName;
|
||||||
import static io.soabase.recordbuilder.processor.RecordBuilderProcessor.generatedRecordInterfaceAnnotation;
|
import static io.soabase.recordbuilder.processor.RecordBuilderProcessor.generatedRecordInterfaceAnnotation;
|
||||||
|
import static io.soabase.recordbuilder.processor.RecordBuilderProcessor.recordBuilderGeneratedAnnotation;
|
||||||
|
|
||||||
class InternalRecordInterfaceProcessor {
|
class InternalRecordInterfaceProcessor {
|
||||||
private final ProcessingEnvironment processingEnv;
|
private final ProcessingEnvironment processingEnv;
|
||||||
@@ -68,6 +69,9 @@ class InternalRecordInterfaceProcessor {
|
|||||||
.addModifiers(Modifier.PUBLIC)
|
.addModifiers(Modifier.PUBLIC)
|
||||||
.addAnnotation(generatedRecordInterfaceAnnotation)
|
.addAnnotation(generatedRecordInterfaceAnnotation)
|
||||||
.addTypeVariables(typeVariables);
|
.addTypeVariables(typeVariables);
|
||||||
|
if (metaData.addClassRetainedGenerated()) {
|
||||||
|
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());
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import com.squareup.javapoet.AnnotationSpec;
|
|||||||
import com.squareup.javapoet.JavaFile;
|
import com.squareup.javapoet.JavaFile;
|
||||||
import com.squareup.javapoet.TypeSpec;
|
import com.squareup.javapoet.TypeSpec;
|
||||||
import io.soabase.recordbuilder.core.RecordBuilder;
|
import io.soabase.recordbuilder.core.RecordBuilder;
|
||||||
|
import io.soabase.recordbuilder.core.RecordBuilderGenerated;
|
||||||
import io.soabase.recordbuilder.core.RecordInterface;
|
import io.soabase.recordbuilder.core.RecordInterface;
|
||||||
|
|
||||||
import javax.annotation.processing.AbstractProcessor;
|
import javax.annotation.processing.AbstractProcessor;
|
||||||
@@ -46,6 +47,7 @@ public class RecordBuilderProcessor
|
|||||||
|
|
||||||
static final AnnotationSpec generatedRecordBuilderAnnotation = AnnotationSpec.builder(Generated.class).addMember("value", "$S", RecordBuilder.class.getName()).build();
|
static final AnnotationSpec generatedRecordBuilderAnnotation = AnnotationSpec.builder(Generated.class).addMember("value", "$S", RecordBuilder.class.getName()).build();
|
||||||
static final AnnotationSpec generatedRecordInterfaceAnnotation = AnnotationSpec.builder(Generated.class).addMember("value", "$S", RecordInterface.class.getName()).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) {
|
||||||
|
|||||||
@@ -66,6 +66,48 @@
|
|||||||
<skip>true</skip>
|
<skip>true</skip>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.jacoco</groupId>
|
||||||
|
<artifactId>jacoco-maven-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>default-prepare-agent</id>
|
||||||
|
<goals>
|
||||||
|
<goal>prepare-agent</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>default-report</id>
|
||||||
|
<goals>
|
||||||
|
<goal>report</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>default-check</id>
|
||||||
|
<goals>
|
||||||
|
<goal>check</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<includes>
|
||||||
|
<include>io/soabase/recordbuilder/test/jacoco/*</include>
|
||||||
|
</includes>
|
||||||
|
<rules>
|
||||||
|
<rule>
|
||||||
|
<element>BUNDLE</element>
|
||||||
|
<limits>
|
||||||
|
<limit>
|
||||||
|
<counter>COMPLEXITY</counter>
|
||||||
|
<value>COVEREDRATIO</value>
|
||||||
|
<minimum>0.60</minimum>
|
||||||
|
</limit>
|
||||||
|
</limits>
|
||||||
|
</rule>
|
||||||
|
</rules>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2019 Jordan Zimmerman
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package io.soabase.recordbuilder.test.jacoco;
|
||||||
|
|
||||||
|
import io.soabase.recordbuilder.core.RecordBuilderFull;
|
||||||
|
import io.soabase.recordbuilder.core.RecordBuilderGenerated;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@RecordBuilderFull
|
||||||
|
@RecordBuilderGenerated
|
||||||
|
public record FullRecordForJacoco(@NotNull List<Number> numbers, @NotNull Map<Number, FullRecordForJacoco> fullRecords, @NotNull String justAString) {
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user