Skip to content

Commit

Permalink
Fix access to changed function in Kotlin 2.1+
Browse files Browse the repository at this point in the history
  • Loading branch information
drewhamilton committed Oct 11, 2024
1 parent 51f75c6 commit 7edbc63
Showing 1 changed file with 32 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
package dev.drewhamilton.poko.fir

import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
import org.jetbrains.kotlin.fir.extensions.FirExtensionSessionComponent
import org.jetbrains.kotlin.fir.extensions.FirExtensionSessionComponent.Factory
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.types.classId
import org.jetbrains.kotlin.fir.types.coneTypeSafe
import org.jetbrains.kotlin.name.ClassId
Expand All @@ -20,8 +25,33 @@ internal class PokoFirExtensionSessionComponent(
}
}

private fun FirAnnotation.classId(): ClassId? =
annotationTypeRef.coneTypeSafe<ConeClassLikeType>()?.classId
private fun FirAnnotation.classId(): ClassId? {
val coneClassLikeType = try {
annotationTypeRef.coneTypeSafe<ConeClassLikeType>()
} catch (noSuchMethodError: NoSuchMethodError) {
val annotationTypeRef = annotationTypeRef
if (annotationTypeRef is FirResolvedTypeRef) {
// The `coneTypeSafe` inline function uses a getter that changes names from `type`
// to `coneType` in 2.1+, so we access the latter via reflection here:
FirResolvedTypeRef::class.java
.methods
.single { it.name == "getConeType" }
.invoke(annotationTypeRef)
as? ConeClassLikeType
} else {
null
}
}
return coneClassLikeType?.classId
}

@OptIn(ExperimentalContracts::class)
private inline fun <reified T : ConeKotlinType> FirTypeRef.coneTypeSafeReflection(): T? {
contract {
returnsNotNull() implies (this@coneTypeSafeReflection is FirResolvedTypeRef)
}
return (this as? FirResolvedTypeRef)?.type as? T
}

internal companion object {
internal fun getFactory(pokoAnnotation: ClassId): Factory {
Expand Down

0 comments on commit 7edbc63

Please sign in to comment.