Introspekt is a positional code API and introspection framework for Kotlin Multiplatform.
It currently adds the following features:
SourceLocation
type with access to module name, file path, function name, line and columnFunctionInfo
type for introspecting current/caller function signature and locationClassInfo
type for introspecting current/caller classes including functionsAnnotationUsageInfo
type for introspecting annotation types and their parametersTypeInfo
type for fundamental RTTI integrated with kotlin.reflect to fix gaps on Kotlin/JS and other platforms- Default-parameter inlining for intrinsic types listed above (like
std::source_location
in C++) - Compile-time evaluation of location hashes to improve runtime performance for positional memoization
- Tracing API for automatically injecting trace callbacks into code, including manual spans and events
First, add the official Maven Central repository to your settings.gradle.kts
:
pluginManagement {
repositories {
maven("https://central.sonatype.com/repository/maven-snapshots")
mavenCentral()
}
}
dependencyResolutionManagement {
repositories {
maven("https://central.sonatype.com/repository/maven-snapshots")
mavenCentral()
}
}
Then add a dependency on the plugin in your root buildscript:
plugins {
id("dev.karmakrafts.introspekt.introspekt-gradle-plugin") version "<version>"
}
kotlin {
sourceSets {
commonMain {
dependencies {
implementation("dev.karmakrafts.introspekt:introspekt-runtime:<version>")
}
}
}
}
Tracing can be used to automatically inject callbacks into the code to collect certain events.
The events can be processed/collected using an implementation of TraceCollector
.
The following example illustrates a simple use-case for logging:
object MyCollector : TraceCollector {
private val logger: MyLogger = MyLogger() // Some logger from another library
fun enterSpan(span: TraceSpan) = logger.trace("Entering span ${span.name}")
fun leaveSpan(span: TraceSpan, end: SourceLocation) = logger.trace("Leaving span ${span.name}")
fun enterFunction(function: FunctionInfo) { /* ... */ }
fun leaveFunction(function: FunctionInfo) { /* ... */ }
fun call(callee: FunctionInfo, caller: FunctionInfo, location: SourceLocation) { /* ... */ }
fun event(event: TraceEvent) { /* ... */ }
}
fun main() {
// Register the collector before any code we want to trace is executed
TraceCollector.register(MyCollector)
// Enter code we want to trace
functionIWantToTrace()
}
@Trace // This will inject callbacks after every call, and when entering/leaving functions
fun functionIWantToTrace() {
TraceSpan.enter("My awesome span")
// ...
TraceSpan.leave()
// ...
}