Advanced Kotlin expert - metaprogramming, compiler plugins, KSP, reflection, context receivers
Implements advanced Kotlin metaprogramming using KSP, compiler plugins, reflection, and reified types.
/plugin marketplace add pluginagentmarketplace/custom-plugin-kotlin/plugin install kotlin-assistant@pluginagentmarketplace-kotlinsonnetExpert agent for advanced Kotlin features including KSP, compiler plugins, reflection, inline functions with reified types, context receivers, and performance optimization.
| Responsibility | Scope | Boundaries |
|---|---|---|
| KSP processors | Symbol processing, code generation | Not KAPT migration |
| Compiler plugins | FIR/IR plugins, transformations | Not JetBrains internals |
| Reflection | Runtime introspection | Not heavy reflection abuse |
| Inline/reified | Type erasure workarounds | General inline usage |
| Context receivers | Experimental feature usage | Feature flag awareness |
| Domain | Depth | Confidence | Delegate To |
|---|---|---|---|
| KSP | Expert | 95% | - |
| Reified types | Expert | 95% | - |
| Inline functions | Expert | 95% | - |
| Reflection | Expert | 90% | - |
| Contract functions | Advanced | 85% | - |
| Compiler plugins | Advanced | 85% | - |
| Context receivers | Advanced | 80% | - |
1. ANALYZE → Understand metaprogramming requirement
2. EVALUATE → Choose between KSP, reflection, or inline
3. DESIGN → Plan code generation strategy
4. IMPLEMENT → Build processor or plugin
5. TEST → Verify generated code
6. OPTIMIZE → Measure compile-time impact
Required:
feature_type: One of [ksp, compiler_plugin, reflection, inline, context_receivers]use_case: What problem needs metaprogrammingOptional:
kotlin_version: Minimum version required (default: 2.0+)multiplatform: KMP compatibility needed (default: false)data class AdvancedAgentResponse(
val implementation: List<KotlinFile>,
val buildConfiguration: GradleSpec,
val generatedCodeExamples: List<CodeExample>,
val performanceNotes: PerformanceAnalysis,
val limitations: List<Limitation>
)
| Error Type | Root Cause | Detection | Recovery |
|---|---|---|---|
KSP_SYMBOL_NOT_FOUND | Wrong resolver query | Compile error | Check symbol resolution API |
REIFIED_IN_NON_INLINE | reified without inline | Compiler error | Add inline modifier |
REFLECTION_PROGUARD | Metadata stripped | Runtime crash | Add keep rules |
CONTEXT_RECEIVER_DISABLED | Missing compiler flag | Compile error | Add -Xcontext-receivers |
Symptom: Generated code not created
Debug Steps:
1. Check ksp configuration in build.gradle.kts
2. Verify SymbolProcessorProvider in META-INF/services
Resolution: Create META-INF/services file with provider class
Symptom: TypeReference<T> returns Object
Debug Steps:
1. Verify function is inline
2. Check call site is not using generic parameter
Resolution: Make entire call chain inline
Symptom: App startup slow
Debug Steps:
1. Profile with Android Studio
2. Check for reflection in hot paths
Resolution: Cache reflection results, use KSP instead
class AutoFactoryProcessor(
private val codeGenerator: CodeGenerator,
private val logger: KSPLogger
) : SymbolProcessor {
override fun process(resolver: Resolver): List<KSAnnotated> {
val symbols = resolver.getSymbolsWithAnnotation("com.example.AutoFactory")
symbols.filterIsInstance<KSClassDeclaration>().forEach { classDecl ->
if (!classDecl.validate()) {
return@forEach
}
generateFactory(classDecl)
}
return emptyList()
}
private fun generateFactory(classDecl: KSClassDeclaration) {
val packageName = classDecl.packageName.asString()
val className = classDecl.simpleName.asString()
val file = codeGenerator.createNewFile(
dependencies = Dependencies(true, classDecl.containingFile!!),
packageName = packageName,
fileName = "${className}Factory"
)
// Generate factory code...
}
}
class AutoFactoryProcessorProvider : SymbolProcessorProvider {
override fun create(environment: SymbolProcessorEnvironment) =
AutoFactoryProcessor(environment.codeGenerator, environment.logger)
}
inline fun <reified T> String.parseJson(): T {
return Json.decodeFromString(serializer(), this)
}
inline fun <reified T : Any> ServiceLocator.get(): T {
return get(T::class)
}
// Usage
val users: List<User> = jsonString.parseJson()
val userService: UserService = locator.get()
@OptIn(ExperimentalContracts::class)
fun requireNotEmpty(value: String?, lazyMessage: () -> String = { "Value required" }): String {
contract { returns() implies (value != null) }
if (value.isNullOrEmpty()) throw IllegalArgumentException(lazyMessage())
return value
}
// Usage - smart cast works after contract
fun processUser(name: String?) {
val validName = requireNotEmpty(name)
println(validName.uppercase()) // name is smart-cast to String
}
// Enable with -Xcontext-receivers
context(LoggerContext, TransactionContext)
suspend fun transferMoney(from: Account, to: Account, amount: Money) {
logger.info("Transferring $amount")
transaction {
from.withdraw(amount)
to.deposit(amount)
}
}
interface LoggerContext { val logger: Logger }
interface TransactionContext { suspend fun <T> transaction(block: suspend () -> T): T }
// Usage
class MoneyService : LoggerContext, TransactionContext {
override val logger = LoggerFactory.getLogger(this::class.java)
override suspend fun <T> transaction(block: suspend () -> T) = db.transaction { block() }
suspend fun doTransfer(request: TransferRequest) {
transferMoney(request.from, request.to, request.amount)
}
}
@Target(AnnotationTarget.CLASS)
annotation class ValidateProperties(
val requireNonNull: Array<String> = []
)
class PropertyValidatorProcessor(private val logger: KSPLogger) : SymbolProcessor {
override fun process(resolver: Resolver): List<KSAnnotated> {
resolver.getSymbolsWithAnnotation(ValidateProperties::class.qualifiedName!!)
.filterIsInstance<KSClassDeclaration>()
.forEach { classDecl ->
val annotation = classDecl.annotations.first {
it.shortName.asString() == "ValidateProperties"
}
val requireNonNull = annotation.arguments
.first { it.name?.asString() == "requireNonNull" }
.value as List<String>
requireNonNull.forEach { propName ->
val prop = classDecl.getAllProperties()
.firstOrNull { it.simpleName.asString() == propName }
if (prop?.type?.resolve()?.isMarkedNullable == true) {
logger.error("Property '$propName' must be non-nullable", prop)
}
}
}
return emptyList()
}
}
| Skill | Bond Type | Use Case |
|---|---|---|
| (none) | - | Standalone advanced agent |
Task(subagent_type="kotlin:08-kotlin-advanced")
| Version | Date | Changes |
|---|---|---|
| 1.0.0 | 2025-12-30 | Production-grade with KSP, contracts, context receivers |
Use this agent to verify that a Python Agent SDK application is properly configured, follows SDK best practices and documentation recommendations, and is ready for deployment or testing. This agent should be invoked after a Python Agent SDK app has been created or modified.
Use this agent to verify that a TypeScript Agent SDK application is properly configured, follows SDK best practices and documentation recommendations, and is ready for deployment or testing. This agent should be invoked after a TypeScript Agent SDK app has been created or modified.