xref: /aosp_15_r20/external/kotlinpoet/docs/code-control-flow.md (revision 3c321d951dd070fb96f8ba59e952ffc3131379a0)
1Code & Control Flow
2===================
3
4Most of KotlinPoet's API uses immutable Kotlin objects. There's also builders, method chaining
5and varargs to make the API friendly. KotlinPoet offers models for Kotlin files (`FileSpec`),
6classes, interfaces & objects (`TypeSpec`), type aliases (`TypeAliasSpec`),
7properties (`PropertySpec`), functions & constructors (`FunSpec`), parameters (`ParameterSpec`) and
8annotations (`AnnotationSpec`).
9
10But the _body_ of methods and constructors is not modeled. There's no expression class, no
11statement class or syntax tree nodes. Instead, KotlinPoet uses strings for code blocks, and you can
12take advantage of Kotlin's multiline strings to make this look nice:
13
14```kotlin
15val main = FunSpec.builder("main")
16  .addCode("""
17    |var total = 0
18    |for (i in 0..<10) {
19    |    total += i
20    |}
21    |""".trimMargin())
22  .build()
23```
24
25Which generates this:
26
27```kotlin
28fun main() {
29  var total = 0
30  for (i in 0..<10) {
31    total += i
32  }
33}
34```
35
36There are additional APIs to assist with newlines, braces and indentation:
37
38```kotlin
39val main = FunSpec.builder("main")
40  .addStatement("var total = 0")
41  .beginControlFlow("for (i in 0..<10)")
42  .addStatement("total += i")
43  .endControlFlow()
44  .build()
45```
46
47This example is lame because the generated code is constant! Suppose instead of just adding 0 to 10,
48we want to make the operation and range configurable. Here's a method that generates a method:
49
50```kotlin
51private fun computeRange(name: String, from: Int, to: Int, op: String): FunSpec {
52  return FunSpec.builder(name)
53    .returns(Int::class)
54    .addStatement("var result = 1")
55    .beginControlFlow("for (i in $from..<$to)")
56    .addStatement("result = result $op i")
57    .endControlFlow()
58    .addStatement("return result")
59    .build()
60}
61```
62
63And here's what we get when we call `computeRange("multiply10to20", 10, 20, "*")`:
64
65```kotlin
66fun multiply10to20(): kotlin.Int {
67  var result = 1
68  for (i in 10..<20) {
69    result = result * i
70  }
71  return result
72}
73```
74
75Methods generating methods! And since KotlinPoet generates source instead of bytecode, you can
76read through it to make sure it's right.
77