Skip to content

Instantly share code, notes, and snippets.

@NikolaDespotoski
Last active February 19, 2023 05:56
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save NikolaDespotoski/5bbb254cf988a0f529a3385fc55114a7 to your computer and use it in GitHub Desktop.
Save NikolaDespotoski/5bbb254cf988a0f529a3385fc55114a7 to your computer and use it in GitHub Desktop.
KSP extensions
import com.google.devtools.ksp.getClassDeclarationByName
import com.google.devtools.ksp.processing.Resolver
import com.google.devtools.ksp.symbol.*
/**
* Reified function to check if receiver [KSType] is assignable from [T] class
*/
inline fun <reified T> KSType.isAssignableFrom(resolver: Resolver): Boolean {
val classDeclaration = requireNotNull(resolver.getClassDeclarationByName<T>()) {
"Unable to resolve ${KSClassDeclaration::class.simpleName} for type ${T::class.simpleName}"
}
return isAssignableFrom(classDeclaration.asStarProjectedType())
}
/**
* Checks if [KSTypeReference] (which has to be [KSClassDeclaration])
* belongs in [packageName]
* @param packageName package name
* @return true if [KSClassDeclaration] belongs to the [packageName]
*/
fun Resolver.isFromPackage(type: KSTypeReference, packageName: String): Boolean {
val returnTypeClassDeclaration = type.resolve().declaration as KSClassDeclaration
val kotlinCollections = getKSNameFromString(packageName)
return kotlinCollections == returnTypeClassDeclaration.packageName
}
/**
* Checks if [KSTypeReference] (which has to be [KSClassDeclaration]
* belongs in [java.util] package
*/
fun Resolver.isJvmCollection(type: KSTypeReference) =
isFromPackage(type = type, packageName = "java.util")
/**
* Checks if [KSTypeReference] (which has to be [KSClassDeclaration]
* belongs in [kotlin.collections] package
*/
fun Resolver.isKtCollection(type: KSTypeReference) =
isFromPackage(type = type, packageName = "kotlin.collections")
/**
* Returns the parameter type of the return type of [KSClassDeclaration]
* e.g: In
* fun getAllDevices() : List<Device>
*
* will return the Device class as [KSType]
* @return returns parametrized type as [KSType]
*/
fun KSFunctionDeclaration.returnTypeParametrized(resolver: Resolver): KSType {
val returnType = requireNotNull(returnType) {
"Function has no return type"
}
check(returnType.resolve().declaration.qualifiedName == resolver.builtIns.unitType) {
"Function ${simpleName.asString()} has kotlin.Unit type. It can't be parametrized."
}
return returnType.element!!.typeArguments.first().type!!.resolve()
}
/**
@returns [KSAnnotation] for typed T or null if not found
*/
inline fun <reified T> KSDeclaration.findAnnotation(resolver: Resolver): KSAnnotation? {
val annotationKsName = resolver.getKSNameFromString(T::class.simpleName!!)
return annotations.firstOrNull { it.shortName.asString() == annotationKsName.asString() }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment