tree: 8a93c8b536aa8e67b0b5a48d15067595b0d64c01 [path history] [tgz]
  1. annotations/
  2. app/
  3. processor/
  4. build.gradle.kts
  5. README.md
  6. settings.gradle.kts
examples/hello-world/README.md

KSP Hello World Example

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.

Key Concepts

While this is a minimal example, it demonstrates several core KSP mechanisms that are essential to understand:

Selecting Functions to Process

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.

Generating Code

Using the selected function in the HelloWorldVisitor, we can create a new file and write directly to it like any other output stream.

Dependency Management

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")).

Inspecting Generated Code

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

Further Reading

Visit the KSP documentation for more information.