Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix arguments handling in KSType.toTypeName() #1529

Merged
merged 4 commits into from
Apr 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
*/
package com.squareup.kotlinpoet.ksp

import com.google.devtools.ksp.symbol.ClassKind
import com.google.devtools.ksp.symbol.KSClassDeclaration
import com.google.devtools.ksp.symbol.KSType
import com.google.devtools.ksp.symbol.KSTypeAlias
Expand Down Expand Up @@ -64,12 +63,6 @@ internal fun KSType.toTypeName(
}
val type = when (val decl = declaration) {
is KSClassDeclaration -> {
val arguments = if (decl.classKind == ClassKind.ANNOTATION_CLASS) {
arguments
} else {
typeArguments
}

decl.toClassName().withTypeArguments(arguments.map { it.toTypeName(typeParamResolver) })
}
is KSTypeParameter -> typeParamResolver[decl.name.getShortName()]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ import com.google.devtools.ksp.isConstructor
import com.google.devtools.ksp.processing.Resolver
import com.google.devtools.ksp.processing.SymbolProcessor
import com.google.devtools.ksp.processing.SymbolProcessorEnvironment
import com.google.devtools.ksp.symbol.ClassKind
import com.google.devtools.ksp.symbol.KSAnnotated
import com.google.devtools.ksp.symbol.KSClassDeclaration
import com.squareup.kotlinpoet.ANY
import com.squareup.kotlinpoet.FileSpec
import com.squareup.kotlinpoet.FunSpec
import com.squareup.kotlinpoet.ParameterSpec
Expand Down Expand Up @@ -66,6 +68,32 @@ class TestProcessor(private val env: SymbolProcessorEnvironment) : SymbolProcess
.filterNot { it.shortName.getShortName() == "ExampleAnnotation" }
.map { it.toAnnotationSpec() }.asIterable(),
)
val allSupertypes = decl.superTypes.toList()
val (superclassReference, superInterfaces) = if (allSupertypes.isNotEmpty()) {
val superClass = allSupertypes.firstOrNull {
val resolved = it.resolve()
resolved is KSClassDeclaration && resolved.classKind == ClassKind.CLASS
}
if (superClass != null) {
superClass to allSupertypes.filterNot { it == superClass }
} else {
null to allSupertypes
}
} else {
null to allSupertypes
}

superclassReference?.let {
val typeName = it.toTypeName(decl.typeParameters.toTypeParameterResolver())
if (typeName != ANY) {
superclass(typeName)
}
}
addSuperinterfaces(
superInterfaces.map { it.toTypeName(decl.typeParameters.toTypeParameterResolver()) }
.filterNot { it == ANY }
.toList(),
)
}
val classTypeParams = decl.typeParameters.toTypeParameterResolver()
classBuilder.addTypeVariables(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,118 @@ class TestProcessorTest {
)
}

@Test
fun regression_1513() {
val compilation = prepareCompilation(
kotlin(
"Example.kt",
"""
package test

import com.squareup.kotlinpoet.ksp.test.processor.ExampleAnnotation

interface Repository<T>
@ExampleAnnotation
class RealRepository @Inject constructor() : Repository<String>
""",
),
)

val result = compilation.compile()
assertThat(result.exitCode).isEqualTo(KotlinCompilation.ExitCode.OK)
val generatedFileText = File(compilation.kspSourcesDir, "kotlin/test/TestRealRepository.kt")
.readText()

assertThat(generatedFileText).isEqualTo(
"""
package test

import kotlin.String

public class RealRepository : Repository<String>

""".trimIndent(),
)
}

@Test
fun regression_1513_annotation() {
val compilation = prepareCompilation(
kotlin(
"Example.kt",
"""
package test

import com.squareup.kotlinpoet.ksp.test.processor.ExampleAnnotation

annotation class GenericAnnotation<T>

@ExampleAnnotation
@GenericAnnotation<String>
class RealRepository
""",
),
)

val result = compilation.compile()
assertThat(result.exitCode).isEqualTo(KotlinCompilation.ExitCode.OK)
val generatedFileText = File(compilation.kspSourcesDir, "kotlin/test/TestRealRepository.kt")
.readText()

assertThat(generatedFileText).isEqualTo(
"""
package test

import kotlin.String

@GenericAnnotation<String>
public class RealRepository

""".trimIndent(),
)
}

@Test
fun regression_1304() {
val compilation = prepareCompilation(
kotlin(
"Example.kt",
"""
package test

import com.squareup.kotlinpoet.ksp.test.processor.ExampleAnnotation

interface Flow<T>
typealias LeAlias = Map<Int, String>

@ExampleAnnotation
class RealRepository {
lateinit var prop: LeAlias
lateinit var complicated: Flow<LeAlias>
}
""",
),
)

val result = compilation.compile()
assertThat(result.exitCode).isEqualTo(KotlinCompilation.ExitCode.OK)
val generatedFileText = File(compilation.kspSourcesDir, "kotlin/test/TestRealRepository.kt")
.readText()

assertThat(generatedFileText).isEqualTo(
"""
package test

public class RealRepository {
public lateinit var prop: LeAlias

public lateinit var complicated: Flow<LeAlias>
}

""".trimIndent(),
)
}

private fun prepareCompilation(vararg sourceFiles: SourceFile): KotlinCompilation {
return KotlinCompilation()
.apply {
Expand Down