Kapt3: Add Kapt runner

This commit is contained in:
Yan Zhulanow
2016-10-20 16:06:24 +03:00
committed by Yan Zhulanow
parent 726471d98e
commit aae80fa4ab
6 changed files with 201 additions and 0 deletions
+1
View File
@@ -68,6 +68,7 @@
<module fileurl="file://$PROJECT_DIR$/js/js.tests/js.tests.iml" filepath="$PROJECT_DIR$/js/js.tests/js.tests.iml" group="compiler/js" />
<module fileurl="file://$PROJECT_DIR$/js/js.translator/js.translator.iml" filepath="$PROJECT_DIR$/js/js.translator/js.translator.iml" group="compiler/js" />
<module fileurl="file://$PROJECT_DIR$/jps-plugin/kannotator-jps-plugin-test/kannotator-jps-plugin-test.iml" filepath="$PROJECT_DIR$/jps-plugin/kannotator-jps-plugin-test/kannotator-jps-plugin-test.iml" group="ide/jps" />
<module fileurl="file://$PROJECT_DIR$/plugins/kapt3/kapt3.iml" filepath="$PROJECT_DIR$/plugins/kapt3/kapt3.iml" />
<module fileurl="file://$PROJECT_DIR$/compiler/light-classes/light-classes.iml" filepath="$PROJECT_DIR$/compiler/light-classes/light-classes.iml" group="compiler/java" />
<module fileurl="file://$PROJECT_DIR$/plugins/lint/lint-api/lint-api.iml" filepath="$PROJECT_DIR$/plugins/lint/lint-api/lint-api.iml" group="plugins/lint" />
<module fileurl="file://$PROJECT_DIR$/plugins/lint/lint-checks/lint-checks.iml" filepath="$PROJECT_DIR$/plugins/lint/lint-checks/lint-checks.iml" group="plugins/lint" />
+17
View File
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
</content>
<orderEntry type="jdk" jdkName="1.8" jdkType="JavaSDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="frontend" />
<orderEntry type="module" module-name="backend" />
<orderEntry type="module" module-name="frontend.java" />
<orderEntry type="library" name="kotlin-runtime" level="project" />
<orderEntry type="library" scope="TEST" name="junit-4.12" level="project" />
</component>
</module>
+31
View File
@@ -0,0 +1,31 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.kapt3
import com.sun.tools.javac.comp.CompileStates
import com.sun.tools.javac.main.JavaCompiler
import com.sun.tools.javac.util.Context
class KaptJavaCompiler(context: Context) : JavaCompiler(context) {
public override fun shouldStop(cs: CompileStates.CompileState) = super.shouldStop(cs)
companion object {
fun preRegister(context: Context) {
context.put(compilerKey, Context.Factory<JavaCompiler>(::KaptJavaCompiler))
}
}
}
+69
View File
@@ -0,0 +1,69 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.kapt3
import com.sun.tools.javac.comp.CompileStates
import com.sun.tools.javac.file.JavacFileManager
import com.sun.tools.javac.main.JavaCompiler
import com.sun.tools.javac.main.Option
import com.sun.tools.javac.processing.JavacProcessingEnvironment
import com.sun.tools.javac.util.Context
import com.sun.tools.javac.util.Log
import com.sun.tools.javac.util.Options
import java.io.File
import java.io.PrintWriter
import javax.annotation.processing.Processor
import javax.tools.JavaFileManager
class KaptError : RuntimeException {
constructor(message: String) : super(message)
constructor(message: String, cause: Throwable) : super(message, cause)
}
class KaptRunner {
fun doAnnotationProcessing(javaSourceFiles: List<File>, processors: List<Processor>, sourceOutputDir: File, classOutputDir: File) {
val context = Context()
JavacFileManager.preRegister(context)
KaptJavaCompiler.preRegister(context)
val options = Options.instance(context)
context.put(Log.outKey, PrintWriter(System.err, true))
options.put(Option.PROC, "only") // Only process annotations
options.put(Option.S, sourceOutputDir.canonicalPath)
options.put(Option.D, classOutputDir.canonicalPath)
val fileManager = context.get(JavaFileManager::class.java) as JavacFileManager
val compiler = JavaCompiler.instance(context) as KaptJavaCompiler
val processingEnvironment = JavacProcessingEnvironment.instance(context)
try {
compiler.initProcessAnnotations(processors)
val javaFileObjects = fileManager.getJavaFileObjectsFromFiles(javaSourceFiles)
val parsedJavaFiles = compiler.parseFiles(javaFileObjects)
if (compiler.shouldStop(CompileStates.CompileState.PARSE)) {
throw KaptError("Error while parsing Java files.")
}
val compilerAfterAnnotationProcessing = compiler.processAnnotations(compiler.enterTrees(parsedJavaFiles))
compilerAfterAnnotationProcessing.close()
} finally {
processingEnvironment.close()
fileManager.close()
}
}
}
+71
View File
@@ -0,0 +1,71 @@
import org.jetbrains.kotlin.kapt3.KaptRunner
import org.junit.Assert
import org.junit.Assert.*
import org.junit.Test
import java.io.File
import java.nio.file.Files
import javax.annotation.processing.AbstractProcessor
import javax.annotation.processing.RoundEnvironment
import javax.lang.model.element.TypeElement
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class KaptRunnerTest {
private companion object {
val TEST_DATA_DIR = File("plugins/kapt3/testData/runner")
}
@Test
fun testSimple() {
val processor = object : AbstractProcessor() {
override fun process(annotations: Set<TypeElement>, roundEnv: RoundEnvironment): Boolean {
for (annotation in annotations) {
val annotationName = annotation.simpleName.toString()
val annotatedElements = roundEnv.getElementsAnnotatedWith(annotation)
for (annotatedElement in annotatedElements) {
val generatedClassName = annotatedElement.simpleName.toString().capitalize() + annotationName.capitalize()
val file = processingEnv.filer.createSourceFile("generated." + generatedClassName)
file.openWriter().use {
it.write("""
package generated;
class $generatedClassName {}
""".trimIndent())
}
}
}
return true;
}
override fun getSupportedAnnotationTypes() = setOf("test.MyAnnotation")
}
val sourceOutputDir = Files.createTempDirectory("kaptRunner").toFile()
try {
KaptRunner().doAnnotationProcessing(
listOf(File(TEST_DATA_DIR, "Simple.java")),
listOf(processor),
sourceOutputDir,
sourceOutputDir)
val myMethodFile = File(sourceOutputDir, "generated/MyMethodMyAnnotation.java")
assertTrue(myMethodFile.exists())
} finally {
sourceOutputDir.deleteRecursively()
}
}
}
+12
View File
@@ -0,0 +1,12 @@
package test;
class Simple {
@MyAnnotation
void myMethod() {
// do nothing
}
}
@interface MyAnnotation {
}