Skip to content

Fix inner class naming in KSP to match KAPT behavior #1317

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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 @@ -154,9 +154,16 @@ class QueryModelExtractor(

companion object {
fun queryClassName(classDeclaration: KSClassDeclaration, settings: KspSettings): ClassName {
val simpleNames = generateSequence(classDeclaration) { it.parentDeclaration as? KSClassDeclaration }
.map { it.simpleName.asString() }
.toList()
.reversed()

val className = simpleNames.joinToString("_")

return ClassName(
"${classDeclaration.packageName.asString()}${settings.packageSuffix}",
"${settings.prefix}${classDeclaration.simpleName.asString()}${settings.suffix}"
"${settings.prefix}${className}${settings.suffix}"
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,48 @@ class RenderTest {
) : com.querydsl.core.types.ConstructorExpression<CatDTO>(CatDTO::class.java, arrayOf(kotlin.Int::class.java, kotlin.String::class.java), id, name)
""".trimIndent())
}

@Test
fun innerClassNaming() {
// Test case for inner class naming compatibility with KAPT
val model = QueryModel(
originalClassName = ClassName("", "OuterClass", "InnerClass"),
typeParameterCount = 0,
className = ClassName("", "QOuterClass_InnerClass"),
type = QueryModelType.ENTITY,
null,
mockk()
)
val properties = listOf(
QProperty("innerProperty", QPropertyType.Simple(SimpleType.QString))
)
model.properties.addAll(properties)
val typeSpec = QueryModelRenderer.render(model)
val code = typeSpec.toString()

// Skip compile check for inner classes as they reference non-existent types
code.assertContains("class QOuterClass_InnerClass")
code.assertContains("val innerProperty: com.querydsl.core.types.dsl.StringPath = createString(\"innerProperty\")")
}

@Test
fun deeplyNestedClassNaming() {
// Test case for deeply nested classes (3 levels) - just check generated code structure
val model = QueryModel(
originalClassName = ClassName("", "Level1", "Level2", "Level3"),
typeParameterCount = 0,
className = ClassName("", "QLevel1_Level2_Level3"),
type = QueryModelType.ENTITY,
null,
mockk()
)
val typeSpec = QueryModelRenderer.render(model)
val code = typeSpec.toString()

// Skip compile check for nested classes as they reference non-existent types
code.assertContains("class QLevel1_Level2_Level3")
code.assertContains("EntityPathBase<Level1.Level2.Level3>")
}
}

private fun String.assertLines(expected: String) {
Expand Down Expand Up @@ -271,3 +313,13 @@ class QAnimal(
class Cat

class CatDTO

class OuterClass {
class InnerClass
}

class Level1 {
class Level2 {
class Level3
}
}