From 36b03dc5c053926c959e78404dbfa4693d325077 Mon Sep 17 00:00:00 2001 From: Andriy Dmytruk <80816836+andriy-dmytruk@users.noreply.github.com> Date: Fri, 9 Feb 2024 11:19:53 -0500 Subject: [PATCH] Change record style (#57) - Use consistent code writer api. - Add extra indentation to record parameters. --- .../sourcegen/javapoet/MethodSpec.java | 23 ++++--- .../sourcegen/javapoet/TypeSpecTest.java | 14 ++-- .../javapoet/write/RecordWriteTest.java | 67 +++++++++++++++++++ 3 files changed, 87 insertions(+), 17 deletions(-) create mode 100644 sourcegen-generator-java/src/test/java/io/micronaut/sourcegen/javapoet/write/RecordWriteTest.java diff --git a/sourcegen-generator-java/src/main/java/io/micronaut/sourcegen/javapoet/MethodSpec.java b/sourcegen-generator-java/src/main/java/io/micronaut/sourcegen/javapoet/MethodSpec.java index 2f55fc4d..8ee52974 100644 --- a/sourcegen-generator-java/src/main/java/io/micronaut/sourcegen/javapoet/MethodSpec.java +++ b/sourcegen-generator-java/src/main/java/io/micronaut/sourcegen/javapoet/MethodSpec.java @@ -158,26 +158,29 @@ static CodeBlock makeJavadocWithParameters(CodeBlock javadoc, static void emitParameters(CodeWriter codeWriter, Iterable parameters, boolean varargs, boolean isRecord) throws IOException { - codeWriter.emit(CodeBlock.of("($Z")); + Iterator paramIter = parameters.iterator(); + boolean hasParameters = paramIter.hasNext(); + codeWriter.emit(CodeBlock.of("($Z"), isRecord && hasParameters); - boolean hasParameters = false; boolean firstParameter = true; - for (Iterator i = parameters.iterator(); i.hasNext(); ) { + if (isRecord && hasParameters) { + codeWriter.indent(2); + } + while (paramIter.hasNext()) { hasParameters = true; - ParameterSpec parameter = i.next(); + ParameterSpec parameter = paramIter.next(); if (!firstParameter) { - codeWriter.emit(","); + codeWriter.emit(CodeBlock.of(","), isRecord); if (!isRecord) codeWriter.emitWrappingSpace(); } - if (isRecord) - codeWriter.emit("\n "); - parameter.emit(codeWriter, !i.hasNext() && varargs); + parameter.emit(codeWriter, !paramIter.hasNext() && varargs); firstParameter = false; } - if (isRecord && hasParameters) { - codeWriter.emit("\n"); + codeWriter.unindent(2); + // Add new line in the end + codeWriter.emit(CodeBlock.of(""), true); } codeWriter.emit(")"); } diff --git a/sourcegen-generator-java/src/test/java/io/micronaut/sourcegen/javapoet/TypeSpecTest.java b/sourcegen-generator-java/src/test/java/io/micronaut/sourcegen/javapoet/TypeSpecTest.java index 3cf98ab1..53f2628d 100644 --- a/sourcegen-generator-java/src/test/java/io/micronaut/sourcegen/javapoet/TypeSpecTest.java +++ b/sourcegen-generator-java/src/test/java/io/micronaut/sourcegen/javapoet/TypeSpecTest.java @@ -365,8 +365,8 @@ public void basicRecord() throws Exception { + "import java.lang.String;\n" + "\n" + "public record KeyValue(\n" - + " String key,\n" - + " String value\n" + + " String key,\n" + + " String value\n" + ") implements Cloneable {\n" + " public KeyValue {\n" + " if (key.indexOf(':') != -1) {\n" @@ -421,8 +421,8 @@ public void varargsRecord() throws Exception { + "import java.lang.String;\n" + "\n" + "public record Vararg(\n" - + " int val,\n" - + " String... keys\n" + + " int val,\n" + + " String... keys\n" + ") {\n" + "}\n"); } @@ -1327,8 +1327,8 @@ public void recordComponentJavadoc() throws Exception { + " * @param soft true for a soft flour tortilla, or false for a crunchy corn tortilla\n" + " */\n" + "record Taco(\n" - + " String shell,\n" - + " boolean soft\n" + + " String shell,\n" + + " boolean soft\n" + ") {\n" + " /**\n" + " * Makes a taco without a cat :(.\n" @@ -1608,7 +1608,7 @@ public void recordComponentJavadoc() throws Exception { + " }\n" + "\n" + " record Veggie(\n" - + " int name\n" + + " int name\n" + " ) {\n" + " }\n" + "}\n"); diff --git a/sourcegen-generator-java/src/test/java/io/micronaut/sourcegen/javapoet/write/RecordWriteTest.java b/sourcegen-generator-java/src/test/java/io/micronaut/sourcegen/javapoet/write/RecordWriteTest.java new file mode 100644 index 00000000..33a21cd3 --- /dev/null +++ b/sourcegen-generator-java/src/test/java/io/micronaut/sourcegen/javapoet/write/RecordWriteTest.java @@ -0,0 +1,67 @@ +package io.micronaut.sourcegen.javapoet.write; + +import io.micronaut.sourcegen.JavaPoetSourceGenerator; +import io.micronaut.sourcegen.model.AnnotationDef; +import io.micronaut.sourcegen.model.ClassTypeDef; +import io.micronaut.sourcegen.model.PropertyDef; +import io.micronaut.sourcegen.model.RecordDef; +import org.junit.Test; + +import java.io.IOException; +import java.io.StringWriter; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +public class RecordWriteTest { + + + @Test + public void writeSimpleRecord() throws IOException { + RecordDef recordDef = RecordDef.builder("test.TestRecord") + .addProperty(PropertyDef.builder("name").ofType(String.class).build()) + .addProperty(PropertyDef.builder("age").ofType(Integer.class) + .addAnnotation(AnnotationDef.builder( + ClassTypeDef.of("jakarta.validation.constraints.Min")) + .addMember("value", 1).build()) + .build() + ) + .addProperty(PropertyDef.builder("description").ofType(String.class) + .addAnnotation("jakarta.validation.constraints.NotBlank") + .build() + ) + .build(); + var result = writeRecord(recordDef); + + var expected = """ + record TestRecord( + String name, + @Min(1) Integer age, + @NotBlank String description + ) { + } + """; + assertEquals(expected.strip(), result.strip()); + } + + private String writeRecord(RecordDef recordDef) throws IOException { + JavaPoetSourceGenerator generator = new JavaPoetSourceGenerator(); + String result; + try (StringWriter writer = new StringWriter()) { + generator.write(recordDef, writer); + result = writer.toString(); + } + + // The regex will skip the imports and make sure it is a record + final Pattern RECORD_REGEX = Pattern.compile("package [^;]+;[\\s\\S]+" + + "(record \\S+[\\s\\S]+})\\s*"); + Matcher matcher = RECORD_REGEX.matcher(result); + if (!matcher.matches()) { + fail("Expected record to match regex: \n" + RECORD_REGEX + "\nbut is: \n" + result); + } + return matcher.group(1); + } + +}