diff --git a/kotlinpoet/src/main/java/com/squareup/kotlinpoet/FunSpec.kt b/kotlinpoet/src/main/java/com/squareup/kotlinpoet/FunSpec.kt index 28c5ca23e2..d44243733a 100644 --- a/kotlinpoet/src/main/java/com/squareup/kotlinpoet/FunSpec.kt +++ b/kotlinpoet/src/main/java/com/squareup/kotlinpoet/FunSpec.kt @@ -55,13 +55,18 @@ public class FunSpec private constructor( public val delegateConstructorArguments: List = builder.delegateConstructorArguments.toImmutableList() public val body: CodeBlock = builder.body.build() + private val isExternalGetter = name == GETTER && builder.modifiers.contains(EXTERNAL) private val isEmptySetter = name == SETTER && parameters.isEmpty() init { require(body.isEmpty() || !builder.modifiers.containsAnyOf(ABSTRACT, EXPECT)) { "abstract or expect function ${builder.name} cannot have code" } - if (name == SETTER) { + if (name == GETTER) { + require(!isExternalGetter || body.isEmpty()) { + "external getter cannot have code" + } + } else if (name == SETTER) { require(parameters.size <= 1) { "$name can have at most one parameter" } @@ -155,7 +160,7 @@ public class FunSpec private constructor( codeWriter.emitCode("%N", this) } - if (!isEmptySetter) { + if (!isEmptySetter && !isExternalGetter) { parameters.emit(codeWriter) { param -> param.emit(codeWriter, includeType = name != SETTER) } diff --git a/kotlinpoet/src/test/java/com/squareup/kotlinpoet/PropertySpecTest.kt b/kotlinpoet/src/test/java/com/squareup/kotlinpoet/PropertySpecTest.kt index ca80ba44ae..ac74aa0ed0 100644 --- a/kotlinpoet/src/test/java/com/squareup/kotlinpoet/PropertySpecTest.kt +++ b/kotlinpoet/src/test/java/com/squareup/kotlinpoet/PropertySpecTest.kt @@ -18,6 +18,7 @@ package com.squareup.kotlinpoet import com.google.common.truth.Truth.assertThat import com.squareup.kotlinpoet.FunSpec.Companion.GETTER import com.squareup.kotlinpoet.FunSpec.Companion.SETTER +import com.squareup.kotlinpoet.KModifier.EXTERNAL import com.squareup.kotlinpoet.KModifier.PRIVATE import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy import java.io.Serializable @@ -74,6 +75,43 @@ class PropertySpecTest { }.hasMessageThat().isEqualTo("parameterless setter cannot have code") } + @Test fun externalGetterAndSetter() { + val prop = PropertySpec.builder("foo", String::class) + .mutable() + .getter( + FunSpec.getterBuilder() + .addModifiers(EXTERNAL) + .build() + ) + .setter( + FunSpec.setterBuilder() + .addModifiers(EXTERNAL) + .build() + ) + .build() + + assertThat(prop.toString()).isEqualTo( + """ + |var foo: kotlin.String + | external get + | external set + |""".trimMargin() + ) + } + + @Test fun externalGetterCannotHaveBody() { + assertThrows { + PropertySpec.builder("foo", String::class) + .getter( + FunSpec.getterBuilder() + .addModifiers(EXTERNAL) + .addStatement("return %S", "foo") + .build() + ) + .build() + }.hasMessageThat().isEqualTo("external getter cannot have code") + } + @Test fun inlineSingleAccessorVal() { val prop = PropertySpec.builder("foo", String::class) .getter(