Kapt: Add tests with Filer.

JavaFileObject.getName() now returns a path as required.
(cherry picked from commit c611f9b)
This commit is contained in:
Yan Zhulanow
2016-08-31 19:40:51 +03:00
committed by Yan Zhulanow
parent 824b778a7b
commit 743be477ec
9 changed files with 131 additions and 16 deletions
@@ -36,7 +36,7 @@ class KotlinFiler(
internal var wasAnythingGenerated: Boolean = false
private set
private fun getGeneratedFile(nameCharSequence: CharSequence, extension: String): File {
private fun getGeneratedFile(nameCharSequence: CharSequence, extension: String, baseDir: File = generatedSourceDir): Pair<File, String> {
val name = nameCharSequence.toString()
val isPackageInfo = name.endsWith(PACKAGE_INFO_SUFFIX)
val fqName = if (isPackageInfo) name.substring(0, PACKAGE_INFO_SUFFIX.length) else name
@@ -44,14 +44,15 @@ class KotlinFiler(
val packageName = fqName.substringBeforeLast('.', "")
val packageDir = if (packageName.isNotEmpty()) {
File(generatedSourceDir, packageName.replace('.', '/')).apply { mkdirs() }
File(baseDir, packageName.replace('.', '/')).apply { mkdirs() }
}
else {
generatedSourceDir
baseDir
}
val fileName = fqName.substringAfterLast('.') + (if (isPackageInfo) PACKAGE_INFO_SUFFIX else extension)
return File(packageDir, fileName)
val file = File(packageDir, fileName)
return Pair(file, file.toRelativeString(baseDir))
}
private fun File.notifyCreated() = apply {
@@ -60,11 +61,13 @@ class KotlinFiler(
}
override fun createSourceFile(name: CharSequence, vararg originatingElements: Element?): JavaFileObject {
return KotlinJavaFileObject(getGeneratedFile(name, ".java").notifyCreated())
val (file, fileName) = getGeneratedFile(name, ".java")
return KotlinJavaFileObject(file.notifyCreated(), fileName)
}
override fun getResource(location: JavaFileManager.Location, pkg: CharSequence, relativeName: CharSequence): FileObject? {
return KotlinFileObject(getResourceFile(location, pkg, relativeName))
val (file, fileName) = getResourceFile(location, pkg, relativeName)
return KotlinFileObject(file, fileName)
}
override fun createResource(
@@ -73,12 +76,12 @@ class KotlinFiler(
relativeName: CharSequence,
vararg originatingElements: Element?
): FileObject? {
val resourceFile = getResourceFile(location, pkg, relativeName)
val (resourceFile, fileName) = getResourceFile(location, pkg, relativeName)
resourceFile.parentFile.mkdirs()
return KotlinFileObject(resourceFile.notifyCreated())
return KotlinFileObject(resourceFile.notifyCreated(), fileName)
}
private fun getResourceFile(location: JavaFileManager.Location, pkg: CharSequence, relativeName: CharSequence): File {
private fun getResourceFile(location: JavaFileManager.Location, pkg: CharSequence, relativeName: CharSequence): Pair<File, String> {
val baseDir = when (location) {
StandardLocation.CLASS_OUTPUT -> classesOutputDir
StandardLocation.SOURCE_OUTPUT -> generatedSourceDir
@@ -88,10 +91,12 @@ class KotlinFiler(
val targetDir = File(baseDir, pkg.toString().replace('.', '/'))
targetDir.mkdirs()
return File(targetDir, relativeName.toString())
val resourceFile = File(targetDir, relativeName.toString())
return Pair(resourceFile, resourceFile.toRelativeString(baseDir))
}
override fun createClassFile(name: CharSequence, vararg originatingElements: Element?): JavaFileObject {
return KotlinJavaFileObject(getGeneratedFile(name, ".class").notifyCreated())
val (file, fileName) = getGeneratedFile(name, ".class")
return KotlinJavaFileObject(file.notifyCreated(), fileName)
}
}
@@ -20,7 +20,7 @@ import java.io.File
import javax.tools.FileObject
import javax.tools.JavaFileObject
class KotlinJavaFileObject(file: File) : KotlinAbstractFileObject(file), JavaFileObject {
class KotlinJavaFileObject(file: File, fileName: String) : KotlinAbstractFileObject(file, fileName), JavaFileObject {
//TODO
override fun isNameCompatible(simpleName: String, kind: JavaFileObject.Kind) = true
@@ -38,12 +38,12 @@ class KotlinJavaFileObject(file: File) : KotlinAbstractFileObject(file), JavaFil
override fun getNestingKind() = null
}
class KotlinFileObject(file: File) : KotlinAbstractFileObject(file)
class KotlinFileObject(file: File, fileName: String) : KotlinAbstractFileObject(file, fileName)
abstract class KotlinAbstractFileObject(val file: File) : FileObject {
abstract class KotlinAbstractFileObject(val file: File, val fileName: String) : FileObject {
override fun openOutputStream() = file.outputStream()
override fun getName() = file.name
override fun getName() = fileName
override fun openWriter() = file.writer()
@@ -0,0 +1,9 @@
annotation class Inject
class Test {
@Inject
fun myFunc(): String = "Mary"
@field:Inject
val myField: String = "Tom"
}
@@ -0,0 +1,9 @@
annotation class Inject
annotation class Inject2
@Inject2
class Test {
@Inject
@Inject2
fun myFunc(): String = "Mary"
}
@@ -0,0 +1,4 @@
annotation class Inject2
@Inject2
class Test
@@ -0,0 +1,8 @@
annotation class Inject
annotation class Inject2
@Inject
class Test {
@Inject
fun myFunc(): String = "Mary"
}
@@ -0,0 +1 @@
class Test
@@ -92,7 +92,7 @@ abstract class AbstractProcessorTest : AbstractBytecodeTextTest() {
vararg supportedAnnotations: String
) = testAP(false, name, { set, roundEnv, env -> fail("Should not run") }, *supportedAnnotations)
private fun testAP(
protected fun testAP(
shouldRun: Boolean,
name: String,
process: (Set<TypeElement>, RoundEnvironment, ProcessingEnvironment) -> Unit,
@@ -0,0 +1,79 @@
/*
* 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.annotation.processing.test.processor
import javax.lang.model.element.TypeElement
import javax.tools.JavaFileObject
class TestsWithFiler : AbstractProcessorTest() {
override val testDataDir = "plugins/annotation-processing/testData/withFiler"
fun testSimple() = filerTest("Simple", 1) { files ->
assertEquals(listOf("generated/Inject2Test.java"), files)
}
fun testMethodsFields() = filerTest("MethodsFields", 1) { files ->
assertEquals(listOf("generated/InjectmyField.java",
"generated/InjectmyFunc.java"), files)
}
fun testTwoRounds() = filerTest("TwoRounds", 2) { files ->
assertEquals(listOf("generated/Inject2InjectTest.java",
"generated/InjectTest.java",
"generated/InjectmyFunc.java"), files)
}
fun testOneRound() = filerTest("OneRound", 1) { files ->
assertEquals(listOf("generated/Inject2Test.java",
"generated/Inject2myFunc.java",
"generated/InjectmyFunc.java"), files)
}
fun testZeroRounds() = filerTest("ZeroRounds", 0) { files ->
assertEquals(emptyList<String>(), files)
}
private fun filerTest(
fileName: String,
roundCount: Int,
check: (List<String>) -> Unit) {
val filesCreated = mutableSetOf<JavaFileObject>()
var actualRoundCount = 0
testAP(roundCount > 0, fileName, { set, roundEnv, env ->
if (!roundEnv.processingOver()) actualRoundCount++
for (anno in set) {
val annotated = roundEnv.getElementsAnnotatedWith(anno)
annotated.forEach { el ->
val className = anno.simpleName.toString() + el.simpleName.toString()
env.filer.createSourceFile("generated.$className").apply {
filesCreated += this
val inject2 = if (el is TypeElement && anno.simpleName.toString() == "Inject") "@Inject2\n" else ""
openWriter().use {
it.write("package generated;\n" + inject2 +
"public class $className {}")
}
}
}
}
}, "Inject", "Inject2")
assertEquals(roundCount, actualRoundCount)
check(filesCreated.map { it.name }.sorted())
}
}