Slide 1

Slide 1 text

kompile-testing internal @hotchemi

Slide 2

Slide 2 text

• google/compile-testing • Testing tools for javac and apt • Used in some code-gen libraries • Dagger2 • JavaPoet • Auto

Slide 3

Slide 3 text

Compilation compilation = javac() .withProcessors(new Processor()) .compile(JavaFileObjects.forResource("HelloWorld.java")); assertThat(compilation).succeeded(); assertThat(compilation) .generatedSourceFile("GeneratedHelloWorld") .hasSourceEquivalentTo( JavaFileObjects.forResource("GeneratedHelloWorld.java"));

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

• kompile-testing • Simple API as compile-testing provides • Supports kotlinc and kapt • Version: 0.1.2(alpha)

Slide 6

Slide 6 text

kotlinc() .withProcessors(Processor()) .addKotlin("input.kt", """ import kompile.testing.TestAnnotation @TestAnnotation class TestClass """.trimIndent()) .compile() .succeededWithoutWarnings() .generatedFile("generatedKtFile.kt") .hasSourceEquivalentTo(""" class GeneratedKtFile """.trimIndent())

Slide 7

Slide 7 text

Demo

Slide 8

Slide 8 text

Under the hood

Slide 9

Slide 9 text

Register processors - Write KClass info as a jar file - For specifying kapt options Add Kotlin file - Just write contents to .kt file - Under source directory Run Kotlin compiler API - Define classpath and kapt options - Then run K2JVMCompiler#exec

Slide 10

Slide 10 text

K2JVMCompiler().exec( errStream = /* stream to output error */), args = /* CLI options */)

Slide 11

Slide 11 text

• Command line compiler kotlinc hello.kt -d hello.jar kotlin -classpath hello.jar HelloKt

Slide 12

Slide 12 text

• plugin/kapt options kotlinc hello.kt -d hello.jar -Xplugin=$KOTLIN_HOME/lib/kotlin-annotation-processing.jar -P plugin:org.jetbrains.kotlin.kapt3:sources=build/kapt/sources -P plugin:org.jetbrains.kotlin.kapt3:classes=build/kapt/classes -P plugin:org.jetbrains.kotlin.kapt3:stubs=build/kapt/stubs -P plugin:org.jetbrains.kotlin.kapt3:aptMode=stubsAndApt -P plugin:org.jetbrains.kotlin.kapt3:correctErrorTypes=true -P plugin:org.jetbrains.kotlin.kapt3:apclasspath=lib/apt.jar

Slide 13

Slide 13 text

fun compile(): Compilation { val args = mutableListOf() args.add("-d") args.add(classesDir.toString()) args.add("-no-stdlib") args.add("-classpath") args.add(fullClasspath().joinToString(separator = ":")) val sourceFiles = sourcesDir.listFiles() if (sourceFiles != null && sourceFiles.isNotEmpty()) { sourceFiles.forEach { args.add(it.toString()) } } val generatedDir = File(rootDir, "generated") args.addAll(annotationProcessorArgs(generatedDir.path)) val systemErrBuffer = Buffer() val stream = PrintStream(systemErrBuffer.outputStream()) val args = *args.toTypedArray() val exitCode = K2JVMCompiler().exec(stream, args) return Compilation(systemErrBuffer.readUtf8(), exitCode, generatedDir) }

Slide 14

Slide 14 text

private fun annotationProcessorArgs(generatedDirPath: String): List { val sourceDir = File(rootDir, "kapt/sources") val stubsDir = File(rootDir, "kapt/stubs") val kaptArgs = mutableMapOf() kaptArgs["kapt.kotlin.generated"] = generatedDirPath val plugin = classpathFiles.find { it.name.startsWith(“kotlin-annotation-processing-embeddable”) } return listOf( "-Xplugin=$plugin", "-P", "plugin:org.jetbrains.kotlin.kapt3:sources=$sourceDir", "-P", "plugin:org.jetbrains.kotlin.kapt3:classes=$classesDir", "-P", "plugin:org.jetbrains.kotlin.kapt3:stubs=$stubsDir", "-P", "plugin:org.jetbrains.kotlin.kapt3:apclasspath=$servicesJar", "-P", "plugin:org.jetbrains.kotlin.kapt3:aptMode=stubsAndApt", "-P", "plugin:org.jetbrains.kotlin.kapt3:correctErrorTypes=true", "-P", "plugin:org.jetbrains.kotlin.kapt3:apoptions=${options(kaptArgs)}" ) }

Slide 15

Slide 15 text

• Conclusion • Extensible compiler API once you figure out • Go into jetbrains/kotlin! • Support Kotlin in your code-gen project with kompile-testing • Still alpha though:D

Slide 16

Slide 16 text

• References • https://kotlinlang.org/docs/tutorials/command-line.html • https://kotlinlang.org/docs/reference/kapt.html • https://kotlinlang.org/docs/reference/compiler- plugins.html • https://speakerdeck.com/kevinmost/writing-your-first- kotlin-compiler-plugin