Repository: square/kotlinpoet
Issue: Mark an immutable property as inline

The documentation suggests the following snippet to generate an `inline val` property:

```kotlin
val android = PropertySpec.builder("android", String::class)
    .getter(FunSpec.getterBuilder()
        .addModifiers(KModifier.INLINE)
        .addStatement("return %S", "foo")
        .build())
    .setter(FunSpec.setterBuilder()
        .addModifiers(KModifier.INLINE)
        .addParameter("value", String::class)
        .build())
    .build()
```

This results in the error message `only a mutable proeprty can have a setter`, which makes sense. However, without adding a setter, the snippet above generates:

```kotlin
val android: String
    inline get() = "foo"
```

Which is not the expected

```kotlin
inline val android: String
    get() = "foo"
```

Now, I don't know if the two declarations above have a meaningful difference in the Kotlin compiler output. If not, it seems to me that inlining a getter on an immutable property should just inline the property. If so, perhaps it would be acceptable to declare `KModifier.INLINE` on the `PropertySpec.Builder` itself, and throw the error when emitting a mutable property.

Changed files:
kotlinpoet/src/main/java/com/squareup/kotlinpoet/PropertySpec.kt, kotlinpoet/src/test/java/com/squareup/kotlinpoet/PropertySpecTest.kt

diff --git a/kotlinpoet/src/main/java/com/squareup/kotlinpoet/PropertySpec.kt b/kotlinpoet/src/main/java/com/squareup/kotlinpoet/PropertySpec.kt
index 0aad3306..9d171154 100644
--- a/kotlinpoet/src/main/java/com/squareup/kotlinpoet/PropertySpec.kt
+++ b/kotlinpoet/src/main/java/com/squareup/kotlinpoet/PropertySpec.kt
@@ -65,7 +65,7 @@ public class PropertySpec private constructor(
     inlineAnnotations: Boolean = inline
   ) {
     val isInlineProperty = getter?.modifiers?.contains(KModifier.INLINE) ?: false &&
-      setter?.modifiers?.contains(KModifier.INLINE) ?: false
+      (!mutable || setter?.modifiers?.contains(KModifier.INLINE) ?: false)
     val propertyModifiers = if (isInlineProperty) modifiers + KModifier.INLINE else modifiers
     if (emitKdoc) {
       codeWriter.emitKdoc(kdoc.ensureEndsWithNewLine())
diff --git a/kotlinpoet/src/test/java/com/squareup/kotlinpoet/PropertySpecTest.kt b/kotlinpoet/src/test/java/com/squareup/kotlinpoet/PropertySpecTest.kt
index 4e7b9d3f..2ab1e244 100644
--- a/kotlinpoet/src/test/java/com/squareup/kotlinpoet/PropertySpecTest.kt
+++ b/kotlinpoet/src/test/java/com/squareup/kotlinpoet/PropertySpecTest.kt
@@ -69,7 +69,7 @@ class PropertySpecTest {
     }.hasMessageThat().isEqualTo("parameterless setter cannot have code")
   }
 
-  @Test fun inlineSingleAccessor() {
+  @Test fun inlineSingleAccessorVal() {
     val prop = PropertySpec.builder("foo", String::class)
       .getter(
         FunSpec.getterBuilder()
@@ -81,7 +81,26 @@ class PropertySpecTest {
 
     assertThat(prop.toString()).isEqualTo(
       """
-      |val foo: kotlin.String
+      |inline val foo: kotlin.String
+      |  get() = "foo"
+      |""".trimMargin()
+    )
+  }
+
+  @Test fun inlineSingleAccessorVar() {
+    val prop = PropertySpec.builder("foo", String::class)
+      .mutable()
+      .getter(
+        FunSpec.getterBuilder()
+          .addModifiers(KModifier.INLINE)
+          .addStatement("return %S", "foo")
+          .build()
+      )
+      .build()
+
+    assertThat(prop.toString()).isEqualTo(
+      """
+      |var foo: kotlin.String
       |  inline get() = "foo"
       |""".trimMargin()
     )
@@ -255,8 +274,8 @@ class PropertySpecTest {
       .build()
     assertThat(prop.toString()).isEqualTo(
       """
-      |private val <T : kotlin.Any> kotlin.reflect.KClass<T>.someFunction: T
-      |  inline get() = stuff as T
+      |private inline val <T : kotlin.Any> kotlin.reflect.KClass<T>.someFunction: T
+      |  get() = stuff as T
       |""".trimMargin()
     )
   }
@@ -296,8 +315,8 @@ class PropertySpecTest {
       .build()
     assertThat(prop.toString()).isEqualTo(
       """
-      |private val <reified T> kotlin.reflect.KClass<T>.someFunction: T
-      |  inline get() = stuff as T
+      |private inline val <reified T> kotlin.reflect.KClass<T>.someFunction: T
+      |  get() = stuff as T
       |""".trimMargin()
     )
   }