Как мне определить эти сложные инициализаторы для свойства - PullRequest
0 голосов
/ 29 апреля 2018

Несмотря на то, что я проверил все тесты в коде kotlinpoet, но я не нашел правильного способа реализации нижеуказанных целевых кодов, или я не уверен, использовал ли я лучший подход для этого. Если кто-то может дать некоторые комментарии по этому поводу, это было бы очень признательно.

Эти свойства определены в функции класса

Целевой код 1

val outputState = StateType1(iouValue, ourIdentity, otherParty)

Я использовал приведенные ниже коды для генерации вышеуказанного кода

.addCode(CodeBlock.of("%L",
    PropertySpec.builder("outputState", ClassName("","StateType1"))
        .initializer(CodeBlock.of("%T(%L, %L, %L)", ClassName("","StateType1"), "iouValue", "ourIdentity", "otherParty"))
        .build()))

Но вопрос в том, что этот outputState может быть из разных типов, например, StateType1 имеет 3 параметра, а StateTyp2 может иметь только 1 параметр, как я должен динамически определять свой код kotlinpoet для генерации правильного целевого кода.

Код цели 2

val txBuilder = TransactionBuilder(notary = notary)
    .addOutputState(outputState, TEMPLATE_CONTRACT_ID)

Я не нашел эталонный тестовый сценарий, в котором есть такой сценарий, после инициализатора свойства, затем вызовите его функцию напрямую.

1 Ответ

0 голосов
/ 01 мая 2018

Используйте CodeBlock.Builder для первого примера, это дает вам больше гибкости при построении CodeBlock s:

fun createConstructorCall(type: TypeName, vararg args: String): CodeBlock {
  val argsCode = args
      .map { CodeBlock.of("%L", it) }
      .joinToCode(separator = ", ", prefix = "(", suffix = ")")
  return CodeBlock.Builder()
      .add("%T", type)
      .add(argsCode)
      .build()
}

val className = ClassName("", "StateType1")
val codeBlock = CodeBlock.of("%L", PropertySpec.builder("outputState", className)
    .initializer(createConstructorCall(className, "iouValue", "ourIdentity", "otherParty"))
    .build())
assertThat(codeBlock.toString()).isEqualTo("""
  |val outputState: StateType1 = StateType1(iouValue, ourIdentity, otherParty)
  |""".trimMargin())

Во втором примере мы не предоставляем ничего особенного, передаем ваш код как строку и не стесняемся использовать заполнители для параметризации при необходимости:

val className1 = ClassName("", "TransactionBuilder")
val codeBlock1 = CodeBlock.of("%L", PropertySpec.builder("txBuilder", className)
    .initializer(
        "%T(notary = notary)\n.addOutputState(outputState, TEMPLATE_CONTRACT_ID)",
        className1)
    .build())
assertThat(codeBlock1.toString()).isEqualTo("""
  |val txBuilder: StateType1 = TransactionBuilder(notary = notary)
  |        .addOutputState(outputState, TEMPLATE_CONTRACT_ID)
  |""".trimMargin())
...