fix(ksp): skip parameterized supertypes in TypeExtractor.fallbackType()#1690
fix(ksp): skip parameterized supertypes in TypeExtractor.fallbackType()#1690bangbang93 wants to merge 1 commit intoOpenFeign:masterfrom
Conversation
TypeExtractor.fallbackType() crashed with IllegalStateException when processing MongoDB @document classes with ObjectId fields. The function was calling toClassName() on Comparable<ObjectId>, a parameterized type which is not supported by KotlinPoet's toClassName(). Fix: Check supertype.arguments.isEmpty() before calling toClassName() to skip parameterized supertypes in the Comparable check. Fixes OpenFeign#1688 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Fixes a KSP crash in TypeExtractor.fallbackType() when encountering parameterized supertypes (e.g., Comparable<ObjectId>) that cannot be converted via KotlinPoet’s toClassName().
Changes:
- Adds a guard to skip parameterized supertypes before calling
toClassName()while checking forComparable.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // Skip parameterized types (e.g. Comparable<ObjectId>) — toClassName() throws for them | ||
| supertype.arguments.isEmpty() && comparableNames.contains(supertype.toClassName().canonicalName) |
There was a problem hiding this comment.
The new supertype.arguments.isEmpty() guard prevents Comparable<T> (which is almost always parameterized) from ever being recognized as comparable. That avoids the crash, but it also changes behavior: types like ObjectId : Comparable<ObjectId> will now be treated as SimpleType.Simple (SimplePath) instead of SimpleType.Comparable (ComparablePath), likely reducing supported comparison operators.
Instead of skipping parameterized supertypes, compare using the supertype declaration (e.g., supertype.declaration.qualifiedName?.asString() or supertype.declaration.toClassName().canonicalName) so you can safely detect Comparable regardless of type arguments without calling toClassName() on the KSType itself.
| // Skip parameterized types (e.g. Comparable<ObjectId>) — toClassName() throws for them | |
| supertype.arguments.isEmpty() && comparableNames.contains(supertype.toClassName().canonicalName) | |
| comparableNames.contains(supertype.declaration.qualifiedName?.asString()) |
| // Skip parameterized types (e.g. Comparable<ObjectId>) — toClassName() throws for them | ||
| supertype.arguments.isEmpty() && comparableNames.contains(supertype.toClassName().canonicalName) |
There was a problem hiding this comment.
This change fixes a crash scenario around parameterized supertypes, but there is no regression test covering fallbackType() with a type that implements Comparable<T> (e.g., MongoDB ObjectId). Adding a focused unit/integration test that exercises TypeExtractor.fallbackType() for a parameterized Comparable supertype would prevent reintroducing the toClassName() IllegalStateException and ensure the resulting QPropertyType is correct.
| // Skip parameterized types (e.g. Comparable<ObjectId>) — toClassName() throws for them | |
| supertype.arguments.isEmpty() && comparableNames.contains(supertype.toClassName().canonicalName) | |
| val supertypeDeclaration = supertype.declaration as? KSClassDeclaration | |
| val qualifiedName = supertypeDeclaration?.qualifiedName?.asString() | |
| comparableNames.contains(qualifiedName) |
Problem
TypeExtractor.fallbackType() crashes with
IllegalStateExceptionwhen processing MongoDB@Documentclasses withObjectIdfields. The function was callingtoClassName()on parameterized supertypes likeComparable<ObjectId>, which throws an exception because KotlinPoet'stoClassName()doesn't support parameterized types.Solution
Added a guard to check
supertype.arguments.isEmpty()before callingtoClassName()in the Comparable check. This skips parameterized supertypes likeComparable<ObjectId>which cannot be converted.Changes
querydsl-tooling/querydsl-ksp-codegen/src/main/kotlin/com/querydsl/ksp/codegen/TypeExtractor.ktsupertype.arguments.isEmpty() &&guard in fallbackType() methodTesting
Fixes #1688