This project is a minimal, self-contained KSP project.
It configures KSP via its Gradle plugin as one would normally do, in the hopes of providing an example that a new user can read and learn from.
The project has three subprojects:
annotations: This subproject defines the Gen annotation. By keeping annotations in a separate module, we avoid leaking the processor‘s implementation or the KSP API to the app’s runtime.processor: This subproject defines a minimal processor that selects functions annotated with Gen and generates a function that prints a message.app: This subproject defines a single main that calls the generated function. The main function is annotated with Gen to trigger the processor.While this is a minimal example, it demonstrates several core KSP mechanisms that are essential to understand:
The processor‘s entry point is the process method, which receives a Resolver. The Resolver type is the primary tool for querying the KSP’s view of the source code.
In HelloWorldProcessor.kt, we use:
resolver.getSymbolsWithAnnotation(...): To find all symbols annotated with our fully qualified annotation name (com.example.annotations.Gen)..filterIsInstance<KSFunctionDeclaration>(): Since our processor is designed to work on functions, we filter the results to ensure we are only dealing with function declarations.Once filtered, we use the Visitor Pattern (it.accept(HelloWorldVisitor(), Unit)) to perform the actual code generation. This is the recommended way to traverse the KSP AST (Abstract Syntax Tree).
Note the file in processor/src/main/resources/META-INF/services/. It contains the fully qualified name of the SymbolProcessorProvider implementation. Without this, KSP will not know your processor exists.
Using the selected function in the HelloWorldVisitor, we can create a new file and write directly to it like any other output stream.
In app/build.gradle.kts, notice how the dependencies are split:
implementation(project(":annotations")): Gives the app access to the Gen annotation definition.ksp(project(":processor")): Tells the KSP plugin to run the processor during compilation.The separation ensures the processor‘s code only exists during the build phase and isn’t bundled into your final application. Note in processor/build.gradle.kts that the processor also depends on the annotations project with implementation(project(":annotations")).
You can find the source code generated by this processor in the build directory of the app: app/build/generated/ksp/main/kotlin/GeneratedHelloWorld.kt
Visit the KSP documentation for more information.