Kapt3: Add simple AP test with Kotlin
This commit is contained in:
committed by
Yan Zhulanow
parent
5b780ec56c
commit
64046f1e40
@@ -137,6 +137,7 @@ import org.jetbrains.kotlin.jvm.compiler.*
|
||||
import org.jetbrains.kotlin.jvm.runtime.AbstractJvm8RuntimeDescriptorLoaderTest
|
||||
import org.jetbrains.kotlin.jvm.runtime.AbstractJvmRuntimeDescriptorLoaderTest
|
||||
import org.jetbrains.kotlin.kapt3.test.AbstractJCTreeConverterTest
|
||||
import org.jetbrains.kotlin.kapt3.test.AbstractKotlinKaptRunnerTest
|
||||
import org.jetbrains.kotlin.kdoc.AbstractKDocLexerTest
|
||||
import org.jetbrains.kotlin.lang.resolve.android.test.AbstractAndroidBoxTest
|
||||
import org.jetbrains.kotlin.lang.resolve.android.test.AbstractAndroidBytecodeShapeTest
|
||||
@@ -1142,6 +1143,10 @@ fun main(args: Array<String>) {
|
||||
testClass<AbstractJCTreeConverterTest> {
|
||||
model("converter")
|
||||
}
|
||||
|
||||
testClass<AbstractKotlinKaptRunnerTest> {
|
||||
model("kotlinRunner")
|
||||
}
|
||||
}
|
||||
|
||||
testGroup("plugins/android-extensions/android-extensions-idea/tests", "plugins/android-extensions/android-extensions-idea/testData") {
|
||||
|
||||
@@ -23,6 +23,7 @@ import com.sun.tools.javac.main.Option
|
||||
import com.sun.tools.javac.processing.AnnotationProcessingError
|
||||
import com.sun.tools.javac.processing.JavacProcessingEnvironment
|
||||
import com.sun.tools.javac.tree.JCTree
|
||||
import com.sun.tools.javac.tree.TreeMaker
|
||||
import com.sun.tools.javac.util.Context
|
||||
import com.sun.tools.javac.util.Options
|
||||
import java.io.File
|
||||
@@ -51,6 +52,7 @@ class KaptError : RuntimeException {
|
||||
class KaptRunner {
|
||||
val context = Context()
|
||||
val compiler: KaptJavaCompiler
|
||||
val fileManager: JavacFileManager
|
||||
private val options: Options
|
||||
|
||||
init {
|
||||
@@ -58,11 +60,17 @@ class KaptRunner {
|
||||
KaptTreeMaker.preRegister(context)
|
||||
KaptJavaCompiler.preRegister(context)
|
||||
|
||||
fileManager = context.get(JavaFileManager::class.java) as JavacFileManager
|
||||
compiler = JavaCompiler.instance(context) as KaptJavaCompiler
|
||||
|
||||
options = Options.instance(context)
|
||||
}
|
||||
|
||||
fun close() {
|
||||
compiler.close()
|
||||
fileManager.close()
|
||||
}
|
||||
|
||||
fun parseJavaFiles(
|
||||
javaSourceFiles: List<File>,
|
||||
classpath: List<File>
|
||||
@@ -85,7 +93,8 @@ class KaptRunner {
|
||||
processors: List<Processor>,
|
||||
classpath: List<File>,
|
||||
sourceOutputDir: File,
|
||||
classOutputDir: File
|
||||
classOutputDir: File,
|
||||
additionalSources: JavacList<JCTree.JCCompilationUnit> = JavacList.nil()
|
||||
) {
|
||||
options.put(Option.PROC, "only") // Only process annotations
|
||||
classpath.forEach { options.put(Option.CLASSPATH, it.canonicalPath) }
|
||||
@@ -106,7 +115,7 @@ class KaptRunner {
|
||||
|
||||
val compilerAfterAnnotationProcessing: JavaCompiler? = null
|
||||
try {
|
||||
compiler.processAnnotations(compiler.enterTrees(parsedJavaFiles))
|
||||
compiler.processAnnotations(compiler.enterTrees(parsedJavaFiles + additionalSources))
|
||||
} catch (e: AnnotationProcessingError) {
|
||||
throw KaptError(KaptError.Kind.EXCEPTION, e.cause ?: e)
|
||||
}
|
||||
|
||||
@@ -36,11 +36,20 @@ class SyntheticJavaFileObject(
|
||||
|
||||
override fun inferBinaryName(path: MutableIterable<File>?) = throw UnsupportedOperationException()
|
||||
|
||||
override fun isNameCompatible(simpleName: String?, kind: JavaFileObject.Kind?) = true
|
||||
override fun isNameCompatible(simpleName: String?, kind: JavaFileObject.Kind?): Boolean {
|
||||
if (simpleName == null || kind == null) return false
|
||||
return this.kind == kind && simpleName == clazz.simpleName.toString()
|
||||
}
|
||||
|
||||
override fun getKind() = JavaFileObject.Kind.SOURCE
|
||||
|
||||
override fun getName() = compilationUnit.packageName.toString().replace('.', '/') + clazz.name + ".java"
|
||||
override fun getName(): String {
|
||||
val packageName = compilationUnit.packageName
|
||||
if (packageName == null || packageName.toString() == "") {
|
||||
return clazz.name.toString() + ".java"
|
||||
}
|
||||
return packageName.toString().replace('.', '/') + '/' + clazz.simpleName.toString() + ".java"
|
||||
}
|
||||
|
||||
override fun getAccessLevel(): Modifier? {
|
||||
val flags = clazz.modifiers.getFlags()
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* 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.test
|
||||
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import com.sun.tools.javac.comp.CompileStates
|
||||
import org.jetbrains.kotlin.codegen.CodegenTestCase
|
||||
import org.jetbrains.kotlin.codegen.CodegenTestUtil
|
||||
import org.jetbrains.kotlin.kapt3.JCTreeConverter
|
||||
import org.jetbrains.kotlin.kapt3.Kapt3BuilderFactory
|
||||
import org.jetbrains.kotlin.kapt3.KaptRunner
|
||||
import org.jetbrains.kotlin.test.ConfigurationKind
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||
import org.jetbrains.kotlin.test.util.trimTrailingWhitespacesAndAddNewlineAtEOF
|
||||
import java.io.File
|
||||
|
||||
abstract class AbstractJCTreeConverterTest : CodegenTestCase() {
|
||||
override fun doMultiFileTest(wholeFile: File, files: List<TestFile>, javaFilesDir: File?) {
|
||||
val javaSources = javaFilesDir?.let { arrayOf(it) } ?: emptyArray()
|
||||
|
||||
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.ALL, *javaSources)
|
||||
loadMultiFiles(files)
|
||||
|
||||
val txtFile = File(wholeFile.parentFile, wholeFile.nameWithoutExtension + ".txt")
|
||||
val classBuilderFactory = Kapt3BuilderFactory()
|
||||
val factory = CodegenTestUtil.generateFiles(myEnvironment, myFiles, classBuilderFactory)
|
||||
val typeMapper = factory.generationState.typeMapper
|
||||
|
||||
val kaptRunner = KaptRunner()
|
||||
try {
|
||||
val converter = JCTreeConverter(kaptRunner.context, typeMapper, classBuilderFactory.compiledClasses, classBuilderFactory.origins)
|
||||
val javaFiles = converter.convert()
|
||||
|
||||
kaptRunner.compiler.enterTrees(javaFiles)
|
||||
|
||||
val actualRaw = javaFiles.joinToString ("\n\n////////////////////\n\n")
|
||||
val actual = StringUtil.convertLineSeparators(actualRaw.trim({ it <= ' ' })).trimTrailingWhitespacesAndAddNewlineAtEOF()
|
||||
|
||||
if (kaptRunner.compiler.shouldStop(CompileStates.CompileState.ENTER)) {
|
||||
error("There were errors during analysis. See errors above. Stubs:\n\n$actual")
|
||||
}
|
||||
|
||||
KotlinTestUtils.assertEqualsToFile(txtFile, actual)
|
||||
} finally {
|
||||
kaptRunner.compiler.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* 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.test
|
||||
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import com.sun.tools.javac.comp.CompileStates
|
||||
import com.sun.tools.javac.tree.JCTree
|
||||
import org.jetbrains.kotlin.codegen.CodegenTestCase
|
||||
import org.jetbrains.kotlin.codegen.CodegenTestUtil
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.kapt3.JCTreeConverter
|
||||
import org.jetbrains.kotlin.kapt3.Kapt3BuilderFactory
|
||||
import org.jetbrains.kotlin.kapt3.KaptRunner
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||
import org.jetbrains.kotlin.test.ConfigurationKind
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||
import org.jetbrains.kotlin.test.util.trimTrailingWhitespacesAndAddNewlineAtEOF
|
||||
import org.jetbrains.org.objectweb.asm.tree.ClassNode
|
||||
import com.sun.tools.javac.util.List as JavacList
|
||||
import java.io.File
|
||||
import java.nio.file.Files
|
||||
|
||||
abstract class AbstractKotlinKapt3Test : CodegenTestCase() {
|
||||
protected companion object {
|
||||
val FILE_SEPARATOR = "\n\n////////////////////\n\n"
|
||||
}
|
||||
|
||||
override fun doMultiFileTest(wholeFile: File, files: List<TestFile>, javaFilesDir: File?) {
|
||||
val javaSources = javaFilesDir?.let { arrayOf(it) } ?: emptyArray()
|
||||
|
||||
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.ALL, *javaSources)
|
||||
loadMultiFiles(files)
|
||||
|
||||
val txtFile = File(wholeFile.parentFile, wholeFile.nameWithoutExtension + ".txt")
|
||||
val classBuilderFactory = Kapt3BuilderFactory()
|
||||
val factory = CodegenTestUtil.generateFiles(myEnvironment, myFiles, classBuilderFactory)
|
||||
val typeMapper = factory.generationState.typeMapper
|
||||
|
||||
val kaptRunner = KaptRunner()
|
||||
try {
|
||||
check(kaptRunner, typeMapper, classBuilderFactory, txtFile)
|
||||
} finally {
|
||||
kaptRunner.close()
|
||||
}
|
||||
}
|
||||
|
||||
protected fun convert(
|
||||
kaptRunner: KaptRunner,
|
||||
typeMapper: KotlinTypeMapper,
|
||||
compiledClasses: List<ClassNode>,
|
||||
origins: Map<Any, JvmDeclarationOrigin>
|
||||
): JavacList<JCTree.JCCompilationUnit> {
|
||||
val converter = JCTreeConverter(kaptRunner.context, typeMapper, compiledClasses, origins)
|
||||
return converter.convert()
|
||||
}
|
||||
|
||||
protected abstract fun check(
|
||||
kaptRunner: KaptRunner,
|
||||
typeMapper: KotlinTypeMapper,
|
||||
classBuilderFactory: Kapt3BuilderFactory,
|
||||
txtFile: File)
|
||||
}
|
||||
|
||||
abstract class AbstractJCTreeConverterTest : AbstractKotlinKapt3Test() {
|
||||
override fun check(kaptRunner: KaptRunner, typeMapper: KotlinTypeMapper, classBuilderFactory: Kapt3BuilderFactory, txtFile: File) {
|
||||
val javaFiles = convert(kaptRunner, typeMapper, classBuilderFactory.compiledClasses, classBuilderFactory.origins)
|
||||
kaptRunner.compiler.enterTrees(javaFiles)
|
||||
|
||||
val actualRaw = javaFiles.joinToString (FILE_SEPARATOR)
|
||||
val actual = StringUtil.convertLineSeparators(actualRaw.trim({ it <= ' ' })).trimTrailingWhitespacesAndAddNewlineAtEOF()
|
||||
|
||||
if (kaptRunner.compiler.shouldStop(CompileStates.CompileState.ENTER)) {
|
||||
error("There were errors during analysis. See errors above. Stubs:\n\n$actual")
|
||||
}
|
||||
KotlinTestUtils.assertEqualsToFile(txtFile, actual)
|
||||
}
|
||||
}
|
||||
|
||||
abstract class AbstractKotlinKaptRunnerTest : AbstractKotlinKapt3Test() {
|
||||
override fun check(kaptRunner: KaptRunner, typeMapper: KotlinTypeMapper, classBuilderFactory: Kapt3BuilderFactory, txtFile: File) {
|
||||
val compilationUnits = convert(kaptRunner, typeMapper, classBuilderFactory.compiledClasses, classBuilderFactory.origins)
|
||||
val sourceOutputDir = Files.createTempDirectory("kaptRunner").toFile()
|
||||
try {
|
||||
kaptRunner.doAnnotationProcessing(emptyList(), listOf(KaptRunnerTest.SIMPLE_PROCESSOR),
|
||||
classpath = listOf(), sourceOutputDir = sourceOutputDir, classOutputDir = sourceOutputDir,
|
||||
additionalSources = compilationUnits)
|
||||
|
||||
val javaFiles = sourceOutputDir.walkTopDown().filter { it.isFile && it.extension == "java" }
|
||||
val actualRaw = javaFiles.sortedBy { it.name }.joinToString(FILE_SEPARATOR) { it.name + ":\n\n" + it.readText() }
|
||||
val actual = StringUtil.convertLineSeparators(actualRaw.trim({ it <= ' ' })).trimTrailingWhitespacesAndAddNewlineAtEOF()
|
||||
KotlinTestUtils.assertEqualsToFile(txtFile, actual)
|
||||
} finally {
|
||||
sourceOutputDir.deleteRecursively()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -43,8 +43,8 @@ import javax.lang.model.element.TypeElement
|
||||
*/
|
||||
|
||||
class KaptRunnerTest {
|
||||
private companion object {
|
||||
val TEST_DATA_DIR = File("plugins/kapt3/testData/runner")
|
||||
companion object {
|
||||
private val TEST_DATA_DIR = File("plugins/kapt3/testData/runner")
|
||||
|
||||
val SIMPLE_PROCESSOR = object : AbstractProcessor() {
|
||||
override fun process(annotations: Set<TypeElement>, roundEnv: RoundEnvironment): Boolean {
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.test;
|
||||
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
||||
import org.jetbrains.kotlin.test.TestMetadata;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
|
||||
@SuppressWarnings("all")
|
||||
@TestMetadata("plugins/kapt3/testData/kotlinRunner")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public class KotlinKaptRunnerTestGenerated extends AbstractKotlinKaptRunnerTest {
|
||||
public void testAllFilesPresentInKotlinRunner() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("plugins/kapt3/testData/kotlinRunner"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("Simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("plugins/kapt3/testData/kotlinRunner/Simple.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package test
|
||||
|
||||
internal class Simple {
|
||||
@MyAnnotation
|
||||
fun myMethod() {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
|
||||
internal annotation class MyAnnotation
|
||||
|
||||
internal enum class EnumClass {
|
||||
BLACK, WHITE
|
||||
}
|
||||
|
||||
|
||||
internal enum class EnumClass2 private constructor(private val blah: String) {
|
||||
WHITE("A"), RED("B")
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
MyMethodMyAnnotation.java:
|
||||
|
||||
package generated;
|
||||
class MyMethodMyAnnotation {}
|
||||
@@ -36,5 +36,6 @@
|
||||
<orderEntry type="module" module-name="annotation-processing" scope="TEST" />
|
||||
<orderEntry type="module" module-name="build-common" scope="TEST" />
|
||||
<orderEntry type="module" module-name="jps-tests" scope="TEST" />
|
||||
<orderEntry type="module" module-name="kapt3" scope="TEST" />
|
||||
</component>
|
||||
</module>
|
||||
Reference in New Issue
Block a user