Skip to content

Commit

Permalink
Promote KSP APIs to stable + integrate ABI validator (#1263)
Browse files Browse the repository at this point in the history
  • Loading branch information
ZacSweers committed Jun 13, 2022
1 parent 298bc22 commit f496b9b
Show file tree
Hide file tree
Showing 15 changed files with 1,607 additions and 69 deletions.
9 changes: 9 additions & 0 deletions build.gradle.kts
Expand Up @@ -26,6 +26,7 @@ plugins {
alias(libs.plugins.dokka) apply false
alias(libs.plugins.spotless) apply false
alias(libs.plugins.mavenPublish) apply false
alias(libs.plugins.kotlinBinaryCompatibilityValidator)
}

allprojects {
Expand Down Expand Up @@ -122,3 +123,11 @@ subprojects {
}
}
}

apiValidation {
nonPublicMarkers += "com.squareup.kotlinpoet.ExperimentalKotlinPoetApi"
ignoredProjects += listOf(
"interop", // Empty middle package
"test-processor" // Test only
)
}
3 changes: 0 additions & 3 deletions docs/interop-ksp.md
Expand Up @@ -5,9 +5,6 @@ KSP Extensions for KotlinPoet
[Kotlin Symbol Processing][ksp] (KSP) types to KotlinPoet types and
writing to KSP `CodeGenerator`.

Note that this API is currently in preview and subject to API changes. Usage of it requires opting
in to the `@KotlinPoetKspPreview` annotation.

