Kapt: Add tests for the command-line 'kapt' tool

This commit is contained in:
Yan Zhulanow
2018-10-31 12:08:28 +09:00
parent 6e5eb0fdd4
commit 69ec958aab
36 changed files with 852 additions and 1 deletions
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.cli.common.arguments
import org.jetbrains.annotations.TestOnly
import java.io.File
import java.io.FileNotFoundException
import java.io.IOException
@@ -35,6 +36,12 @@ fun preprocessCommandLineArguments(args: List<String>, errors: ArgumentParseErro
}
}
@TestOnly
fun readArgumentsFromArgFile(content: String): List<String> {
val reader = content.reader()
return generateSequence { reader.parseNextArgument() }.toList()
}
private fun File.expand(errors: ArgumentParseErrors): List<String> {
return try {
bufferedReader(Charsets.UTF_8).use {
+1
View File
@@ -24,6 +24,7 @@ dependencies {
compile(projectTests(":plugins:android-extensions-ide"))
compile(projectTests(":plugins:android-extensions-jps"))
compile(projectTests(":kotlin-annotation-processing"))
compile(projectTests(":kotlin-annotation-processing-cli"))
compile(projectTests(":kotlin-allopen-compiler-plugin"))
compile(projectTests(":kotlin-noarg-compiler-plugin"))
compile(projectTests(":kotlin-sam-with-receiver-compiler-plugin"))
+1
View File
@@ -24,6 +24,7 @@ dependencies {
compile(projectTests(":plugins:android-extensions-ide"))
compile(projectTests(":plugins:android-extensions-jps"))
compile(projectTests(":kotlin-annotation-processing"))
compile(projectTests(":kotlin-annotation-processing-cli"))
compile(projectTests(":kotlin-allopen-compiler-plugin"))
compile(projectTests(":kotlin-noarg-compiler-plugin"))
compile(projectTests(":kotlin-sam-with-receiver-compiler-plugin"))
+1
View File
@@ -24,6 +24,7 @@ dependencies {
compile(projectTests(":plugins:android-extensions-ide"))
compile(projectTests(":plugins:android-extensions-jps"))
compile(projectTests(":kotlin-annotation-processing"))
compile(projectTests(":kotlin-annotation-processing-cli"))
compile(projectTests(":kotlin-allopen-compiler-plugin"))
compile(projectTests(":kotlin-noarg-compiler-plugin"))
compile(projectTests(":kotlin-sam-with-receiver-compiler-plugin"))
+1
View File
@@ -24,6 +24,7 @@ dependencies {
compile(projectTests(":plugins:android-extensions-ide"))
compile(projectTests(":plugins:android-extensions-jps"))
compile(projectTests(":kotlin-annotation-processing"))
compile(projectTests(":kotlin-annotation-processing-cli"))
compile(projectTests(":kotlin-allopen-compiler-plugin"))
compile(projectTests(":kotlin-noarg-compiler-plugin"))
compile(projectTests(":kotlin-sam-with-receiver-compiler-plugin"))
+1
View File
@@ -24,6 +24,7 @@ dependencies {
compile(projectTests(":plugins:android-extensions-ide"))
compile(projectTests(":plugins:android-extensions-jps"))
compile(projectTests(":kotlin-annotation-processing"))
compile(projectTests(":kotlin-annotation-processing-cli"))
compile(projectTests(":kotlin-allopen-compiler-plugin"))
compile(projectTests(":kotlin-noarg-compiler-plugin"))
compile(projectTests(":kotlin-sam-with-receiver-compiler-plugin"))
@@ -149,6 +149,8 @@ import org.jetbrains.kotlin.jps.build.android.AbstractAndroidJpsTestCase
import org.jetbrains.kotlin.jps.build.dependeciestxt.actualizeMppJpsIncTestCaseDirs
import org.jetbrains.kotlin.jps.incremental.AbstractJsProtoComparisonTest
import org.jetbrains.kotlin.jps.incremental.AbstractJvmProtoComparisonTest
import org.jetbrains.kotlin.kapt.cli.test.AbstractArgumentParsingTest
import org.jetbrains.kotlin.kapt.cli.test.AbstractKaptToolIntegrationTest
import org.jetbrains.kotlin.kapt3.test.AbstractClassFileToSourceStubConverterTest
import org.jetbrains.kotlin.kapt3.test.AbstractKotlinKaptContextTest
import org.jetbrains.kotlin.noarg.AbstractBlackBoxCodegenTestForNoArg
@@ -1073,6 +1075,16 @@ fun main(args: Array<String>) {
}
}
testGroup("plugins/kapt3/kapt3-cli/test", "plugins/kapt3/kapt3-cli/testData") {
testClass<AbstractArgumentParsingTest> {
model("argumentParsing", extension = "txt")
}
testClass<AbstractKaptToolIntegrationTest> {
model("integration", recursive = false, extension = null)
}
}
testGroup("plugins/allopen/allopen-cli/test", "plugins/allopen/allopen-cli/testData") {
testClass<AbstractBytecodeListingTestForAllOpen> {
model("bytecodeListing", extension = "kt")
@@ -148,6 +148,8 @@ import org.jetbrains.kotlin.j2k.AbstractJavaToKotlinConverterSingleFileTest
//import org.jetbrains.kotlin.jps.build.android.AbstractAndroidJpsTestCase
//import org.jetbrains.kotlin.jps.incremental.AbstractJsProtoComparisonTest
//import org.jetbrains.kotlin.jps.incremental.AbstractJvmProtoComparisonTest
import org.jetbrains.kotlin.kapt.cli.test.AbstractArgumentParsingTest
import org.jetbrains.kotlin.kapt.cli.test.AbstractKaptToolIntegrationTest
import org.jetbrains.kotlin.kapt3.test.AbstractClassFileToSourceStubConverterTest
import org.jetbrains.kotlin.kapt3.test.AbstractKotlinKaptContextTest
import org.jetbrains.kotlin.noarg.AbstractBlackBoxCodegenTestForNoArg
@@ -993,6 +995,16 @@ fun main(args: Array<String>) {
}
}
testGroup("plugins/kapt3/kapt3-cli/test", "plugins/kapt3/kapt3-cli/testData") {
testClass<AbstractArgumentParsingTest> {
model("argumentParsing", extension = "txt")
}
testClass<AbstractKaptToolIntegrationTest> {
model("integration", recursive = false, extension = null)
}
}
testGroup("plugins/allopen/allopen-cli/test", "plugins/allopen/allopen-cli/testData") {
testClass<AbstractBytecodeListingTestForAllOpen> {
model("bytecodeListing", extension = "kt")
@@ -148,6 +148,8 @@ import org.jetbrains.kotlin.j2k.AbstractJavaToKotlinConverterSingleFileTest
//import org.jetbrains.kotlin.jps.build.android.AbstractAndroidJpsTestCase
//import org.jetbrains.kotlin.jps.incremental.AbstractJsProtoComparisonTest
//import org.jetbrains.kotlin.jps.incremental.AbstractJvmProtoComparisonTest
import org.jetbrains.kotlin.kapt.cli.test.AbstractArgumentParsingTest
import org.jetbrains.kotlin.kapt.cli.test.AbstractKaptToolIntegrationTest
import org.jetbrains.kotlin.kapt3.test.AbstractClassFileToSourceStubConverterTest
import org.jetbrains.kotlin.kapt3.test.AbstractKotlinKaptContextTest
import org.jetbrains.kotlin.noarg.AbstractBlackBoxCodegenTestForNoArg
@@ -993,6 +995,16 @@ fun main(args: Array<String>) {
}
}
testGroup("plugins/kapt3/kapt3-cli/test", "plugins/kapt3/kapt3-cli/testData") {
testClass<AbstractArgumentParsingTest> {
model("argumentParsing", extension = "txt")
}
testClass<AbstractKaptToolIntegrationTest> {
model("integration", recursive = false, extension = null)
}
}
testGroup("plugins/allopen/allopen-cli/test", "plugins/allopen/allopen-cli/testData") {
testClass<AbstractBytecodeListingTestForAllOpen> {
model("bytecodeListing", extension = "kt")
@@ -140,6 +140,8 @@ import org.jetbrains.kotlin.j2k.AbstractJavaToKotlinConverterSingleFileTest
//import org.jetbrains.kotlin.jps.build.android.AbstractAndroidJpsTestCase
//import org.jetbrains.kotlin.jps.incremental.AbstractJsProtoComparisonTest
//import org.jetbrains.kotlin.jps.incremental.AbstractJvmProtoComparisonTest
import org.jetbrains.kotlin.kapt.cli.test.AbstractArgumentParsingTest
import org.jetbrains.kotlin.kapt.cli.test.AbstractKaptToolIntegrationTest
import org.jetbrains.kotlin.kapt3.test.AbstractClassFileToSourceStubConverterTest
import org.jetbrains.kotlin.kapt3.test.AbstractKotlinKaptContextTest
import org.jetbrains.kotlin.noarg.AbstractBlackBoxCodegenTestForNoArg
@@ -985,6 +987,16 @@ fun main(args: Array<String>) {
}
}
testGroup("plugins/kapt3/kapt3-cli/test", "plugins/kapt3/kapt3-cli/testData") {
testClass<AbstractArgumentParsingTest> {
model("argumentParsing", extension = "txt")
}
testClass<AbstractKaptToolIntegrationTest> {
model("integration", recursive = false, extension = null)
}
}
testGroup("plugins/allopen/allopen-cli/test", "plugins/allopen/allopen-cli/testData") {
testClass<AbstractBytecodeListingTestForAllOpen> {
model("bytecodeListing", extension = "kt")
@@ -140,6 +140,8 @@ import org.jetbrains.kotlin.j2k.AbstractJavaToKotlinConverterSingleFileTest
//import org.jetbrains.kotlin.jps.build.android.AbstractAndroidJpsTestCase
//import org.jetbrains.kotlin.jps.incremental.AbstractJsProtoComparisonTest
//import org.jetbrains.kotlin.jps.incremental.AbstractJvmProtoComparisonTest
import org.jetbrains.kotlin.kapt.cli.test.AbstractArgumentParsingTest
import org.jetbrains.kotlin.kapt.cli.test.AbstractKaptToolIntegrationTest
import org.jetbrains.kotlin.kapt3.test.AbstractClassFileToSourceStubConverterTest
import org.jetbrains.kotlin.kapt3.test.AbstractKotlinKaptContextTest
import org.jetbrains.kotlin.noarg.AbstractBlackBoxCodegenTestForNoArg
@@ -985,6 +987,16 @@ fun main(args: Array<String>) {
}
}
testGroup("plugins/kapt3/kapt3-cli/test", "plugins/kapt3/kapt3-cli/testData") {
testClass<AbstractArgumentParsingTest> {
model("argumentParsing", extension = "txt")
}
testClass<AbstractKaptToolIntegrationTest> {
model("integration", recursive = false, extension = null)
}
}
testGroup("plugins/allopen/allopen-cli/test", "plugins/allopen/allopen-cli/testData") {
testClass<AbstractBytecodeListingTestForAllOpen> {
model("bytecodeListing", extension = "kt")
+5 -1
View File
@@ -5,11 +5,15 @@ plugins {
dependencies {
compile(project(":compiler:cli"))
testCompile(projectTests(":compiler:tests-common"))
testCompile(projectTests(":compiler"))
testCompile(commonDep("junit:junit"))
}
sourceSets {
"main" { projectDefault() }
"test" { }
"test" { projectDefault() }
}
testsJar {}
@@ -0,0 +1,32 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.kapt.cli.test
import junit.framework.TestCase
import org.jetbrains.kotlin.daemon.TestMessageCollector
import org.jetbrains.kotlin.kapt.cli.transformArgs
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners
import org.jetbrains.kotlin.test.KotlinTestUtils
import org.junit.runner.RunWith
import java.io.File
private val LINE_SEPARATOR: String = System.getProperty("line.separator")
@RunWith(JUnit3RunnerWithInners::class)
abstract class AbstractArgumentParsingTest : TestCase() {
fun doTest(filePath: String) {
val testFile = File(filePath)
val sections = Section.parse(testFile)
val before = sections.single { it.name == "before" }
val messageCollector = TestMessageCollector()
val transformedArgs = transformArgs(before.content.split(LINE_SEPARATOR), messageCollector, isTest = true)
val actualAfter = if (messageCollector.hasErrors()) messageCollector.toString() else transformedArgs.joinToString(LINE_SEPARATOR)
val actual = sections.replacingSection("after", actualAfter).render()
KotlinTestUtils.assertEqualsToFile(testFile, actual)
}
}
@@ -0,0 +1,122 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.kapt.cli.test
import com.intellij.openapi.util.SystemInfo
import org.jetbrains.kotlin.cli.common.arguments.readArgumentsFromArgFile
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners
import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.test.TestCaseWithTmpdir
import org.junit.runner.RunWith
import java.io.File
import java.util.concurrent.TimeUnit
@RunWith(JUnit3RunnerWithInners::class)
abstract class AbstractKaptToolIntegrationTest : TestCaseWithTmpdir() {
fun doTest(filePath: String) {
val testDir = File(filePath)
val testFile = File(testDir, "build.txt")
assert(testFile.isFile) { "build.txt doesn't exist" }
testDir.listFiles().forEach { it.copyRecursively(File(tmpdir, it.name)) }
doTestInTempDirectory(testFile, File(tmpdir, testFile.name))
}
private class GotResult(val actual: String): RuntimeException()
private fun doTestInTempDirectory(originalTestFile: File, testFile: File) {
val sections = Section.parse(testFile)
for (section in sections) {
try {
when (section.name) {
"mkdir" -> section.args.forEach { File(tmpdir, it).mkdirs() }
"copy" -> copyFile(originalTestFile.parentFile, section.args)
"kotlinc" -> runKotlinDistBinary("kotlinc", section.args)
"kapt" -> runKotlinDistBinary("kapt", section.args)
"javac" -> runJavac(section.args)
"java" -> runJava(section.args)
"after" -> {}
else -> error("Unknown section name ${section.name}")
}
} catch (e: GotResult) {
val actual = sections.replacingSection("after", e.actual).render()
KotlinTestUtils.assertEqualsToFile(originalTestFile, actual)
return
} catch (e: Throwable) {
throw RuntimeException("Section ${section.name} failed:\n${section.content}", e)
}
}
}
private fun copyFile(testDir: File, args: List<String>) {
assert(args.size == 2)
val source = File(testDir, args[0])
val target = File(tmpdir, args[1]).also { it.parentFile.mkdirs() }
source.copyRecursively(target)
}
private fun runKotlinDistBinary(name: String, args: List<String>) {
val executableName = if (SystemInfo.isWindows) name + ".bat" else name
val executablePath = File("dist/kotlinc/bin/" + executableName).absolutePath
runProcess(executablePath, args)
}
private fun runJavac(args: List<String>) {
val executableName = if (SystemInfo.isWindows) "javac.exe" else "javac"
val executablePath = File(getJdk8Home(), "bin/" + executableName).absolutePath
runProcess(executablePath, args)
}
private fun runJava(args: List<String>) {
val outputFile = File(tmpdir, "javaOutput.txt")
val executableName = if (SystemInfo.isWindows) "java.exe" else "java"
val executablePath = File(getJdk8Home(), "bin/" + executableName).absolutePath
runProcess(executablePath, args, outputFile)
throw GotResult(outputFile.takeIf { it.isFile }?.readText() ?: "")
}
private fun runProcess(executablePath: String, args: List<String>, outputFile: File = File(tmpdir, "processOutput.txt")) {
fun err(message: String): Nothing = error("$message: $name (${args.joinToString(" ")})")
outputFile.delete()
val transformedArgs = transformArguments(args).toTypedArray()
val process = ProcessBuilder(executablePath, *transformedArgs).directory(tmpdir)
.inheritIO()
.redirectError(ProcessBuilder.Redirect.to(outputFile))
.redirectOutput(ProcessBuilder.Redirect.to(outputFile))
.start()
if (!process.waitFor(2, TimeUnit.MINUTES)) err("Process is still alive")
if (process.exitValue() != 0) {
throw GotResult(buildString {
append("Return code: ").appendln(process.exitValue()).appendln()
appendln(outputFile.readText())
})
}
}
private fun transformArguments(args: List<String>): List<String> {
return args.map { it.replace("%KOTLIN_STDLIB%", File("dist/kotlinc/lib/kotlin-stdlib.jar").absolutePath) }
}
private fun getJdk8Home(): File {
val homePath = System.getenv()["JDK_18"] ?: error("Can't find JDK 1.8 home")
return File(homePath)
}
}
private val Section.args get() = readArgumentsFromArgFile(preprocessPathSeparators(content))
private fun preprocessPathSeparators(text: String): String = buildString {
for (line in text.lineSequence()) {
val transformed = if (line.startsWith("-cp ")) line.replace(':', File.pathSeparatorChar) else line
appendln(transformed)
}
}
@@ -0,0 +1,56 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.kapt.cli.test;
import com.intellij.testFramework.TestDataPath;
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
import org.jetbrains.kotlin.test.KotlinTestUtils;
import org.jetbrains.kotlin.test.TargetBackend;
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/kapt3-cli/testData/argumentParsing")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public class ArgumentParsingTestGenerated extends AbstractArgumentParsingTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
}
public void testAllFilesPresentInArgumentParsing() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("plugins/kapt3/kapt3-cli/testData/argumentParsing"), Pattern.compile("^(.+)\\.txt$"), TargetBackend.ANY, true);
}
@TestMetadata("errorFlag.txt")
public void testErrorFlag() throws Exception {
runTest("plugins/kapt3/kapt3-cli/testData/argumentParsing/errorFlag.txt");
}
@TestMetadata("errorKeyValue.txt")
public void testErrorKeyValue() throws Exception {
runTest("plugins/kapt3/kapt3-cli/testData/argumentParsing/errorKeyValue.txt");
}
@TestMetadata("errorValue.txt")
public void testErrorValue() throws Exception {
runTest("plugins/kapt3/kapt3-cli/testData/argumentParsing/errorValue.txt");
}
@TestMetadata("kotlincHelp.txt")
public void testKotlincHelp() throws Exception {
runTest("plugins/kapt3/kapt3-cli/testData/argumentParsing/kotlincHelp.txt");
}
@TestMetadata("simple.txt")
public void testSimple() throws Exception {
runTest("plugins/kapt3/kapt3-cli/testData/argumentParsing/simple.txt");
}
}
@@ -0,0 +1,61 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.kapt.cli.test;
import com.intellij.testFramework.TestDataPath;
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
import org.jetbrains.kotlin.test.KotlinTestUtils;
import org.jetbrains.kotlin.test.TargetBackend;
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/kapt3-cli/testData/integration")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public class KaptToolIntegrationTestGenerated extends AbstractKaptToolIntegrationTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
}
public void testAllFilesPresentInIntegration() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("plugins/kapt3/kapt3-cli/testData/integration"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, false);
}
@TestMetadata("argfile")
public void testArgfile() throws Exception {
runTest("plugins/kapt3/kapt3-cli/testData/integration/argfile/");
}
@TestMetadata("correctErrorTypesOff")
public void testCorrectErrorTypesOff() throws Exception {
runTest("plugins/kapt3/kapt3-cli/testData/integration/correctErrorTypesOff/");
}
@TestMetadata("correctErrorTypesOn")
public void testCorrectErrorTypesOn() throws Exception {
runTest("plugins/kapt3/kapt3-cli/testData/integration/correctErrorTypesOn/");
}
@TestMetadata("separateStubAptCompilation")
public void testSeparateStubAptCompilation() throws Exception {
runTest("plugins/kapt3/kapt3-cli/testData/integration/separateStubAptCompilation/");
}
@TestMetadata("simple")
public void testSimple() throws Exception {
runTest("plugins/kapt3/kapt3-cli/testData/integration/simple/");
}
@TestMetadata("withoutService")
public void testWithoutService() throws Exception {
runTest("plugins/kapt3/kapt3-cli/testData/integration/withoutService/");
}
}
@@ -0,0 +1,68 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.kapt.cli.test
import org.jetbrains.kotlin.kapt.cli.test.Section.Companion.SECTION_INDICATOR
import java.io.File
class Section(val name: String, val content: String) {
companion object {
const val SECTION_INDICATOR = "# "
fun parse(file: File): List<Section> {
val sections = mutableListOf<Section>()
var currentName = ""
val currentContent = StringBuilder()
fun saveCurrent() {
if (currentName.isNotEmpty()) {
sections += Section(currentName.trim(), currentContent.toString().trim())
}
currentName = ""
currentContent.clear()
}
file.forEachLine { line ->
if (line.startsWith(SECTION_INDICATOR)) {
assert(line.length > 2)
saveCurrent()
currentName = line.drop(2)
} else {
currentContent.appendln(line)
}
}
saveCurrent()
return sections
}
}
}
fun List<Section>.render(): String = buildString {
for (section in this@render) {
append(SECTION_INDICATOR).appendln(section.name)
appendln(section.content).appendln()
}
}.trim()
fun List<Section>.replacingSection(name: String, newContent: String): List<Section> {
val result = mutableListOf<Section>()
var found = false
for (section in this) {
result += if (section.name == name) {
found = true
Section(name, newContent)
} else {
section
}
}
assert(found) { "Section $name not found" }
return result
}
@@ -0,0 +1,5 @@
# before
-Kapt-verbose=blah
# after
ERROR: Invalid option format, should be -Kapt-verbose=true/false
@@ -0,0 +1,7 @@
# before
-Kapt-option=a:b
# after
-P
plugin:org.jetbrains.kotlin.kapt3:aptMode=compile
-Kapt-option=a:b
@@ -0,0 +1,9 @@
# before
-Kapt-sources
blah
# after
-P
plugin:org.jetbrains.kotlin.kapt3:aptMode=compile
-Kapt-sources
blah
@@ -0,0 +1,7 @@
# before
-help-kotlinc
# after
-P
plugin:org.jetbrains.kotlin.kapt3:aptMode=compile
-help-kotlinc
@@ -0,0 +1,42 @@
# before
-Kapt-sources=output/sources
-Kapt-classes=output/classes
-Kapt-stubs=output/stubs
-Kapt-classpath=out/production/apt
-Kapt-processors=test.Foo
-Kapt-option:foo=true
-Kapt-option:bar=abc
-Kapt-javac-option:-Xmaxerrs=500
-Kapt-verbose=true
-Kapt-use-light-analysis=false
-Kapt-correct-error-types=true
-Kapt-map-diagnostic-locations=false
-Kapt-mode=apt
# after
-P
plugin:org.jetbrains.kotlin.kapt3:sources=output/sources
-P
plugin:org.jetbrains.kotlin.kapt3:classes=output/classes
-P
plugin:org.jetbrains.kotlin.kapt3:stubs=output/stubs
-P
plugin:org.jetbrains.kotlin.kapt3:apclasspath=out/production/apt
-P
plugin:org.jetbrains.kotlin.kapt3:processors=test.Foo
-P
plugin:org.jetbrains.kotlin.kapt3:apOption=foo=true
-P
plugin:org.jetbrains.kotlin.kapt3:apOption=bar=abc
-P
plugin:org.jetbrains.kotlin.kapt3:javacOption=-Xmaxerrs=500
-P
plugin:org.jetbrains.kotlin.kapt3:verbose=true
-P
plugin:org.jetbrains.kotlin.kapt3:useLightAnalysis=false
-P
plugin:org.jetbrains.kotlin.kapt3:correctErrorTypes=true
-P
plugin:org.jetbrains.kotlin.kapt3:mapDiagnosticLocations=false
-P
plugin:org.jetbrains.kotlin.kapt3:aptMode=apt
@@ -0,0 +1,3 @@
-cp %KOTLIN_STDLIB%
-d output/ap
ap/Processor.kt
@@ -0,0 +1,30 @@
# copy
../simple/ap
ap
# copy
../simple/Test.kt
Test.kt
# mkdir
output/ap
output/stubs
output/classes
output/javaClasses
output/sources
# kotlinc
@apKotlincArgs.txt
# kapt
@kaptArgs.txt
# javac
@javacArgs.txt
# java
-cp output/classes:output/javaClasses:output/ap:%KOTLIN_STDLIB%
test.TestKt
# after
Generated class: generated.Test
@@ -0,0 +1,6 @@
-cp output/ap
-d output/javaClasses
-proc:none
output/sources/generated/Function.java
output/sources/generated/Property.java
output/sources/generated/Test.java
@@ -0,0 +1,8 @@
-Kapt-stubs=output/stubs
-Kapt-classes=output/classes
-Kapt-sources=output/sources
-Kapt-classpath=output/ap
-Kapt-processors=apt.SampleApt
-d output/classes
-cp output/ap:%KOTLIN_STDLIB%
Test.kt
@@ -0,0 +1,50 @@
# copy
../correctErrorTypesOn/ap
ap
# copy
../correctErrorTypesOn/Test.kt
Test.kt
# mkdir
output/ap
output/stubs
output/classes
output/javaClasses
output/sources
# kotlinc
-cp %KOTLIN_STDLIB%
-d output/ap
ap/Processor.kt
# kapt
-Kapt-stubs=output/stubs
-Kapt-classes=output/classes
-Kapt-sources=output/sources
-Kapt-classpath=output/ap
-Kapt-processors=apt.SampleApt
-d output/classes
-cp output/ap:%KOTLIN_STDLIB%
Test.kt
# javac
-cp output/ap
-d output/javaClasses
-proc:none
output/sources/generated/Property.java
# java
-cp output/classes:output/javaClasses:output/ap:%KOTLIN_STDLIB%
test.Test
# after
Return code: 1
error: error: NonExistentClass type occurred
Test.kt:4:8: error: unresolved reference: generated
import generated.Property
^
Test.kt:8:28: error: unresolved reference: Property
lateinit var property: Property
^
@@ -0,0 +1,14 @@
package test
import apt.Anno
import generated.Property
object Test {
@field:Anno
lateinit var property: Property
@JvmStatic
fun main(args: Array<String>) {
print(javaClass.getDeclaredField("property").type.toGenericString())
}
}
@@ -0,0 +1,31 @@
package apt
import javax.annotation.processing.*
import javax.lang.model.SourceVersion
import javax.lang.model.element.*
import javax.lang.model.type.DeclaredType
import javax.tools.Diagnostic.Kind.*
annotation class Anno
class SampleApt : AbstractProcessor() {
override fun process(annotations: Set<TypeElement>, roundEnv: RoundEnvironment): Boolean {
for (element in roundEnv.getElementsAnnotatedWith(Anno::class.java).filterIsInstance<VariableElement>()) {
val type = element.asType() as? DeclaredType ?: continue
if (type.toString() == "error.NonExistentClass") {
processingEnv.messager.printMessage(ERROR, "NonExistentClass type occurred")
}
val generatedSimpleName = element.simpleName.toString().capitalize()
processingEnv.filer.createSourceFile("generated.$generatedSimpleName").openWriter().use {
it.write("package generated;\npublic class $generatedSimpleName {}")
}
}
return true
}
override fun getSupportedOptions() = emptySet<String>()
override fun getSupportedSourceVersion() = SourceVersion.RELEASE_8
override fun getSupportedAnnotationTypes() = setOf("apt.Anno")
}
@@ -0,0 +1,35 @@
# mkdir
output/ap
output/stubs
output/classes
output/javaClasses
output/sources
# kotlinc
-cp %KOTLIN_STDLIB%
-d output/ap
ap/Processor.kt
# kapt
-Kapt-stubs=output/stubs
-Kapt-classes=output/classes
-Kapt-sources=output/sources
-Kapt-classpath=output/ap
-Kapt-processors=apt.SampleApt
-Kapt-correct-error-types=true
-d output/classes
-cp output/ap:%KOTLIN_STDLIB%
Test.kt
# javac
-cp output/ap
-d output/javaClasses
-proc:none
output/sources/generated/Property.java
# java
-cp output/classes:output/javaClasses:output/ap:%KOTLIN_STDLIB%
test.Test
# after
public class generated.Property
@@ -0,0 +1,61 @@
# copy
../simple/ap
ap
# copy
../simple/Test.kt
Test.kt
# mkdir
output/ap
output/stubs
output/classes
output/javaClasses
output/sources
# kotlinc
-cp %KOTLIN_STDLIB%
-d output/ap
ap/Processor.kt
# kapt
-Kapt-stubs=output/stubs
-Kapt-classes=output/classes
-Kapt-sources=output/sources
-Kapt-classpath=output/ap
-Kapt-mode=stubs
-d output/classes
-cp output/ap:%KOTLIN_STDLIB%
Test.kt
# kapt
-Kapt-stubs=output/stubs
-Kapt-classes=output/classes
-Kapt-sources=output/sources
-Kapt-classpath=output/ap
-Kapt-mode=apt
-Kapt-processors=apt.SampleApt
-d output/classes
-cp output/ap:%KOTLIN_STDLIB%
Test.kt
# kotlinc
-d output/classes
-cp output/ap:%KOTLIN_STDLIB%
output/sources
Test.kt
# javac
-cp output/ap
-d output/javaClasses
-proc:none
output/sources/generated/Function.java
output/sources/generated/Property.java
output/sources/generated/Test.java
# java
-cp output/classes:output/javaClasses:output/ap:%KOTLIN_STDLIB%
test.TestKt
# after
Generated class: generated.Test
@@ -0,0 +1,19 @@
package test
import apt.Anno
import generated.Test as TestGenerated
@Anno
class Test {
@field:Anno
val property: String = ""
@Anno
fun function() {
}
}
fun main() {
println("Generated class: " + TestGenerated::class.java.name)
}
@@ -0,0 +1,25 @@
package apt
import javax.annotation.processing.*
import javax.lang.model.SourceVersion
import javax.lang.model.element.TypeElement
import javax.tools.Diagnostic.Kind.*
annotation class Anno
class SampleApt : AbstractProcessor() {
override fun process(annotations: Set<TypeElement>, roundEnv: RoundEnvironment): Boolean {
for (element in roundEnv.getElementsAnnotatedWith(Anno::class.java)) {
val generatedSimpleName = element.simpleName.toString().capitalize()
processingEnv.filer.createSourceFile("generated.$generatedSimpleName").openWriter().use {
it.write("package generated;\npublic class $generatedSimpleName {}")
}
}
return true
}
override fun getSupportedOptions() = emptySet<String>()
override fun getSupportedSourceVersion() = SourceVersion.RELEASE_8
override fun getSupportedAnnotationTypes() = setOf("apt.Anno")
}
@@ -0,0 +1,39 @@
# mkdir
output/ap
output/stubs
output/classes
output/javaClasses
output/sources
# kotlinc
-cp %KOTLIN_STDLIB%
-d output/ap
ap/Processor.kt
# copy
ap/META-INF/services/javax.annotation.processing.Processor
output/ap/META-INF/services/javax.annotation.processing.Processor
# kapt
-Kapt-stubs=output/stubs
-Kapt-classes=output/classes
-Kapt-sources=output/sources
-Kapt-classpath=output/ap
-d output/classes
-cp output/ap:%KOTLIN_STDLIB%
Test.kt
# javac
-cp output/ap
-d output/javaClasses
-proc:none
output/sources/generated/Function.java
output/sources/generated/Property.java
output/sources/generated/Test.java
# java
-cp output/classes:output/javaClasses:output/ap:%KOTLIN_STDLIB%
test.TestKt
# after
Generated class: generated.Test
@@ -0,0 +1,44 @@
# copy
../simple/ap
ap
# copy
../simple/Test.kt
Test.kt
# mkdir
output/ap
output/stubs
output/classes
output/javaClasses
output/sources
# kotlinc
-cp %KOTLIN_STDLIB%
-d output/ap
ap/Processor.kt
# kapt
-Kapt-stubs=output/stubs
-Kapt-classes=output/classes
-Kapt-sources=output/sources
-Kapt-classpath=output/ap
-Kapt-processors=apt.SampleApt
-d output/classes
-cp output/ap:%KOTLIN_STDLIB%
Test.kt
# javac
-cp output/ap
-d output/javaClasses
-proc:none
output/sources/generated/Function.java
output/sources/generated/Property.java
output/sources/generated/Test.java
# java
-cp output/classes:output/javaClasses:output/ap:%KOTLIN_STDLIB%
test.TestKt
# after
Generated class: generated.Test