diff --git a/querydsl-tooling/querydsl-ksp-codegen/src/main/kotlin/com/querydsl/ksp/codegen/QueryModelExtractor.kt b/querydsl-tooling/querydsl-ksp-codegen/src/main/kotlin/com/querydsl/ksp/codegen/QueryModelExtractor.kt index 2db706271..071facea9 100644 --- a/querydsl-tooling/querydsl-ksp-codegen/src/main/kotlin/com/querydsl/ksp/codegen/QueryModelExtractor.kt +++ b/querydsl-tooling/querydsl-ksp-codegen/src/main/kotlin/com/querydsl/ksp/codegen/QueryModelExtractor.kt @@ -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}" ) } } diff --git a/querydsl-tooling/querydsl-ksp-codegen/src/test/kotlin/RenderTest.kt b/querydsl-tooling/querydsl-ksp-codegen/src/test/kotlin/RenderTest.kt index be89d0373..ba2b2e075 100644 --- a/querydsl-tooling/querydsl-ksp-codegen/src/test/kotlin/RenderTest.kt +++ b/querydsl-tooling/querydsl-ksp-codegen/src/test/kotlin/RenderTest.kt @@ -211,6 +211,48 @@ class RenderTest { ) : com.querydsl.core.types.ConstructorExpression(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") + } } private fun String.assertLines(expected: String) { @@ -271,3 +313,13 @@ class QAnimal( class Cat class CatDTO + +class OuterClass { + class InnerClass +} + +class Level1 { + class Level2 { + class Level3 + } +} \ No newline at end of file