diff --git a/README.md b/README.md index fce84b4..b8ed8d9 100644 --- a/README.md +++ b/README.md @@ -286,6 +286,9 @@ public void Placeholder { } ``` +`@RecordBuilder.Include` also supports a `packages` attribute that includes all records +in the listed packages. + The target package for generation is the same as the package that contains the "Include" annotation. Use `packagePattern` to change this (see Javadoc for details). diff --git a/record-builder-core/src/main/java/io/soabase/recordbuilder/core/RecordBuilder.java b/record-builder-core/src/main/java/io/soabase/recordbuilder/core/RecordBuilder.java index 5d8875c..8a90a69 100644 --- a/record-builder-core/src/main/java/io/soabase/recordbuilder/core/RecordBuilder.java +++ b/record-builder-core/src/main/java/io/soabase/recordbuilder/core/RecordBuilder.java @@ -25,12 +25,32 @@ public @interface RecordBuilder { @Retention(RetentionPolicy.SOURCE) @Inherited @interface Include { - Class[] value(); + /** + * @return list of classes to include + */ + Class[] value() default {}; + + /** + * Synonym for {@code value()}. When using the other attributes it maybe more clear to + * use {@code classes()} instead of {@code value()}. Note: both attributes are applied + * (i.e. a union of classes from both attributes). + * + * @return list of classes + */ + Class[] classes() default {}; + + /** + * Optional list of package names. All records in the packages will get processed as + * if they were listed as classes to include. + * + * @return list of package names + */ + String[] packages() default {}; /** * Pattern used to generate the package for the generated class. The value * is the literal package name however two replacement values can be used. '@' - * is replaced with the package of the Include annotation. '*' is replaced with + * is replaced with the package of the {@code Include} annotation. '*' is replaced with * the package of the included class. * * @return package pattern diff --git a/record-builder-core/src/main/java/io/soabase/recordbuilder/core/RecordInterface.java b/record-builder-core/src/main/java/io/soabase/recordbuilder/core/RecordInterface.java index 177c7c3..ea950ca 100644 --- a/record-builder-core/src/main/java/io/soabase/recordbuilder/core/RecordInterface.java +++ b/record-builder-core/src/main/java/io/soabase/recordbuilder/core/RecordInterface.java @@ -27,14 +27,31 @@ public @interface RecordInterface { @Retention(RetentionPolicy.SOURCE) @Inherited @interface Include { - Class[] value(); + /** + * @return list of classes to include + */ + Class[] value() default {}; + /** + * Synonym for {@code value()}. When using the other attributes it maybe more clear to + * use {@code classes()} instead of {@code value()}. Note: both attributes are applied + * (i.e. a union of classes from both attributes). + * + * @return list of classes + */ + Class[] classes() default {}; + + /** + * If true the generated record is annotated with {@code @RecordBuilder} + * + * @return true/false + */ boolean addRecordBuilder() default true; /** * Pattern used to generate the package for the generated class. The value * is the literal package name however two replacement values can be used. '@' - * is replaced with the package of the Include annotation. '*' is replaced with + * is replaced with the package of the {@code Include} annotation. '*' is replaced with * the package of the included class. * * @return package pattern diff --git a/record-builder-processor/src/main/java/io/soabase/recordbuilder/processor/ElementUtils.java b/record-builder-processor/src/main/java/io/soabase/recordbuilder/processor/ElementUtils.java index e9cb3cf..77bdda9 100644 --- a/record-builder-processor/src/main/java/io/soabase/recordbuilder/processor/ElementUtils.java +++ b/record-builder-processor/src/main/java/io/soabase/recordbuilder/processor/ElementUtils.java @@ -52,12 +52,19 @@ public class ElementUtils { } @SuppressWarnings("unchecked") - public static List getClassesAttribute(AnnotationValue attribute) + public static List getAttributeTypeMirrorList(AnnotationValue attribute) { List values = (attribute != null) ? (List)attribute.getValue() : Collections.emptyList(); return values.stream().map(v -> (TypeMirror)v.getValue()).collect(Collectors.toList()); } + @SuppressWarnings("unchecked") + public static List getAttributeStringList(AnnotationValue attribute) + { + List values = (attribute != null) ? (List)attribute.getValue() : Collections.emptyList(); + return values.stream().map(v -> (String)v.getValue()).collect(Collectors.toList()); + } + public static boolean getBooleanAttribute(AnnotationValue attribute) { Object value = (attribute != null) ? attribute.getValue() : null; diff --git a/record-builder-processor/src/main/java/io/soabase/recordbuilder/processor/IncludeHelper.java b/record-builder-processor/src/main/java/io/soabase/recordbuilder/processor/IncludeHelper.java new file mode 100644 index 0000000..9d5cf56 --- /dev/null +++ b/record-builder-processor/src/main/java/io/soabase/recordbuilder/processor/IncludeHelper.java @@ -0,0 +1,96 @@ +/** + * 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.processor; + +import javax.annotation.processing.ProcessingEnvironment; +import javax.lang.model.element.*; +import javax.lang.model.type.TypeMirror; +import javax.tools.Diagnostic; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +class IncludeHelper { + private final boolean isValid; + private final List classTypeElements; + private final Map annotationValues; + + IncludeHelper(ProcessingEnvironment processingEnv, Element element, AnnotationMirror annotationMirror, boolean packagesSupported) { + annotationValues = processingEnv.getElementUtils().getElementValuesWithDefaults(annotationMirror); + var value = ElementUtils.getAnnotationValue(annotationValues, "value"); + var classes = ElementUtils.getAnnotationValue(annotationValues, "classes"); + var packages = ElementUtils.getAnnotationValue(annotationValues, "packages"); + var isValid = true; + var classTypeElements = new ArrayList(); + if (value.isPresent() || classes.isPresent() || packages.isPresent()) { + var valueList = value.map(ElementUtils::getAttributeTypeMirrorList).orElseGet(List::of); + var classesList = classes.map(ElementUtils::getAttributeTypeMirrorList).orElseGet(List::of); + var packagesList = packages.map(ElementUtils::getAttributeStringList).orElseGet(List::of); + if (valueList.isEmpty() && classesList.isEmpty() && packagesList.isEmpty()) { + if (packagesSupported) { + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "At least one of \"value\", \"classes\" or \"packages\" required", element); + } else { + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "At least one of \"value\" or \"classes\" required", element); + } + isValid = false; + } + isValid = processList(processingEnv, isValid, element, valueList, classTypeElements); + isValid = processList(processingEnv, isValid, element, classesList, classTypeElements); + packages.ifPresent(annotationValue -> processPackages(processingEnv, classTypeElements, packagesList)); + } else { + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Could not read attribute for annotation", element); + isValid = false; + } + this.isValid = isValid; + this.classTypeElements = List.copyOf(classTypeElements); + } + + Map getAnnotationValues() { + return annotationValues; + } + + boolean isValid() { + return isValid; + } + + List getClassTypeElements() { + return classTypeElements; + } + + private boolean processList(ProcessingEnvironment processingEnv, boolean isValid, Element element, List list, ArrayList classTypeElements) { + for (var typeMirror : list) { + TypeElement typeElement = (TypeElement) processingEnv.getTypeUtils().asElement(typeMirror); + if (typeElement == null) { + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Could not get element for: " + typeMirror, element); + isValid = false; + } else { + classTypeElements.add(typeElement); + } + } + return isValid; + } + + private void processPackages(ProcessingEnvironment processingEnv, List classTypeElements, List packagesList) { + for (var packageName : packagesList) { + var packageElement = processingEnv.getElementUtils().getPackageElement(packageName); + for (var child : packageElement.getEnclosedElements()) { + if (child.getKind() == ElementKind.RECORD) { + classTypeElements.add((TypeElement) child); + } + } + } + } +} diff --git a/record-builder-processor/src/main/java/io/soabase/recordbuilder/processor/RecordBuilderProcessor.java b/record-builder-processor/src/main/java/io/soabase/recordbuilder/processor/RecordBuilderProcessor.java index 8e64975..0be6071 100644 --- a/record-builder-processor/src/main/java/io/soabase/recordbuilder/processor/RecordBuilderProcessor.java +++ b/record-builder-processor/src/main/java/io/soabase/recordbuilder/processor/RecordBuilderProcessor.java @@ -29,10 +29,8 @@ import javax.lang.model.SourceVersion; import javax.lang.model.element.Element; import javax.lang.model.element.PackageElement; import javax.lang.model.element.TypeElement; -import javax.lang.model.type.TypeMirror; import javax.tools.Diagnostic; import javax.tools.JavaFileObject; - import java.io.IOException; import java.io.Writer; import java.util.Optional; @@ -40,8 +38,7 @@ import java.util.Set; import java.util.function.Function; public class RecordBuilderProcessor - extends AbstractProcessor -{ + extends AbstractProcessor { 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_INTERFACE = RecordInterface.class.getName(); @@ -51,21 +48,18 @@ public class RecordBuilderProcessor static final AnnotationSpec generatedRecordInterfaceAnnotation = AnnotationSpec.builder(Generated.class).addMember("value", "$S", RecordInterface.class.getName()).build(); @Override - public boolean process(Set annotations, RoundEnvironment roundEnv) - { + public boolean process(Set annotations, RoundEnvironment roundEnv) { annotations.forEach(annotation -> roundEnv.getElementsAnnotatedWith(annotation).forEach(element -> process(annotation, element))); return false; } @Override - public Set getSupportedAnnotationTypes() - { + public Set getSupportedAnnotationTypes() { return Set.of("*"); } @Override - public SourceVersion getSupportedSourceVersion() - { + public SourceVersion getSupportedSourceVersion() { // we don't directly return RELEASE_14 as that may // not exist in prior releases // if we're running on an older release, returning latest() @@ -73,18 +67,15 @@ public class RecordBuilderProcessor return SourceVersion.latest(); } - private void process(TypeElement annotation, Element element) - { + private void process(TypeElement annotation, Element element) { String annotationClass = annotation.getQualifiedName().toString(); if (annotationClass.equals(RECORD_BUILDER)) { var typeElement = (TypeElement) element; processRecordBuilder(typeElement, getMetaData(typeElement), Optional.empty()); - } - else if (annotationClass.equals(RECORD_INTERFACE)) { + } else if (annotationClass.equals(RECORD_INTERFACE)) { var typeElement = (TypeElement) element; 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)) { var metaData = RecordBuilderOptions.build(processingEnv.getOptions()); processIncludes(element, metaData, annotationClass); } else { @@ -104,37 +95,24 @@ public class RecordBuilderProcessor 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 annotationMirrorOpt = ElementUtils.findAnnotationMirror(processingEnv, element, annotationClass); if (annotationMirrorOpt.isEmpty()) { processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Could not get annotation mirror for: " + annotationClass, element); - } - else { - var values = processingEnv.getElementUtils().getElementValuesWithDefaults(annotationMirrorOpt.get()); - var classes = ElementUtils.getAnnotationValue(values, "value"); - if (classes.isEmpty()) { - processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Could not get annotation value for: " + annotationClass, element); - } - else { - var packagePattern = ElementUtils.getStringAttribute(ElementUtils.getAnnotationValue(values, "packagePattern").orElse(null), "*"); - var classesMirrors = ElementUtils.getClassesAttribute(classes.get()); - for (TypeMirror mirror : classesMirrors) { - TypeElement typeElement = (TypeElement) processingEnv.getTypeUtils().asElement(mirror); - if (typeElement == null) { - processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Could not get element for: " + mirror, element); - } - else { - var packageName = buildPackageName(packagePattern, element, typeElement); - if (packageName != null) { - if (annotationClass.equals(RECORD_INTERFACE_INCLUDE)) { - var addRecordBuilderOpt = ElementUtils.getAnnotationValue(values, "addRecordBuilder"); - var addRecordBuilder = addRecordBuilderOpt.map(ElementUtils::getBooleanAttribute).orElse(true); - processRecordInterface(typeElement, addRecordBuilder, metaData, Optional.of(packageName), false); - } - else { - processRecordBuilder(typeElement, metaData, Optional.of(packageName)); - } + } else { + var includeHelper = new IncludeHelper(processingEnv, element, annotationMirrorOpt.get(), isRecordBuilderInclude); + if (includeHelper.isValid()) { + var packagePattern = ElementUtils.getStringAttribute(ElementUtils.getAnnotationValue(includeHelper.getAnnotationValues(), "packagePattern").orElse(null), "*"); + for (var typeElement : includeHelper.getClassTypeElements()) { + var packageName = buildPackageName(packagePattern, element, typeElement); + if (packageName != null) { + if (isRecordBuilderInclude) { + processRecordBuilder(typeElement, metaData, Optional.of(packageName)); + } else { + var addRecordBuilderOpt = ElementUtils.getAnnotationValue(includeHelper.getAnnotationValues(), "addRecordBuilder"); + var addRecordBuilder = addRecordBuilderOpt.map(ElementUtils::getBooleanAttribute).orElse(true); + processRecordInterface(typeElement, addRecordBuilder, metaData, Optional.of(packageName), false); } } } @@ -142,8 +120,7 @@ public class RecordBuilderProcessor } } - private String buildPackageName(String packagePattern, Element builderElement, TypeElement includedClass) - { + private String buildPackageName(String packagePattern, Element builderElement, TypeElement includedClass) { PackageElement includedClassPackage = findPackageElement(includedClass, includedClass); if (includedClassPackage == null) { return null; @@ -155,8 +132,7 @@ public class RecordBuilderProcessor return replaced.replace("@", ((PackageElement) builderElement.getEnclosingElement()).getQualifiedName().toString()); } - private PackageElement findPackageElement(Element actualElement, Element includedClass) - { + private PackageElement findPackageElement(Element actualElement, Element includedClass) { if (includedClass == null) { processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Element has not package", actualElement); return null; @@ -167,8 +143,7 @@ public class RecordBuilderProcessor return findPackageElement(actualElement, includedClass.getEnclosingElement()); } - private void processRecordInterface(TypeElement element, boolean addRecordBuilder, RecordBuilder.Options metaData, Optional packageName, boolean fromTemplate) - { + private void processRecordInterface(TypeElement element, boolean addRecordBuilder, RecordBuilder.Options metaData, Optional packageName, boolean fromTemplate) { if (!element.getKind().isInterface()) { processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "RecordInterface only valid for interfaces.", element); return; @@ -180,8 +155,7 @@ public class RecordBuilderProcessor writeRecordInterfaceJavaFile(element, internalProcessor.packageName(), internalProcessor.recordClassType(), internalProcessor.recordType(), metaData, internalProcessor::toRecord); } - private void processRecordBuilder(TypeElement record, RecordBuilder.Options metaData, Optional packageName) - { + private void processRecordBuilder(TypeElement record, RecordBuilder.Options metaData, Optional packageName) { // we use string based name comparison for the element kind, // as the ElementKind.RECORD enum doesn't exist on JRE releases // older than Java 14, and we don't want to throw unexpected @@ -194,8 +168,7 @@ public class RecordBuilderProcessor 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 JavaFile javaFile = javaFileBuilder(packageName, builderType, metaData); Filer filer = processingEnv.getFiler(); @@ -205,14 +178,12 @@ public class RecordBuilderProcessor try (Writer writer = sourceFile.openWriter()) { javaFile.writeTo(writer); } - } - catch (IOException e) { + } catch (IOException e) { handleWriteError(record, e); } } - private void writeRecordInterfaceJavaFile(TypeElement element, String packageName, ClassType classType, TypeSpec type, RecordBuilder.Options metaData, Function toRecordProc) - { + private void writeRecordInterfaceJavaFile(TypeElement element, String packageName, ClassType classType, TypeSpec type, RecordBuilder.Options metaData, Function toRecordProc) { JavaFile javaFile = javaFileBuilder(packageName, type, metaData); String classSourceCode = javaFile.toString(); @@ -226,14 +197,12 @@ public class RecordBuilderProcessor try (Writer writer = sourceFile.openWriter()) { writer.write(recordSourceCode); } - } - catch (IOException e) { + } catch (IOException e) { handleWriteError(element, e); } } - 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 comment = metaData.fileComment(); if ((comment != null) && !comment.isEmpty()) { @@ -242,8 +211,7 @@ public class RecordBuilderProcessor return javaFileBuilder.build(); } - private void handleWriteError(TypeElement element, IOException e) - { + private void handleWriteError(TypeElement element, IOException e) { String message = "Could not create source file"; if (e.getMessage() != null) { message = message + ": " + e.getMessage(); diff --git a/record-builder-test/src/main/java/io/soabase/recordbuilder/test/includes/IncludeFactory.java b/record-builder-test/src/main/java/io/soabase/recordbuilder/test/includes/IncludeFactory.java new file mode 100644 index 0000000..a31c943 --- /dev/null +++ b/record-builder-test/src/main/java/io/soabase/recordbuilder/test/includes/IncludeFactory.java @@ -0,0 +1,25 @@ +/** + * 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.includes; + +import io.soabase.recordbuilder.core.RecordBuilder; + +@RecordBuilder.Include( + packages = "io.soabase.recordbuilder.test.includes.pack", + classes = JustATest.class +) +public class IncludeFactory { +} diff --git a/record-builder-test/src/main/java/io/soabase/recordbuilder/test/includes/JustATest.java b/record-builder-test/src/main/java/io/soabase/recordbuilder/test/includes/JustATest.java new file mode 100644 index 0000000..4767364 --- /dev/null +++ b/record-builder-test/src/main/java/io/soabase/recordbuilder/test/includes/JustATest.java @@ -0,0 +1,19 @@ +/** + * 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.includes; + +public record JustATest(int i) { +} diff --git a/record-builder-test/src/main/java/io/soabase/recordbuilder/test/includes/pack/AlsoIgnoreMe.java b/record-builder-test/src/main/java/io/soabase/recordbuilder/test/includes/pack/AlsoIgnoreMe.java new file mode 100644 index 0000000..eefb885 --- /dev/null +++ b/record-builder-test/src/main/java/io/soabase/recordbuilder/test/includes/pack/AlsoIgnoreMe.java @@ -0,0 +1,19 @@ +/** + * 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.includes.pack; + +public interface AlsoIgnoreMe { +} diff --git a/record-builder-test/src/main/java/io/soabase/recordbuilder/test/includes/pack/IgnoreMe.java b/record-builder-test/src/main/java/io/soabase/recordbuilder/test/includes/pack/IgnoreMe.java new file mode 100644 index 0000000..921c170 --- /dev/null +++ b/record-builder-test/src/main/java/io/soabase/recordbuilder/test/includes/pack/IgnoreMe.java @@ -0,0 +1,19 @@ +/** + * 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.includes.pack; + +public class IgnoreMe { +} diff --git a/record-builder-test/src/main/java/io/soabase/recordbuilder/test/includes/pack/PackRecord1.java b/record-builder-test/src/main/java/io/soabase/recordbuilder/test/includes/pack/PackRecord1.java new file mode 100644 index 0000000..6578622 --- /dev/null +++ b/record-builder-test/src/main/java/io/soabase/recordbuilder/test/includes/pack/PackRecord1.java @@ -0,0 +1,19 @@ +/** + * 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.includes.pack; + +public record PackRecord1(String name) { +} diff --git a/record-builder-test/src/main/java/io/soabase/recordbuilder/test/includes/pack/PackRecord2.java b/record-builder-test/src/main/java/io/soabase/recordbuilder/test/includes/pack/PackRecord2.java new file mode 100644 index 0000000..f7a4900 --- /dev/null +++ b/record-builder-test/src/main/java/io/soabase/recordbuilder/test/includes/pack/PackRecord2.java @@ -0,0 +1,19 @@ +/** + * 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.includes.pack; + +public record PackRecord2(String name, int age) { +} diff --git a/record-builder-test/src/main/java/io/soabase/recordbuilder/test/includes/pack/PackRecord3.java b/record-builder-test/src/main/java/io/soabase/recordbuilder/test/includes/pack/PackRecord3.java new file mode 100644 index 0000000..6c053d2 --- /dev/null +++ b/record-builder-test/src/main/java/io/soabase/recordbuilder/test/includes/pack/PackRecord3.java @@ -0,0 +1,21 @@ +/** + * 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.includes.pack; + +import java.time.Instant; + +public record PackRecord3(Instant time, int age) { +}