From cd145767225221ba12fd8171fd676686452ba252 Mon Sep 17 00:00:00 2001 From: Jordan Zimmerman Date: Sun, 24 Mar 2024 10:41:02 +0000 Subject: [PATCH] Record support From https://github.com/square/javapoet/pull/981 User: @zzBBc --- README.md | 2 + pom.xml | 2 +- .../java/com/squareup/javapoet/TypeSpec.java | 64 +++++++++++++++---- .../com/squareup/javapoet/JavaFileTest.java | 38 ++++++++--- 4 files changed, 81 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index eecac62..b7313f4 100644 --- a/README.md +++ b/README.md @@ -8,4 +8,6 @@ Please see [JavaPoet](https://github.com/square/javapoet) for documentation, lic # Changes From JavaPoet +### March 24, 2024 - Require Java 17 +- Add record support from https://github.com/square/javapoet/pull/981 diff --git a/pom.xml b/pom.xml index 9ac2b0c..e8d2645 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - org.example + io.soabase.java-composer java-composer 1.0-SNAPSHOT diff --git a/src/main/java/com/squareup/javapoet/TypeSpec.java b/src/main/java/com/squareup/javapoet/TypeSpec.java index 6fdd6d8..02abf2e 100644 --- a/src/main/java/com/squareup/javapoet/TypeSpec.java +++ b/src/main/java/com/squareup/javapoet/TypeSpec.java @@ -15,15 +15,6 @@ */ package com.squareup.javapoet; -import javax.lang.model.SourceVersion; -import javax.lang.model.element.Element; -import javax.lang.model.element.Modifier; -import javax.lang.model.element.TypeElement; -import javax.lang.model.type.DeclaredType; -import javax.lang.model.type.NoType; -import javax.lang.model.type.TypeMirror; -import javax.lang.model.util.ElementFilter; - import java.io.IOException; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; @@ -39,6 +30,14 @@ import java.util.Locale; import java.util.Map; import java.util.Set; +import javax.lang.model.SourceVersion; +import javax.lang.model.element.Element; +import javax.lang.model.element.Modifier; +import javax.lang.model.element.TypeElement; +import javax.lang.model.type.DeclaredType; +import javax.lang.model.type.NoType; +import javax.lang.model.type.TypeMirror; +import javax.lang.model.util.ElementFilter; import static com.squareup.javapoet.Util.checkArgument; import static com.squareup.javapoet.Util.checkNotNull; @@ -133,6 +132,15 @@ public static Builder classBuilder(ClassName className) { return classBuilder(checkNotNull(className, "className == null").simpleName()); } + public static Builder recordBuilder(String name) { + return new Builder(Kind.RECORD, checkNotNull(name, "name == null"), null); + } + + public static Builder recordBuilder(ClassName className) { + return recordBuilder(checkNotNull(className, "className == null").simpleName()); + } + + public static Builder interfaceBuilder(String name) { return new Builder(Kind.INTERFACE, checkNotNull(name, "name == null"), null); } @@ -229,6 +237,26 @@ void emit(CodeWriter codeWriter, String enumName, Set implicitModifier if (kind == Kind.INTERFACE) { extendsTypes = superinterfaces; implementsTypes = Collections.emptyList(); + } else if (kind == Kind.RECORD) { + extendsTypes = Collections.emptyList(); + implementsTypes = superinterfaces; + + // Record constructor + boolean firstParameter = true; + codeWriter.emit("("); + int fieldSpecsLength = fieldSpecs.size(); + for (int i = 0; i < fieldSpecsLength; i++) { + FieldSpec fieldSpec = fieldSpecs.get(i); + + if (fieldSpec.hasModifier(Modifier.STATIC)) + continue; + ParameterSpec parameter = ParameterSpec.builder(fieldSpec.type, fieldSpec.name).build(); + if (!firstParameter) + codeWriter.emit(",").emitWrappingSpace(); + parameter.emit(codeWriter, !(i < fieldSpecsLength)); + firstParameter = false; + } + codeWriter.emit(")"); } else { extendsTypes = superclass.equals(ClassName.OBJECT) ? Collections.emptyList() @@ -296,11 +324,16 @@ void emit(CodeWriter codeWriter, String enumName, Set implicitModifier } // Non-static fields. - for (FieldSpec fieldSpec : fieldSpecs) { - if (fieldSpec.hasModifier(Modifier.STATIC)) continue; - if (!firstMember) codeWriter.emit("\n"); - fieldSpec.emit(codeWriter, kind.implicitFieldModifiers); - firstMember = false; + // If kind RECORD, ignore generate Non-static field + if (!(Kind.RECORD == kind)) { + for (FieldSpec fieldSpec : fieldSpecs) { + if (fieldSpec.hasModifier(Modifier.STATIC)) + continue; + if (!firstMember) + codeWriter.emit("\n"); + fieldSpec.emit(codeWriter, kind.implicitFieldModifiers); + firstMember = false; + } } // Initializer block. @@ -375,6 +408,9 @@ public enum Kind { Collections.emptySet(), Collections.emptySet()), + RECORD(Collections.emptySet(), Collections.emptySet(), Collections.emptySet(), + Collections.emptySet()), + INTERFACE( Util.immutableSet(Arrays.asList(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)), Util.immutableSet(Arrays.asList(Modifier.PUBLIC, Modifier.ABSTRACT)), diff --git a/src/test/java/com/squareup/javapoet/JavaFileTest.java b/src/test/java/com/squareup/javapoet/JavaFileTest.java index 902eec3..6aa5d94 100644 --- a/src/test/java/com/squareup/javapoet/JavaFileTest.java +++ b/src/test/java/com/squareup/javapoet/JavaFileTest.java @@ -15,17 +15,8 @@ */ package com.squareup.javapoet; -import com.google.testing.compile.CompilationRule; -import org.junit.Ignore; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -import javax.lang.model.element.Modifier; -import javax.lang.model.element.TypeElement; - import java.io.File; +import com.google.testing.compile.CompilationRule; import java.util.Collections; import java.util.Date; import java.util.List; @@ -33,6 +24,13 @@ import java.util.Optional; import java.util.concurrent.TimeUnit; import java.util.regex.Pattern; +import javax.lang.model.element.Modifier; +import javax.lang.model.element.TypeElement; +import org.junit.Ignore; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; import static com.google.common.truth.Truth.assertThat; @@ -287,6 +285,26 @@ private TypeSpec importStaticTypeSpec(String name) { + "}\n"); } + @Test + public void recordNoField() { + String source = JavaFile.builder("com.squareup.tacos", TypeSpec.recordBuilder("Taco").build()) + .skipJavaLangImports(true).build().toString(); + assertThat(source).isEqualTo( + "" + "package com.squareup.tacos;\n" + "\n" + "record Taco() {\n" + "}\n" + ""); + } + + @Test + public void recordTwoField() { + String source = JavaFile + .builder("com.squareup.tacos", + TypeSpec.recordBuilder("Taco") + .addField(FieldSpec.builder(String.class, "name").build()) + .addField(FieldSpec.builder(Integer.class, "code").build()).build()) + .skipJavaLangImports(true).build().toString(); + assertThat(source).isEqualTo("" + "package com.squareup.tacos;\n" + "\n" + + "record Taco(String name, Integer code) {\n" + "}\n" + ""); + } + @Test public void conflictingImports() throws Exception { String source = JavaFile.builder("com.squareup.tacos", TypeSpec.classBuilder("Taco")