Skip to content

Commit

Permalink
KSType.toTypeName fixed to work with aliased types (#1534)
Browse files Browse the repository at this point in the history
* KSType.toTypeName fixed to work with aliased types

resolves #1513

* test fixed

* imports fixed

* test case

* import fix

* imports fix

* Simplify test + fix formatting/style issues

---------

Co-authored-by: Zac Sweers <[email protected]>
  • Loading branch information
Squiry and ZacSweers authored Apr 28, 2023
1 parent 757c034 commit c7fe08f
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 7 deletions.
1 change: 1 addition & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ insert_final_newline = true
ij_kotlin_imports_layout = *
ij_kotlin_allow_trailing_comma = true
ij_kotlin_allow_trailing_comma_on_call_site = true
ij_kotlin_name_count_to_use_star_import = 99999
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public fun KSType.toClassName(): ClassName {
*/
public fun KSType.toTypeName(
typeParamResolver: TypeParameterResolver = TypeParameterResolver.EMPTY,
): TypeName = toTypeName(typeParamResolver, emptyList())
): TypeName = toTypeName(typeParamResolver, arguments)

internal fun KSType.toTypeName(
typeParamResolver: TypeParameterResolver,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,15 @@ 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.google.devtools.ksp.symbol.KSTypeReference
import com.squareup.kotlinpoet.ANY
import com.squareup.kotlinpoet.FileSpec
import com.squareup.kotlinpoet.FunSpec
import com.squareup.kotlinpoet.ParameterSpec
import com.squareup.kotlinpoet.PropertySpec
import com.squareup.kotlinpoet.TypeName
import com.squareup.kotlinpoet.TypeSpec
import com.squareup.kotlinpoet.ksp.TypeParameterResolver
import com.squareup.kotlinpoet.ksp.addOriginatingKSFile
import com.squareup.kotlinpoet.ksp.kspDependencies
import com.squareup.kotlinpoet.ksp.originatingKSFiles
Expand All @@ -55,6 +58,15 @@ class TestProcessor(private val env: SymbolProcessorEnvironment) : SymbolProcess
return emptyList()
}

private fun KSTypeReference.toValidatedTypeName(resolver: TypeParameterResolver): TypeName {
// Validates that both toTypeName() and resolve() return the same TypeName.
// Regression for https://github.com/square/kotlinpoet/issues/1513.
val typeName = toTypeName(resolver)
val resolvedTypeName = resolve().toTypeName(resolver)
check(typeName == resolvedTypeName)
return typeName
}

private fun process(decl: KSAnnotated) {
check(decl is KSClassDeclaration)

Expand Down Expand Up @@ -84,13 +96,13 @@ class TestProcessor(private val env: SymbolProcessorEnvironment) : SymbolProcess
}

superclassReference?.let {
val typeName = it.toTypeName(decl.typeParameters.toTypeParameterResolver())
val typeName = it.toValidatedTypeName(decl.typeParameters.toTypeParameterResolver())
if (typeName != ANY) {
superclass(typeName)
}
}
addSuperinterfaces(
superInterfaces.map { it.toTypeName(decl.typeParameters.toTypeParameterResolver()) }
superInterfaces.map { it.toValidatedTypeName(decl.typeParameters.toTypeParameterResolver()) }
.filterNot { it == ANY }
.toList(),
)
Expand All @@ -113,7 +125,7 @@ class TestProcessor(private val env: SymbolProcessorEnvironment) : SymbolProcess
classBuilder.addProperty(
PropertySpec.builder(
property.simpleName.getShortName(),
property.type.toTypeName(classTypeParams).let {
property.type.toValidatedTypeName(classTypeParams).let {
if (unwrapTypeAliases) {
it.unwrapTypeAlias()
} else {
Expand Down Expand Up @@ -158,7 +170,7 @@ class TestProcessor(private val env: SymbolProcessorEnvironment) : SymbolProcess
)
.addParameters(
function.parameters.map { parameter ->
val parameterType = parameter.type.toTypeName(functionTypeParams).let {
val parameterType = parameter.type.toValidatedTypeName(functionTypeParams).let {
if (unwrapTypeAliases) {
it.unwrapTypeAlias()
} else {
Expand All @@ -171,7 +183,7 @@ class TestProcessor(private val env: SymbolProcessorEnvironment) : SymbolProcess
},
)
.returns(
function.returnType!!.toTypeName(functionTypeParams).let {
function.returnType!!.toValidatedTypeName(functionTypeParams).let {
if (unwrapTypeAliases) {
it.unwrapTypeAlias()
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class KsTypesTest {
override val annotations: Sequence<KSAnnotation>
get() = throw NotImplementedError()
override val arguments: List<KSTypeArgument>
get() = throw NotImplementedError()
get() = emptyList()
override val declaration: KSDeclaration
get() = throw NotImplementedError()
override val isFunctionType: Boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -595,6 +595,46 @@ class TestProcessorTest {
)
}

@Test
fun regression_1304_with_type_parameters() {
val compilation = prepareCompilation(
kotlin(
"Example.kt",
"""
package test
import com.squareup.kotlinpoet.ksp.test.processor.ExampleAnnotation
interface Flow<T>
typealias LeAlias<T> = Flow<T>
@ExampleAnnotation
class RealRepository {
lateinit var prop: LeAlias<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 {
public lateinit var prop: LeAlias<String>
}
""".trimIndent(),
)
}

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

0 comments on commit c7fe08f

Please sign in to comment.