diff --git a/generator/accessor-runtime/src/main/java/me/kcra/takenaka/accessor/mapping/ClassMapping.java b/generator/accessor-runtime/src/main/java/me/kcra/takenaka/accessor/mapping/ClassMapping.java
index ef7f4b52110..a8b20af2a72 100644
--- a/generator/accessor-runtime/src/main/java/me/kcra/takenaka/accessor/mapping/ClassMapping.java
+++ b/generator/accessor-runtime/src/main/java/me/kcra/takenaka/accessor/mapping/ClassMapping.java
@@ -26,6 +26,7 @@
import org.jetbrains.annotations.Nullable;
import java.util.*;
+import java.util.function.Consumer;
import java.util.stream.Collectors;
/**
@@ -348,52 +349,61 @@ public ClassMapping(@NotNull String name) {
}
/**
- * Puts a new field mapping into this {@link ClassMapping}.
+ * Puts a new field mapping into this {@link ClassMapping} and runs a builder action on it.
*
* This is only for use in generated code.
*
* @param name the field name declared in the accessor model
- * @return the new {@link FieldMapping}
+ * @param builder the builder action
+ * @return this {@link ClassMapping}
*/
@ApiStatus.Internal
- public @NotNull FieldMapping putField(@NotNull String name) {
+ @Contract("_, _ -> this")
+ public @NotNull ClassMapping putField(@NotNull String name, @NotNull Consumer builder) {
final List overloads = fields.computeIfAbsent(name, (k) -> new ArrayList<>());
final FieldMapping mapping = new FieldMapping(this, name, overloads.size());
+ builder.accept(mapping);
overloads.add(mapping);
- return mapping;
+ return this;
}
/**
- * Puts a new constructor mapping into this {@link ClassMapping}.
+ * Puts a new constructor mapping into this {@link ClassMapping} and runs a builder action on it.
*
* This is only for use in generated code.
*
- * @return the new {@link ConstructorMapping}
+ * @param builder the builder action
+ * @return this {@link ClassMapping}
*/
@ApiStatus.Internal
- public @NotNull ConstructorMapping putConstructor() {
+ @Contract("_ -> this")
+ public @NotNull ClassMapping putConstructor(@NotNull Consumer builder) {
final ConstructorMapping mapping = new ConstructorMapping(this, constructors.size());
+ builder.accept(mapping);
constructors.add(mapping);
- return mapping;
+ return this;
}
/**
- * Puts a new method mapping into this {@link ClassMapping}.
+ * Puts a new method mapping into this {@link ClassMapping} and runs a builder action on it.
*
* This is only for use in generated code.
*
* @param name the method name declared in the accessor model
- * @return the new {@link MethodMapping}
+ * @param builder the builder action
+ * @return this {@link ClassMapping}
*/
@ApiStatus.Internal
- public @NotNull MethodMapping putMethod(@NotNull String name) {
+ @Contract("_, _ -> this")
+ public @NotNull ClassMapping putMethod(@NotNull String name, @NotNull Consumer builder) {
final List overloads = methods.computeIfAbsent(name, (k) -> new ArrayList<>());
final MethodMapping mapping = new MethodMapping(this, name, overloads.size());
+ builder.accept(mapping);
overloads.add(mapping);
- return mapping;
+ return this;
}
/**
diff --git a/generator/accessor-runtime/src/main/kotlin/me/kcra/takenaka/accessor/util/kotlin/builderExtensions.kt b/generator/accessor-runtime/src/main/kotlin/me/kcra/takenaka/accessor/util/kotlin/builderExtensions.kt
index 0bb6dc23509..a9ad8c0e5a6 100644
--- a/generator/accessor-runtime/src/main/kotlin/me/kcra/takenaka/accessor/util/kotlin/builderExtensions.kt
+++ b/generator/accessor-runtime/src/main/kotlin/me/kcra/takenaka/accessor/util/kotlin/builderExtensions.kt
@@ -44,23 +44,23 @@ inline fun classMapping(name: String, block: ClassMapping.() -> Unit): ClassMapp
*
* @param name the field name declared in the accessor model
* @param block the builder action
- * @return the [FieldMapping]
+ * @return the [ClassMapping]
*/
-inline fun ClassMapping.field(name: String, block: FieldMapping.() -> Unit): FieldMapping = putField(name).apply(block)
+fun ClassMapping.field(name: String, block: FieldMapping.() -> Unit): ClassMapping = putField(name, block)
/**
* Builds a new [ConstructorMapping] and appends it to the [ClassMapping].
*
* @param block the builder action
- * @return the [ConstructorMapping]
+ * @return the [ClassMapping]
*/
-inline fun ClassMapping.constructor(block: ConstructorMapping.() -> Unit): ConstructorMapping = putConstructor().apply(block)
+fun ClassMapping.constructor(block: ConstructorMapping.() -> Unit): ClassMapping = putConstructor(block)
/**
* Builds a new [MethodMapping] and appends it to the [ClassMapping].
*
* @param name the method name declared in the accessor model
* @param block the builder action
- * @return the [MethodMapping]
+ * @return the [ClassMapping]
*/
-inline fun ClassMapping.method(name: String, block: MethodMapping.() -> Unit): MethodMapping = putMethod(name).apply(block)
+fun ClassMapping.method(name: String, block: MethodMapping.() -> Unit): ClassMapping = putMethod(name, block)
diff --git a/generator/accessor/src/main/kotlin/me/kcra/takenaka/generator/accessor/context/impl/JavaGenerationContext.kt b/generator/accessor/src/main/kotlin/me/kcra/takenaka/generator/accessor/context/impl/JavaGenerationContext.kt
index bf59c44e8f6..41b6fdeb62d 100644
--- a/generator/accessor/src/main/kotlin/me/kcra/takenaka/generator/accessor/context/impl/JavaGenerationContext.kt
+++ b/generator/accessor/src/main/kotlin/me/kcra/takenaka/generator/accessor/context/impl/JavaGenerationContext.kt
@@ -105,62 +105,64 @@ open class JavaGenerationContext(
}
resolvedAccessor.fields.forEach { (fieldAccessor, fieldNode) ->
- add("\n.putField(\$S)", fieldAccessor.name)
- withIndent {
- groupFieldNames(fieldNode).forEach { (fieldKey, versions) ->
- val (ns, name) = fieldKey
+ add(
+ "\n.putField(\$S, \$L)",
+ fieldAccessor.name,
+ buildJLambdaBlock("m") {
+ groupFieldNames(fieldNode).forEach { (fieldKey, versions) ->
+ val (ns, name) = fieldKey
- add("\n.put(\$S, \$S, \$L)", ns, name, JCodeBlock.join(versions.map { JCodeBlock.of("\$S", it.id) }, ", "))
+ addStatement("m.put(\$S, \$S, \$L)", ns, name, JCodeBlock.join(versions.map { JCodeBlock.of("\$S", it.id) }, ", "))
+ }
}
-
- add("\n.getParent()")
- }
+ )
}
resolvedAccessor.constructors.forEach { (_, ctorNode) ->
- add("\n.putConstructor()")
- withIndent {
- groupConstructorNames(ctorNode).forEach { (ctorKey, versions) ->
- val (ns, desc) = ctorKey
+ add(
+ "\n.putConstructor(\$L)",
+ buildJLambdaBlock("m") {
+ groupConstructorNames(ctorNode).forEach { (ctorKey, versions) ->
+ val (ns, desc) = ctorKey
- add("\n.put(\$S, new \$T[] { \$L }", ns, SourceTypes.STRING, JCodeBlock.join(versions.map { JCodeBlock.of("\$S", it.id) }, ", "))
+ add("m.put(\$S, new \$T[] { \$L }", ns, SourceTypes.STRING, JCodeBlock.join(versions.map { JCodeBlock.of("\$S", it.id) }, ", "))
- val args = Type.getArgumentTypes(desc)
- .map { JCodeBlock.of("\$S", it.className) }
+ val args = Type.getArgumentTypes(desc)
+ .map { JCodeBlock.of("\$S", it.className) }
- if (args.isNotEmpty()) {
- add(", ")
- add(JCodeBlock.join(args, ", "))
- }
+ if (args.isNotEmpty()) {
+ add(", ")
+ add(JCodeBlock.join(args, ", "))
+ }
- add(")")
+ add(");\n")
+ }
}
-
- add("\n.getParent()")
- }
+ )
}
resolvedAccessor.methods.forEach { (methodAccessor, methodNode) ->
- add("\n.putMethod(\$S)", methodAccessor.name)
- withIndent {
- groupMethodNames(methodNode).forEach { (methodKey, versions) ->
- val (ns, name, desc) = methodKey
+ add(
+ "\n.putMethod(\$S, \$L)",
+ methodAccessor.name,
+ buildJLambdaBlock("m") {
+ groupMethodNames(methodNode).forEach { (methodKey, versions) ->
+ val (ns, name, desc) = methodKey
- add("\n.put(\$S, new \$T[] { \$L }, \$S", ns, SourceTypes.STRING, JCodeBlock.join(versions.map { JCodeBlock.of("\$S", it.id) }, ", "), name)
+ add("m.put(\$S, new \$T[] { \$L }, \$S", ns, SourceTypes.STRING, JCodeBlock.join(versions.map { JCodeBlock.of("\$S", it.id) }, ", "), name)
- val args = Type.getArgumentTypes(desc)
- .map { JCodeBlock.of("\$S", it.className) }
+ val args = Type.getArgumentTypes(desc)
+ .map { JCodeBlock.of("\$S", it.className) }
- if (args.isNotEmpty()) {
- add(", ")
- add(JCodeBlock.join(args, ", "))
- }
+ if (args.isNotEmpty()) {
+ add(", ")
+ add(JCodeBlock.join(args, ", "))
+ }
- add(")")
+ add(");\n")
+ }
}
-
- add("\n.getParent()")
- }
+ )
}
}
}
diff --git a/generator/accessor/src/main/kotlin/me/kcra/takenaka/generator/accessor/context/impl/SourceTypes.kt b/generator/accessor/src/main/kotlin/me/kcra/takenaka/generator/accessor/context/impl/SourceTypes.kt
index 97e1329035a..39f093aca56 100644
--- a/generator/accessor/src/main/kotlin/me/kcra/takenaka/generator/accessor/context/impl/SourceTypes.kt
+++ b/generator/accessor/src/main/kotlin/me/kcra/takenaka/generator/accessor/context/impl/SourceTypes.kt
@@ -73,6 +73,29 @@ inline fun com.squareup.kotlinpoet.PropertySpec.Builder.initializer(block: KCode
fun com.squareup.kotlinpoet.FileSpec.Builder.addImport(memberName: MemberName): com.squareup.kotlinpoet.FileSpec.Builder =
memberName.run { addImport("$packageName${enclosingClassName?.let { ".$it" } ?: ""}", simpleName) }
+/**
+ * Builds a Java lambda block.
+ *
+ * @param parameters the lambda parameter names
+ * @param block the lambda code block builder action
+ * @return the built code block
+ */
+inline fun buildJLambdaBlock(vararg parameters: String, block: JCodeBlockBuilder.() -> Unit): JCodeBlock = buildJCodeBlock {
+ add(
+ parameters.joinToString(
+ prefix = "(".takeIf { parameters.size != 1 } ?: "",
+ postfix = ")".takeIf { parameters.size != 1 } ?: ""
+ )
+ )
+ add(" -> {\n")
+
+ indent()
+ block()
+ unindent()
+
+ add("}")
+}
+
/**
* JavaPoet/KotlinPoet types.
*/