From 896d995476925872d9e28dcc3faaa44bde074379 Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Mon, 28 Aug 2023 11:37:17 +0200 Subject: [PATCH] [jOOQ/jOOQ#228] Added ScalaGenerator support This includes: - Refactor Internal methods, remove unnecessary type variables --- .../org/jooq/codegen/AbstractGenerator.java | 4 +- .../java/org/jooq/codegen/JavaGenerator.java | 89 ++++++++++++++----- .../src/main/java/org/jooq/impl/Internal.java | 44 ++++----- pom.xml | 2 +- 4 files changed, 91 insertions(+), 48 deletions(-) diff --git a/jOOQ-codegen/src/main/java/org/jooq/codegen/AbstractGenerator.java b/jOOQ-codegen/src/main/java/org/jooq/codegen/AbstractGenerator.java index 6f95f1b812..b352db08c0 100644 --- a/jOOQ-codegen/src/main/java/org/jooq/codegen/AbstractGenerator.java +++ b/jOOQ-codegen/src/main/java/org/jooq/codegen/AbstractGenerator.java @@ -310,8 +310,8 @@ abstract class AbstractGenerator implements Generator { @Override public boolean generateUDTPaths() { - // [#228] TODO: Support this also in Scala and Kotlin - return generateUDTPaths && language == Language.JAVA; + // [#228] TODO: Support this also in Kotlin + return generateUDTPaths && language != Language.KOTLIN; } @Override diff --git a/jOOQ-codegen/src/main/java/org/jooq/codegen/JavaGenerator.java b/jOOQ-codegen/src/main/java/org/jooq/codegen/JavaGenerator.java index b8a4db27b0..941810971c 100644 --- a/jOOQ-codegen/src/main/java/org/jooq/codegen/JavaGenerator.java +++ b/jOOQ-codegen/src/main/java/org/jooq/codegen/JavaGenerator.java @@ -3383,9 +3383,27 @@ public class JavaGenerator extends AbstractGenerator { generateUDTPathClassJavadoc(udt, out); printClassAnnotations(out, udt, Mode.PATH); - out.println("%sclass %s extends %s[[before= implements ][%s]] {", - visibility(), className, Record.class, classExtends, recordType, interfaces); - out.printSerial(); + if (scala) { + out.println("%sclass %s[R <: %s, T](", visibility(), className, Record.class); + out.println("name: %s,", Name.class); + out.println("klass: %s[T],", DataType.class); + out.println("qualifier: %s[R],", RecordQualifier.class); + out.println("comment: %s,", Comment.class); + out.println("binding: %s[_, T]", Binding.class); + out.println(")"); + out.println("extends %s[R, %s, T](", classExtends, recordType); + out.println("name, klass, qualifier, %s, comment, binding", udtId); + if (interfaces.isEmpty()) + out.println(") {"); + else + out.println(")") + .println("[[before= with ][separator= with ][%s]] {", interfaces); + } + else { + out.println("%sclass %s extends %s[[before= implements ][%s]] {", + visibility(), className, Record.class, classExtends, recordType, interfaces); + out.printSerial(); + } for (AttributeDefinition attribute : udt.getAttributes()) { final String attrTypeFull = getJavaType(attribute.getType(resolver(out)), out); @@ -3395,31 +3413,45 @@ public class JavaGenerator extends AbstractGenerator { final String attrName = attribute.getName(); final List converter = out.ref(list(attribute.getType(resolver(out)).getConverter())); final List binding = out.ref(list(attribute.getType(resolver(out)).getBinding())); + final boolean udtPath = attribute.getType().isUDT() && !attribute.getDatabase().isArrayType(attribute.getType().getType()); + if (!printDeprecationIfUnknownType(out, attrTypeFull)) out.javadoc("The attribute %s.[[before= ][%s]]", attribute.getQualifiedOutputName(), list(escapeEntities(comment(attribute)))); - if (attribute.getType().isUDT() && !attribute.getDatabase().isArrayType(attrTypeFull)) { + if (udtPath) { final SchemaDefinition attrUdtSchema = attribute.getDatabase().getSchema(attribute.getType().getQualifiedUserType().qualifier().last()); final UDTDefinition attrUdt = attribute.getDatabase().getUDT(attrUdtSchema, attribute.getType().getUserType()); final String attrPathType = out.ref(getStrategy().getFullJavaClassName(attrUdt, Mode.PATH)); - out.println("%sfinal %s<%s, %s> %s = %s.createUDTPathField(%s.name(\"%s\"), %s, this, \"%s\", %s.class" + converterTemplate(converter) + converterTemplate(binding) + ");", - visibility(), attrPathType, recordType, attrType, attrId, Internal.class, DSL.class, escapeString(attrName), attrTypeRef, escapeString(""), attrPathType, converter, binding); + if (scala) + out.println("%sval %s: %s[%s, %s] = %s.createUDTPathField[ %s, %s[%s, %s] ](%s.name(\"%s\"), %s, this, \"%s\", classOf[ %s[%s, %s] ]" + converterTemplate(converter) + converterTemplate(binding) + ")", + visibility(), scalaWhitespaceSuffix(attrId), attrPathType, recordType, attrType, Internal.class, attrType, attrPathType, recordType, attrType, DSL.class, escapeString(attrName), attrTypeRef, escapeString(""), attrPathType, recordType, attrType, converter, binding); + else + out.println("%sfinal %s<%s, %s> %s = %s.createUDTPathField(%s.name(\"%s\"), %s, this, \"%s\", %s.class" + converterTemplate(converter) + converterTemplate(binding) + ");", + visibility(), attrPathType, recordType, attrType, attrId, Internal.class, DSL.class, escapeString(attrName), attrTypeRef, escapeString(""), attrPathType, converter, binding); } else { final String attrPathType = out.ref(UDTField.class); - out.println("%sfinal %s<%s, %s> %s = %s.createUDTPathField(%s.name(\"%s\"), %s, this, \"%s\", %s.class" + converterTemplate(converter) + converterTemplate(binding) + ");", - visibility(), attrPathType, recordType, attrType, attrId, Internal.class, DSL.class, escapeString(attrName), attrTypeRef, escapeString(""), attrPathType, converter, binding); + if (scala) + out.println("%sval %s: %s[%s, %s] = %s.createUDTPathField(%s.name(\"%s\"), %s, this, \"%s\", classOf[ %s[%s, %s] ]" + converterTemplate(converter) + converterTemplate(binding) + ")", + visibility(), scalaWhitespaceSuffix(attrId), attrPathType, recordType, attrType, Internal.class, DSL.class, escapeString(attrName), attrTypeRef, escapeString(""), attrPathType, recordType, attrType, converter, binding); + else + out.println("%sfinal %s<%s, %s> %s = %s.createUDTPathField(%s.name(\"%s\"), %s, this, \"%s\", %s.class" + converterTemplate(converter) + converterTemplate(binding) + ");", + visibility(), attrPathType, recordType, attrType, attrId, Internal.class, DSL.class, escapeString(attrName), attrTypeRef, escapeString(""), attrPathType, converter, binding); } } out.println(); - out.println("%s%s(%s name, %s type, %s qualifier, %s comment, %s binding) {", - visibility(), className, Name.class, DataType.class, RecordQualifier.class, Comment.class, Binding.class); - out.println("super(name, type, qualifier, %s, comment, binding);", udtId); - out.println("}"); + + if (scala) {} + else { + out.println("%s%s(%s name, %s type, %s qualifier, %s comment, %s binding) {", + visibility(), className, Name.class, DataType.class, RecordQualifier.class, Comment.class, Binding.class); + out.println("super(name, type, qualifier, %s, comment, binding);", udtId); + out.println("}"); + } generateUDTPathClassFooter(udt, out); out.println("}"); @@ -6373,6 +6405,9 @@ public class JavaGenerator extends AbstractGenerator { final String columnVisibility; + final boolean udtPath = generateUDTPaths() + && column.getType().isUDT() + && !column.getDatabase().isArrayType(column.getType().getType()); @@ -6390,30 +6425,36 @@ public class JavaGenerator extends AbstractGenerator { out.javadoc("The column %s.[[before= ][%s]]", column.getQualifiedOutputName(), list(escapeEntities(comment(column)))); if (scala) { + if (udtPath) { + final SchemaDefinition columnUdtSchema = column.getDatabase().getSchema(column.getType().getQualifiedUserType().qualifier().last()); + final UDTDefinition columnUdt = column.getDatabase().getUDT(columnUdtSchema, column.getType().getUserType()); + final String columnPathType = out.ref(getStrategy().getFullJavaClassName(columnUdt, Mode.PATH)); + + out.println("%sval %s: %s[%s, %s] = %s.createUDTPathTableField[ %s, %s, %s[%s, %s] ](%s.name(\"%s\"), %s, this, \"%s\", classOf[ %s[%s, %s] ]" + converterTemplate(converter) + converterTemplate(binding) + ")", + columnVisibility, scalaWhitespaceSuffix(columnId), columnPathType, recordType, columnType, Internal.class, recordType, columnType, columnPathType, recordType, columnType, DSL.class, escapeString(columnName), columnTypeRef, escapeString(comment(column)), columnPathType, recordType, columnType, converter, binding); + } + // [#9879] In scala, subclasses cannot call a superclass protected static method // only a superclass protected instance method. But to capture the Generator // type variable, we need to pass it explicitly. The relevant createField0() method // can't be overloaded, so it has that "0" suffix... - if (generator.isEmpty()) + // [#15505] TODO: Use Internal API instead + else if (generator.isEmpty()) out.println("%sval %s: %s[%s, %s] = createField(%s.name(\"%s\"), %s, \"%s\"" + converterTemplate(converter) + converterTemplate(binding) + converterTemplate(generator) + ")", - columnVisibility, scalaWhitespaceSuffix(columnId), TableField.class, recordType, columnType, DSL.class, columnName, columnTypeRef, escapeString(comment(column)), converter, binding, generator); + columnVisibility, scalaWhitespaceSuffix(columnId), TableField.class, recordType, columnType, DSL.class, escapeString(columnName), columnTypeRef, escapeString(comment(column)), converter, binding, generator); else out.println("%sval %s: %s[%s, %s] = createField0(%s.name(\"%s\"), %s, this, \"%s\"" + converterTemplate(converter) + converterTemplate(binding) + converterTemplate(generator) + ")", - columnVisibility, scalaWhitespaceSuffix(columnId), TableField.class, recordType, columnType, DSL.class, columnName, columnTypeRef, escapeString(comment(column)), converter, binding, generator); + columnVisibility, scalaWhitespaceSuffix(columnId), TableField.class, recordType, columnType, DSL.class, escapeString(columnName), columnTypeRef, escapeString(comment(column)), converter, binding, generator); } else if (kotlin) { out.println("%sval %s: %s<%s, %s?> = createField(%s.name(\"%s\"), %s, this, \"%s\"" + converterTemplate(converter) + converterTemplate(binding) + converterTemplate(generator) + ")", - columnVisibility, columnId, TableField.class, recordType, columnType, DSL.class, columnName, columnTypeRef, escapeString(comment(column)), converter, binding, generator); + columnVisibility, columnId, TableField.class, recordType, columnType, DSL.class, escapeString(columnName), columnTypeRef, escapeString(comment(column)), converter, binding, generator); } else { String isStatic = generateInstanceFields() ? "" : "static "; String tableRef = generateInstanceFields() ? "this" : out.ref(getStrategy().getJavaIdentifier(table), 2); - if (generateInstanceFields() - && generateUDTPaths() - && column.getType().isUDT() - && !column.getDatabase().isArrayType(columnTypeFull) - ) { + if (generateInstanceFields() && udtPath) { final SchemaDefinition columnUdtSchema = column.getDatabase().getSchema(column.getType().getQualifiedUserType().qualifier().last()); final UDTDefinition columnUdt = column.getDatabase().getUDT(columnUdtSchema, column.getType().getUserType()); final String columnPathType = out.ref(getStrategy().getFullJavaClassName(columnUdt, Mode.PATH)); @@ -6423,7 +6464,7 @@ public class JavaGenerator extends AbstractGenerator { } else out.println("%s%sfinal %s<%s, %s> %s = createField(%s.name(\"%s\"), %s, %s, \"%s\"" + converterTemplate(converter) + converterTemplate(binding) + converterTemplate(generator) + ");", - columnVisibility, isStatic, TableField.class, recordType, columnType, columnId, DSL.class, columnName, columnTypeRef, tableRef, escapeString(comment(column)), converter, binding, generator); + columnVisibility, isStatic, TableField.class, recordType, columnType, columnId, DSL.class, escapeString(columnName), columnTypeRef, tableRef, escapeString(comment(column)), converter, binding, generator); } } @@ -10553,8 +10594,10 @@ public class JavaGenerator extends AbstractGenerator { } private void appendGetDataTypeCall(StringBuilder sb) { - if (language == KOTLIN) + if (kotlin) sb.append(".dataType"); + else if (scala) + sb.append(".getDataType"); else sb.append(".getDataType()"); } diff --git a/jOOQ/src/main/java/org/jooq/impl/Internal.java b/jOOQ/src/main/java/org/jooq/impl/Internal.java index 868946b9dc..8373c92f35 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Internal.java +++ b/jOOQ/src/main/java/org/jooq/impl/Internal.java @@ -125,7 +125,7 @@ import org.reactivestreams.Subscription; @org.jooq.Internal public final class Internal { - public static final , T, P extends UDTPathTableField> P createUDTPathTableField( + public static final > P createUDTPathTableField( Name name, DataType type, Table table, @@ -134,7 +134,7 @@ public final class Internal { return createUDTPathTableField(name, type, table, null, returnType, null, null, null); } - public static final , T, P extends UDTPathTableField> P createUDTPathTableField( + public static final > P createUDTPathTableField( Name name, DataType type, Table table, @@ -144,7 +144,7 @@ public final class Internal { return createUDTPathTableField(name, type, table, comment, returnType, null, null, null); } - public static final , T, U, P extends UDTPathTableField> P createUDTPathTableField( + public static final > P createUDTPathTableField( Name name, DataType type, Table table, @@ -155,7 +155,7 @@ public final class Internal { return createUDTPathTableField(name, type, table, comment, returnType, converter, null, null); } - public static final , T, U, P extends UDTPathTableField> P createUDTPathTableField( + public static final > P createUDTPathTableField( Name name, DataType type, Table table, @@ -166,7 +166,7 @@ public final class Internal { return createUDTPathTableField(name, type, table, comment, returnType, null, binding, null); } - public static final , T, X, U, P extends UDTPathTableField> P createUDTPathTableField( + public static final > P createUDTPathTableField( Name name, DataType type, Table table, @@ -178,7 +178,7 @@ public final class Internal { return createUDTPathTableField(name, type, table, comment, returnType, converter, binding, null); } - public static final , UR extends UDTRecord, T, P extends UDTPathTableField> P createUDTPathTableField( + public static final , T, P extends UDTPathTableField> P createUDTPathTableField( Name name, DataType type, TR table, @@ -189,7 +189,7 @@ public final class Internal { return createUDTPathTableField(name, type, table, comment, returnType, null, null, generator); } - public static final , UR extends UDTRecord, T, U, P extends UDTPathTableField> P createUDTPathTableField( + public static final , T, U, P extends UDTPathTableField> P createUDTPathTableField( Name name, DataType type, TR table, @@ -201,7 +201,7 @@ public final class Internal { return createUDTPathTableField(name, type, table, comment, returnType, converter, null, generator); } - public static final , UR extends UDTRecord, T, U, P extends UDTPathTableField> P createUDTPathTableField( + public static final , T, U, P extends UDTPathTableField> P createUDTPathTableField( Name name, DataType type, TR table, @@ -214,7 +214,7 @@ public final class Internal { } @SuppressWarnings("unchecked") - public static final , UR extends UDTRecord, T, X, U, P extends UDTPathTableField> P createUDTPathTableField( + public static final , T, X, U, P extends UDTPathTableField> P createUDTPathTableField( Name name, DataType type, TR table, @@ -248,29 +248,29 @@ public final class Internal { } } - public static final , T, P extends UDTField> P createUDTPathField( + public static final > P createUDTPathField( Name name, DataType type, - UDTPathField qualifier, + UDTPathField qualifier, Class

returnType ) { return createUDTPathField(name, type, qualifier, null, returnType, null, null); } - public static final , T, P extends UDTField> P createUDTPathField( + public static final > P createUDTPathField( Name name, DataType type, - UDTPathField qualifier, + UDTPathField qualifier, String comment, Class

returnType ) { return createUDTPathField(name, type, qualifier, comment, returnType, null, null); } - public static final , T, U, P extends UDTField> P createUDTPathField( + public static final > P createUDTPathField( Name name, DataType type, - UDTPathField qualifier, + UDTPathField qualifier, String comment, Class

returnType, Converter converter @@ -278,10 +278,10 @@ public final class Internal { return createUDTPathField(name, type, qualifier, comment, returnType, converter, null); } - public static final , T, U, P extends UDTField> P createUDTPathField( + public static final > P createUDTPathField( Name name, DataType type, - UDTPathField qualifier, + UDTPathField qualifier, String comment, Class

returnType, Binding binding @@ -289,10 +289,10 @@ public final class Internal { return createUDTPathField(name, type, qualifier, comment, returnType, null, binding); } - public static final , T, X, U, P extends UDTField> P createUDTPathField( + public static final > P createUDTPathField( Name name, DataType type, - UDTPathField qualifier, + UDTPathField qualifier, String comment, Class

returnType, Converter converter, @@ -318,10 +318,10 @@ public final class Internal { } @SuppressWarnings("unchecked") - private static , T, X, U, P extends UDTField> P newInstance( + private static > P newInstance( Name name, - RecordQualifier qualifier, - UDTPathField path, + RecordQualifier qualifier, + UDTPathField path, String comment, Class

returnType, Binding actualBinding, diff --git a/pom.xml b/pom.xml index 144b0d2412..60e534fcca 100644 --- a/pom.xml +++ b/pom.xml @@ -745,7 +745,7 @@ net.alchim31.maven scala-maven-plugin - 4.4.1 + 4.8.1 -deprecation