```kotlin
dependencies {
implementation("com.squareup:kotlinpoet-ksp:<version>")
Expand Down
1 change: 1 addition & 0 deletions gradle/libs.versions.toml
Expand Up @@ -24,6 +24,7 @@ dokka = { id = "org.jetbrains.dokka", version = "1.6.21" }
ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
spotless = { id = "com.diffplug.spotless", version = "6.7.1" }
mavenPublish = { id = "com.vanniktech.maven.publish", version = "0.20.0" }
kotlinBinaryCompatibilityValidator = { id = "org.jetbrains.kotlinx.binary-compatibility-validator", version = "0.10.0" }

[libraries]
autoCommon = { module = "com.google.auto:auto-common", version = "1.1.2" }
Expand Down
22 changes: 22 additions & 0 deletions interop/javapoet/api/javapoet.api
@@ -0,0 +1,22 @@
public final class com/squareup/kotlinpoet/javapoet/J2kInteropKt {
public static final fun toKClassName (Lcom/squareup/javapoet/ClassName;)Lcom/squareup/kotlinpoet/ClassName;
public static final fun toKParameterizedTypeName (Lcom/squareup/javapoet/ParameterizedTypeName;)Lcom/squareup/kotlinpoet/ParameterizedTypeName;
public static final fun toKTypeName (Lcom/squareup/javapoet/TypeName;)Lcom/squareup/kotlinpoet/TypeName;
public static final fun toKTypeVariableName (Lcom/squareup/javapoet/TypeVariableName;)Lcom/squareup/kotlinpoet/TypeVariableName;
public static final fun toKWildcardTypeName (Lcom/squareup/javapoet/WildcardTypeName;)Lcom/squareup/kotlinpoet/WildcardTypeName;
}

public final class com/squareup/kotlinpoet/javapoet/K2jInteropKt {
public static final fun toJClassName (Lcom/squareup/kotlinpoet/ClassName;Z)Lcom/squareup/javapoet/TypeName;
public static synthetic fun toJClassName$default (Lcom/squareup/kotlinpoet/ClassName;ZILjava/lang/Object;)Lcom/squareup/javapoet/TypeName;
public static final fun toJParameterizedOrArrayTypeName (Lcom/squareup/kotlinpoet/ParameterizedTypeName;)Lcom/squareup/javapoet/TypeName;
public static final fun toJParameterizedTypeName (Lcom/squareup/kotlinpoet/ParameterizedTypeName;)Lcom/squareup/javapoet/ParameterizedTypeName;
public static final fun toJTypeName (Lcom/squareup/kotlinpoet/TypeName;Z)Lcom/squareup/javapoet/TypeName;
public static synthetic fun toJTypeName$default (Lcom/squareup/kotlinpoet/TypeName;ZILjava/lang/Object;)Lcom/squareup/javapoet/TypeName;
public static final fun toJTypeVariableName (Lcom/squareup/kotlinpoet/TypeVariableName;)Lcom/squareup/javapoet/TypeVariableName;
public static final fun toJWildcardTypeName (Lcom/squareup/kotlinpoet/WildcardTypeName;)Lcom/squareup/javapoet/WildcardTypeName;
}

public abstract interface annotation class com/squareup/kotlinpoet/javapoet/KotlinPoetJavaPoetPreview : java/lang/annotation/Annotation {
}

368 changes: 368 additions & 0 deletions interop/kotlinx-metadata/api/kotlinx-metadata.api

Large diffs are not rendered by default.

64 changes: 64 additions & 0 deletions interop/ksp/api/ksp.api
@@ -0,0 +1,64 @@
public final class com/squareup/kotlinpoet/ksp/AnnotationsKt {
public static final fun toAnnotationSpec (Lcom/google/devtools/ksp/symbol/KSAnnotation;)Lcom/squareup/kotlinpoet/AnnotationSpec;
}

public final class com/squareup/kotlinpoet/ksp/KsClassDeclarationsKt {
public static final fun toClassName (Lcom/google/devtools/ksp/symbol/KSClassDeclaration;)Lcom/squareup/kotlinpoet/ClassName;
}

public final class com/squareup/kotlinpoet/ksp/KsTypesKt {
public static final fun toClassName (Lcom/google/devtools/ksp/symbol/KSType;)Lcom/squareup/kotlinpoet/ClassName;
public static final fun toTypeName (Lcom/google/devtools/ksp/symbol/KSType;Lcom/squareup/kotlinpoet/ksp/TypeParameterResolver;)Lcom/squareup/kotlinpoet/TypeName;
public static final fun toTypeName (Lcom/google/devtools/ksp/symbol/KSTypeArgument;Lcom/squareup/kotlinpoet/ksp/TypeParameterResolver;)Lcom/squareup/kotlinpoet/TypeName;
public static final fun toTypeName (Lcom/google/devtools/ksp/symbol/KSTypeReference;Lcom/squareup/kotlinpoet/ksp/TypeParameterResolver;)Lcom/squareup/kotlinpoet/TypeName;
public static synthetic fun toTypeName$default (Lcom/google/devtools/ksp/symbol/KSType;Lcom/squareup/kotlinpoet/ksp/TypeParameterResolver;ILjava/lang/Object;)Lcom/squareup/kotlinpoet/TypeName;
public static synthetic fun toTypeName$default (Lcom/google/devtools/ksp/symbol/KSTypeArgument;Lcom/squareup/kotlinpoet/ksp/TypeParameterResolver;ILjava/lang/Object;)Lcom/squareup/kotlinpoet/TypeName;
public static synthetic fun toTypeName$default (Lcom/google/devtools/ksp/symbol/KSTypeReference;Lcom/squareup/kotlinpoet/ksp/TypeParameterResolver;ILjava/lang/Object;)Lcom/squareup/kotlinpoet/TypeName;
public static final fun toTypeVariableName (Lcom/google/devtools/ksp/symbol/KSTypeParameter;Lcom/squareup/kotlinpoet/ksp/TypeParameterResolver;)Lcom/squareup/kotlinpoet/TypeVariableName;
public static synthetic fun toTypeVariableName$default (Lcom/google/devtools/ksp/symbol/KSTypeParameter;Lcom/squareup/kotlinpoet/ksp/TypeParameterResolver;ILjava/lang/Object;)Lcom/squareup/kotlinpoet/TypeVariableName;
}

public final class com/squareup/kotlinpoet/ksp/ModifiersKt {
public static final fun toKModifier (Lcom/google/devtools/ksp/symbol/Modifier;)Lcom/squareup/kotlinpoet/KModifier;
}

public abstract interface class com/squareup/kotlinpoet/ksp/OriginatingKSFiles {
public abstract fun getFiles ()Ljava/util/List;
}

public final class com/squareup/kotlinpoet/ksp/OriginatingKSFilesKt {
public static final fun addOriginatingKSFile (Lcom/squareup/kotlinpoet/FunSpec$Builder;Lcom/google/devtools/ksp/symbol/KSFile;)Lcom/squareup/kotlinpoet/FunSpec$Builder;
public static final fun addOriginatingKSFile (Lcom/squareup/kotlinpoet/PropertySpec$Builder;Lcom/google/devtools/ksp/symbol/KSFile;)Lcom/squareup/kotlinpoet/PropertySpec$Builder;
public static final fun addOriginatingKSFile (Lcom/squareup/kotlinpoet/TypeAliasSpec$Builder;Lcom/google/devtools/ksp/symbol/KSFile;)Lcom/squareup/kotlinpoet/TypeAliasSpec$Builder;
public static final fun addOriginatingKSFile (Lcom/squareup/kotlinpoet/TypeSpec$Builder;Lcom/google/devtools/ksp/symbol/KSFile;)Lcom/squareup/kotlinpoet/TypeSpec$Builder;
public static final fun kspDependencies (Lcom/squareup/kotlinpoet/FileSpec;ZLjava/lang/Iterable;)Lcom/google/devtools/ksp/processing/Dependencies;
public static synthetic fun kspDependencies$default (Lcom/squareup/kotlinpoet/FileSpec;ZLjava/lang/Iterable;ILjava/lang/Object;)Lcom/google/devtools/ksp/processing/Dependencies;
public static final fun originatingKSFiles (Lcom/squareup/kotlinpoet/FileSpec;)Ljava/util/List;
public static final fun originatingKSFiles (Lcom/squareup/kotlinpoet/FunSpec;)Ljava/util/List;
public static final fun originatingKSFiles (Lcom/squareup/kotlinpoet/PropertySpec;)Ljava/util/List;
public static final fun originatingKSFiles (Lcom/squareup/kotlinpoet/TypeAliasSpec;)Ljava/util/List;
public static final fun originatingKSFiles (Lcom/squareup/kotlinpoet/TypeSpec;)Ljava/util/List;
public static final fun writeTo (Lcom/squareup/kotlinpoet/FileSpec;Lcom/google/devtools/ksp/processing/CodeGenerator;Lcom/google/devtools/ksp/processing/Dependencies;)V
public static final fun writeTo (Lcom/squareup/kotlinpoet/FileSpec;Lcom/google/devtools/ksp/processing/CodeGenerator;ZLjava/lang/Iterable;)V
public static synthetic fun writeTo$default (Lcom/squareup/kotlinpoet/FileSpec;Lcom/google/devtools/ksp/processing/CodeGenerator;ZLjava/lang/Iterable;ILjava/lang/Object;)V
}

public abstract interface class com/squareup/kotlinpoet/ksp/TypeParameterResolver {
public static final field Companion Lcom/squareup/kotlinpoet/ksp/TypeParameterResolver$Companion;
public abstract fun get (Ljava/lang/String;)Lcom/squareup/kotlinpoet/TypeVariableName;
public abstract fun getParametersMap ()Ljava/util/Map;
}

public final class com/squareup/kotlinpoet/ksp/TypeParameterResolver$Companion {
public final fun getEMPTY ()Lcom/squareup/kotlinpoet/ksp/TypeParameterResolver;
}

public final class com/squareup/kotlinpoet/ksp/TypeParameterResolverKt {
public static final fun toTypeParameterResolver (Ljava/util/List;Lcom/squareup/kotlinpoet/ksp/TypeParameterResolver;Ljava/lang/String;)Lcom/squareup/kotlinpoet/ksp/TypeParameterResolver;
public static synthetic fun toTypeParameterResolver$default (Ljava/util/List;Lcom/squareup/kotlinpoet/ksp/TypeParameterResolver;Ljava/lang/String;ILjava/lang/Object;)Lcom/squareup/kotlinpoet/ksp/TypeParameterResolver;
}

public final class com/squareup/kotlinpoet/ksp/VisibilitiesKt {
public static final fun toKModifier (Lcom/google/devtools/ksp/symbol/Visibility;)Lcom/squareup/kotlinpoet/KModifier;
}

This file was deleted.

Expand Up @@ -30,7 +30,6 @@ import com.squareup.kotlinpoet.TypeVariableName
*
* @see toTypeParameterResolver
*/
@KotlinPoetKspPreview
public interface TypeParameterResolver {
public val parametersMap: Map<String, TypeVariableName>
public operator fun get(index: String): TypeVariableName
Expand Down Expand Up @@ -58,7 +57,6 @@ public interface TypeParameterResolver {
* @param sourceTypeHint an optional hint for error messages. Unresolvable parameter IDs will
* include this hint in the thrown error's message.
*/
@KotlinPoetKspPreview
public fun List<KSTypeParameter>.toTypeParameterResolver(
parent: TypeParameterResolver? = null,
sourceTypeHint: String = "<unknown>",
Expand Down
Expand Up @@ -29,7 +29,6 @@ import com.squareup.kotlinpoet.CodeBlock
import com.squareup.kotlinpoet.ParameterizedTypeName

/** Returns an [AnnotationSpec] representation of this [KSAnnotation] instance. */
@KotlinPoetKspPreview
public fun KSAnnotation.toAnnotationSpec(): AnnotationSpec {
val builder = when (val type = annotationType.resolve().unwrapTypeAlias().toTypeName()) {
is ClassName -> AnnotationSpec.builder(type)
Expand Down Expand Up @@ -68,7 +67,6 @@ internal fun KSType.unwrapTypeAlias(): KSType {
}
}

@KotlinPoetKspPreview
private fun addValueToBlock(value: Any, member: CodeBlock.Builder) {
when (value) {
is List<*> -> {
Expand Down
Expand Up @@ -19,7 +19,6 @@ import com.google.devtools.ksp.symbol.KSClassDeclaration
import com.squareup.kotlinpoet.ClassName

/** Returns the [ClassName] representation of this [KSClassDeclaration]. */
@KotlinPoetKspPreview
public fun KSClassDeclaration.toClassName(): ClassName {
return toClassNameInternal()
}
Expand Up @@ -34,7 +34,6 @@ import com.squareup.kotlinpoet.WildcardTypeName
import com.squareup.kotlinpoet.tags.TypeAliasTag

/** Returns the [ClassName] representation of this [KSType] IFF it's a [KSClassDeclaration]. */
@KotlinPoetKspPreview
public fun KSType.toClassName(): ClassName {
val decl = declaration
check(decl is KSClassDeclaration) {
Expand All @@ -51,12 +50,10 @@ public fun KSType.toClassName(): ClassName {
* declarations can be anything with generics that child nodes declare as
* defined by [KSType.arguments].
*/
@KotlinPoetKspPreview
public fun KSType.toTypeName(
typeParamResolver: TypeParameterResolver = TypeParameterResolver.EMPTY
): TypeName = toTypeName(typeParamResolver, emptyList())

@KotlinPoetKspPreview
internal fun KSType.toTypeName(
typeParamResolver: TypeParameterResolver,
typeArguments: List<KSTypeArgument>,
Expand Down Expand Up @@ -111,7 +108,6 @@ internal fun KSType.toTypeName(
return type.copy(nullable = isMarkedNullable)
}

@KotlinPoetKspPreview
private fun mapTypeArgumentsFromTypeAliasToAbbreviatedType(
typeAlias: KSTypeAlias,
typeAliasTypeArguments: List<KSTypeArgument>,
Expand Down Expand Up @@ -139,7 +135,6 @@ private fun mapTypeArgumentsFromTypeAliasToAbbreviatedType(
* declarations can be anything with generics that child nodes declare as
* defined by [KSType.arguments].
*/
@KotlinPoetKspPreview
public fun KSTypeParameter.toTypeVariableName(
typeParamResolver: TypeParameterResolver = TypeParameterResolver.EMPTY
): TypeVariableName {
Expand All @@ -161,7 +156,6 @@ public fun KSTypeParameter.toTypeVariableName(
* declarations can be anything with generics that child nodes declare as
* defined by [KSType.arguments].
*/
@KotlinPoetKspPreview
public fun KSTypeArgument.toTypeName(
typeParamResolver: TypeParameterResolver = TypeParameterResolver.EMPTY
): TypeName {
Expand All @@ -182,7 +176,6 @@ public fun KSTypeArgument.toTypeName(
* declarations can be anything with generics that child nodes declare as
* defined by [KSType.arguments].
*/
@KotlinPoetKspPreview
public fun KSTypeReference.toTypeName(
typeParamResolver: TypeParameterResolver = TypeParameterResolver.EMPTY
): TypeName {
Expand Down
Expand Up @@ -34,33 +34,27 @@ import java.nio.charset.StandardCharsets
*
* See [the docs](https://github.com/google/ksp/blob/main/docs/incremental.md) for more information.
*/
@KotlinPoetKspPreview
public interface OriginatingKSFiles {
public val files: List<KSFile>
}

/** Returns this spec's originating [KSFiles][KSFile] for use with incremental processing. */
@KotlinPoetKspPreview
public fun TypeSpec.originatingKSFiles(): List<KSFile> = getKSFilesTag()

/** Returns this spec's originating [KSFiles][KSFile] for use with incremental processing. */
@KotlinPoetKspPreview
public fun FunSpec.originatingKSFiles(): List<KSFile> = getKSFilesTag()

/** Returns this spec's originating [KSFiles][KSFile] for use with incremental processing. */
@KotlinPoetKspPreview
public fun PropertySpec.originatingKSFiles(): List<KSFile> = getKSFilesTag()

/** Returns this spec's originating [KSFiles][KSFile] for use with incremental processing. */
@KotlinPoetKspPreview
public fun TypeAliasSpec.originatingKSFiles(): List<KSFile> = getKSFilesTag()

/**
* Returns the list of all files added to the contained
* [TypeSpecs][TypeSpec], [PropertySpecs][PropertySpec], [FunSpecs][FunSpec], or
* [TypeAliasSpecs][TypeAliasSpec] contained in this spec.
*/
@KotlinPoetKspPreview
public fun FileSpec.originatingKSFiles(): List<KSFile> {
return members
.flatMap {
Expand All @@ -76,25 +70,21 @@ public fun FileSpec.originatingKSFiles(): List<KSFile> {
}

/** Adds the given [ksFile] to this builder's tags for use with [originatingKSFiles]. */
@KotlinPoetKspPreview
public fun TypeAliasSpec.Builder.addOriginatingKSFile(ksFile: KSFile): TypeAliasSpec.Builder = apply {
getOrCreateKSFilesTag().add(ksFile)
}

/** Adds the given [ksFile] to this builder's tags for use with [originatingKSFiles]. */
@KotlinPoetKspPreview
public fun PropertySpec.Builder.addOriginatingKSFile(ksFile: KSFile): PropertySpec.Builder = apply {
getOrCreateKSFilesTag().add(ksFile)
}

/** Adds the given [ksFile] to this builder's tags for use with [originatingKSFiles]. */
@KotlinPoetKspPreview
public fun FunSpec.Builder.addOriginatingKSFile(ksFile: KSFile): FunSpec.Builder = apply {
getOrCreateKSFilesTag().add(ksFile)
}

/** Adds the given [ksFile] to this builder's tags for use with [originatingKSFiles]. */
@KotlinPoetKspPreview
public fun TypeSpec.Builder.addOriginatingKSFile(ksFile: KSFile): TypeSpec.Builder = apply {
getOrCreateKSFilesTag().add(ksFile)
}
Expand All @@ -112,7 +102,6 @@ public fun TypeSpec.Builder.addOriginatingKSFile(ksFile: KSFile): TypeSpec.Build
* @param codeGenerator the [CodeGenerator] to write to.
* @param aggregating flag indicating if this is an aggregating symbol processor.
*/
@KotlinPoetKspPreview
public fun FileSpec.writeTo(
codeGenerator: CodeGenerator,
aggregating: Boolean,
Expand All @@ -132,7 +121,6 @@ public fun FileSpec.writeTo(
* @param codeGenerator the [CodeGenerator] to write to.
* @param dependencies the [Dependencies] to create a new file with.
*/
@KotlinPoetKspPreview
public fun FileSpec.writeTo(
codeGenerator: CodeGenerator,
dependencies: Dependencies
Expand All @@ -157,7 +145,6 @@ public fun FileSpec.writeTo(
* @see FileSpec.writeTo
* @param aggregating flag indicating if this is an aggregating symbol processor.
*/
@KotlinPoetKspPreview
public fun FileSpec.kspDependencies(
aggregating: Boolean,
originatingKSFiles: Iterable<KSFile> = originatingKSFiles()
Expand All @@ -166,19 +153,16 @@ public fun FileSpec.kspDependencies(
/**
* A mutable [OriginatingKSFiles] instance for use with KotlinPoet Builders via [Taggable.Builder].
*/
@OptIn(KotlinPoetKspPreview::class)
private interface MutableOriginatingKSFiles : OriginatingKSFiles {
override val files: MutableList<KSFile>
}

private data class MutableOriginatingKSFilesImpl(override val files: MutableList<KSFile> = mutableListOf()) : MutableOriginatingKSFiles

@OptIn(KotlinPoetKspPreview::class)
private fun Taggable.getKSFilesTag(): List<KSFile> {
return tag<OriginatingKSFiles>()?.files.orEmpty()
}

@OptIn(KotlinPoetKspPreview::class)
private fun Taggable.Builder<*>.getOrCreateKSFilesTag(): MutableList<KSFile> {
val holder = tags.getOrPut(
OriginatingKSFiles::class, ::MutableOriginatingKSFilesImpl
Expand Down
7 changes: 0 additions & 7 deletions interop/ksp/test-processor/build.gradle.kts
Expand Up @@ -18,13 +18,6 @@ plugins {
id("com.google.devtools.ksp")
}

tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>().configureEach {
kotlinOptions {
@Suppress("SuspiciousCollectionReassignment")
freeCompilerArgs += listOf("-opt-in=com.squareup.kotlinpoet.ksp.KotlinPoetKspPreview")
}
}

dependencies {
implementation(project(":kotlinpoet"))
implementation(project(":interop:ksp"))
Expand Down
Expand Up @@ -29,7 +29,6 @@ import com.squareup.kotlinpoet.FunSpec
import com.squareup.kotlinpoet.ParameterSpec
import com.squareup.kotlinpoet.PropertySpec
import com.squareup.kotlinpoet.TypeSpec
import com.squareup.kotlinpoet.ksp.KotlinPoetKspPreview
import com.squareup.kotlinpoet.ksp.addOriginatingKSFile
import com.squareup.kotlinpoet.ksp.kspDependencies
import com.squareup.kotlinpoet.ksp.originatingKSFiles
Expand All @@ -44,7 +43,6 @@ import com.squareup.kotlinpoet.ksp.writeTo
* A simple processor that generates a skeleton API of classes annotated with [ExampleAnnotation]
* for test and verification purposes.
*/
@OptIn(KotlinPoetKspPreview::class)
class TestProcessor(private val env: SymbolProcessorEnvironment) : SymbolProcessor {

private val unwrapTypeAliases = env.options["unwrapTypeAliases"]?.toBooleanStrictOrNull() ?: false
Expand Down

0 comments on commit f496b9b

Please sign in to comment.