square / javapoet

A Java API for generating .java source files.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Alternate to '$' syntax for substitutions?

kevinherron opened this issue · comments

Any chance of adding an alternate character that can be used when specifying substitions ($T, $L, $S etc...)?

$ is a real bummer to use from Kotlin.

Regular Strings are kinda bad:

addStatement(
    "CompletableFuture<\$T> future = getMemberNodeAsync(" +
        "\"\$L\", " +
        "\"$variableName\", " +
        "\$T.parse(\"\$L\"), " +
        "false" +
        ")",
    UaNode::class.java,
    variableTypeNodeNamespaceUri,
    ExpandedNodeId::class.java,
    referenceTypeId.expanded(namespaceTable).toParseableString()
)

Multi-line Strings are even worse:

add(
    """
    new ${'$'}T<>(
        "$namespaceUri",
        "$propertyName",
        ${'$'}T.parse("nsu=${'$'}L;${'$'}L"),
        ${'$'}T.${propertyNode.valueRank.toValueRanksFieldRef()},
        ${'$'}T.class
    )
    """.trimIndent(),
    QualifiedProperty::class.java,
    ExpandedNodeId::class.java,
    dataTypeNamespace,
    dataTypeIdString,
    ValueRanks::class.java,
    dataTypeClassName
)

Here's an easy workaround I've used in the past:

private const val T = "\$T"

This works but you need to be careful with type parameters in places you import those constants.

In particular, a reified type parameter T defined in any file where you've imported the constant will require its type parameter to be renamed:

inline fun <reified T> MethodSpec.Builder.addAnnotation(builderAction: AnnotationSpec.Builder.() -> Unit) {
    val clazz = T::class.java
    val annotationBuilder = AnnotationSpec.builder(clazz)
    builderAction(annotationBuilder)
    addAnnotation(annotationBuilder.build())
}

@kevinherron , you might want to check #761 (comment)

An alternative approach for Kotlin would be to apply JetPack Compose for building the AST.