Skip to content

Commit 66feb61

Browse files
committed
Test that java annotation processors are run
1 parent ca5d26b commit 66feb61

File tree

7 files changed

+170
-58
lines changed

7 files changed

+170
-58
lines changed

build.gradle

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ buildscript {
1414
plugins {
1515
id 'java'
1616
id 'org.jetbrains.kotlin.jvm' version '1.3.11'
17-
1817
}
1918

2019
apply plugin: 'kotlin'
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import com.squareup.kotlinpoet.FileSpec;
2+
import com.squareup.kotlinpoet.FunSpec;
3+
import com.squareup.kotlinpoet.TypeSpec;
4+
import kotlin.text.Charsets;
5+
6+
import javax.annotation.processing.AbstractProcessor;
7+
import javax.annotation.processing.ProcessingEnvironment;
8+
import javax.annotation.processing.RoundEnvironment;
9+
import javax.lang.model.SourceVersion;
10+
import javax.lang.model.element.Element;
11+
import javax.lang.model.element.TypeElement;
12+
import javax.tools.Diagnostic;
13+
import java.io.File;
14+
import java.io.FileOutputStream;
15+
import java.util.LinkedHashSet;
16+
import java.util.Set;
17+
18+
public class JavaTestProcessor extends AbstractProcessor {
19+
20+
@Override
21+
public SourceVersion getSupportedSourceVersion() {
22+
return SourceVersion.latestSupported();
23+
}
24+
25+
@Override
26+
public Set<String> getSupportedAnnotationTypes() {
27+
LinkedHashSet<String> set = new LinkedHashSet<>();
28+
set.add(Marker.class.getCanonicalName());
29+
return set;
30+
}
31+
32+
@Override
33+
public Set<String> getSupportedOptions() {
34+
LinkedHashSet<String> set = new LinkedHashSet<>();
35+
set.add("kapt.kotlin.generated");
36+
return set;
37+
}
38+
39+
@Override
40+
public synchronized void init(ProcessingEnvironment processingEnv) {
41+
super.init(processingEnv);
42+
processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING, "java processor init");
43+
}
44+
45+
@Override
46+
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
47+
processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING, "java processor was called");
48+
49+
if(!annotations.isEmpty()) {
50+
TypeSpec.Builder typeSpecBuilder = TypeSpec.classBuilder("JavaGeneratedKotlinClass");
51+
52+
for(Element annotatedElement : roundEnv.getElementsAnnotatedWith(Marker.class)) {
53+
typeSpecBuilder.addFunction(FunSpec.builder(annotatedElement.getSimpleName().toString()
54+
).build()
55+
).build();
56+
}
57+
58+
FileSpec fileSpec = FileSpec.builder("", "JavaGeneratedKotlinClass.kt")
59+
.addType(typeSpecBuilder.build())
60+
.build();
61+
62+
writeKotlinFile(fileSpec, fileSpec.getName(), fileSpec.getPackageName());
63+
}
64+
65+
return false;
66+
}
67+
68+
private void writeKotlinFile(FileSpec fileSpec, String fileName, String packageName) {
69+
String kaptKotlinGeneratedDir = processingEnv.getOptions().get("kapt.kotlin.generated");
70+
71+
String relativePath = packageName.replace('.', File.separatorChar);
72+
73+
File outputFolder = new File(kaptKotlinGeneratedDir, relativePath);
74+
outputFolder.mkdirs();
75+
76+
// finally write to output file
77+
try {
78+
(new FileOutputStream(new File(outputFolder, fileName))).write(fileSpec.toString().getBytes(Charsets.UTF_8));
79+
}
80+
catch(Exception e) {
81+
82+
}
83+
}
84+
}

src/test/kotlin/JavacUtils.kt

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
1-
package com.tschuchort.compiletest
2-
3-
import org.jetbrains.kotlin.incremental.isJavaFile
41
import java.io.*
52
import java.net.URI
6-
import java.net.URL
73
import java.nio.charset.Charset
84
import javax.tools.JavaCompiler
95
import javax.tools.JavaFileObject

src/test/kotlin/KotlinCompilation.kt

Lines changed: 38 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16-
package com.tschuchort.compiletest
1716

17+
import com.tschuchort.compiletest.NullStream
18+
import com.tschuchort.compiletest.TeeOutputStream
1819
import io.github.classgraph.ClassGraph
1920
import okio.Buffer
2021
import okio.buffer
@@ -65,39 +66,39 @@ open class KotlinCompilation(
6566
* process' classpaths
6667
*/
6768
val kotlinStdLibJar: File? = findKtStdLib(
68-
log = { if(verbose) systemOut.log(it) }
69+
log = { if (verbose) systemOut.log(it) }
6970
),
7071
/**
7172
* Path to the kotlin-stdlib-jdk*.jar
7273
* If none is given, it will be searched for in the host
7374
* process' classpaths
7475
*/
7576
val kotlinStdLibJdkJar: File? = findKtStdLibJdk(
76-
log = { if(verbose) systemOut.log(it) }
77+
log = { if (verbose) systemOut.log(it) }
7778
),
7879
/**
7980
* Path to the kotlin-reflect.jar
8081
* If none is given, it will be searched for in the host
8182
* process' classpaths
8283
*/
8384
val kotlinReflectJar: File? = findKtReflect(
84-
log = { if(verbose) systemOut.log(it) }
85+
log = { if (verbose) systemOut.log(it) }
8586
),
8687
/**
8788
* Path to the kotlin-script-runtime.jar
8889
* If none is given, it will be searched for in the host
8990
* process' classpaths
9091
*/
9192
val kotlinScriptRuntimeJar: File? = findKtScriptRt(
92-
log = { if(verbose) systemOut.log(it) }
93+
log = { if (verbose) systemOut.log(it) }
9394
),
9495
/**
9596
* Path to the kotlin-stdlib-common.jar
9697
* If none is given, it will be searched for in the host
9798
* process' classpaths
9899
*/
99100
val kotlinStdLibCommonJar: File? = findKtStdLibCommon(
100-
log = { if(verbose) systemOut.log(it) }
101+
log = { if (verbose) systemOut.log(it) }
101102
),
102103
/**
103104
* Path to the tools.jar file needed for kapt when using a JDK 8.
@@ -106,17 +107,17 @@ open class KotlinCompilation(
106107
* internal compiler error!
107108
*/
108109
val toolsJar: File? = findToolsInHostClasspath(
109-
log = { if(verbose) systemOut.log(it) }
110-
),
110+
log = { if (verbose) systemOut.log(it) }
111+
),
111112
/**
112113
* Path to the kotlin-annotation-processing-embeddable*.jar that
113114
* contains kapt3.
114115
*
115116
* Only needed when [services] is not empty.
116117
*/
117118
val kapt3Jar: File? = findKapt3(
118-
log = { if(verbose) systemOut.log(it) }
119-
),
119+
log = { if (verbose) systemOut.log(it) }
120+
),
120121
/** Inherit classpath from calling process */
121122
val inheritClassPath: Boolean = false,
122123
val jvmTarget: String? = null,
@@ -272,6 +273,7 @@ open class KotlinCompilation(
272273
// Don't forget aptMode! Without it, the compiler will crash with an obscure error about
273274
// write unsafe context
274275
"plugin:org.jetbrains.kotlin.kapt3:aptMode=stubsAndApt",
276+
"plugin:org.jetbrains.kotlin.kapt3:mapDiagnosticLocations=true",
275277
*if (verbose)
276278
arrayOf("plugin:org.jetbrains.kotlin.kapt3:verbose=true")
277279
else
@@ -370,7 +372,8 @@ open class KotlinCompilation(
370372
val compilerSystemOutBuffer = Buffer() // Buffer for capturing compiler's logging output
371373
val compilerMessageCollector = PrintingMessageCollector(
372374
PrintStream(
373-
TeeOutputStream(systemOut, compilerSystemOutBuffer.outputStream())),
375+
TeeOutputStream(systemOut, compilerSystemOutBuffer.outputStream())
376+
),
374377
MessageRenderer.WITHOUT_PATHS, true)
375378

376379
/*
@@ -462,34 +465,46 @@ open class KotlinCompilation(
462465

463466
/** Tries to find the kotlin-stdlib.jar in the host process' classpath */
464467
fun findKtStdLib(log: ((String) -> Unit)? = null)
465-
= findInHostClasspath("kotlin-stdlib.jar",
466-
Regex("(kotlin-stdlib|kotlin-runtime)(-[0-9]+\\.[0-9]+\\.[0-9]+)\\.jar"), log)
468+
= findInHostClasspath(
469+
"kotlin-stdlib.jar",
470+
Regex("(kotlin-stdlib|kotlin-runtime)(-[0-9]+\\.[0-9]+\\.[0-9]+)\\.jar"), log
471+
)
467472
// kotlin-stdlib.jar used to be kotlin-runtime.jar in <1.1
468473

469474
/** Tries to find the kotlin-stdlib-jdk*.jar in the host process' classpath */
470475
fun findKtStdLibJdk(log: ((String) -> Unit)? = null)
471-
= findInHostClasspath("kotlin-stdlib-jdk*.jar",
472-
Regex("kotlin-stdlib-jdk[0-9]+(-[0-9]+\\.[0-9]+\\.[0-9]+)\\.jar"), log)
476+
= findInHostClasspath(
477+
"kotlin-stdlib-jdk*.jar",
478+
Regex("kotlin-stdlib-jdk[0-9]+(-[0-9]+\\.[0-9]+\\.[0-9]+)\\.jar"), log
479+
)
473480

474481
/** Tries to find the kotlin-stdlib-common.jar in the host process' classpath */
475482
fun findKtStdLibCommon(log: ((String) -> Unit)? = null)
476-
= findInHostClasspath("kotlin-stdlib-common.jar",
477-
Regex("kotlin-stdlib-common(-[0-9]+\\.[0-9]+\\.[0-9]+)\\.jar"), log)
483+
= findInHostClasspath(
484+
"kotlin-stdlib-common.jar",
485+
Regex("kotlin-stdlib-common(-[0-9]+\\.[0-9]+\\.[0-9]+)\\.jar"), log
486+
)
478487

479488
/** Tries to find the kotlin-reflect.jar in the host process' classpath */
480489
fun findKtReflect(log: ((String) -> Unit)? = null)
481-
= findInHostClasspath("kotlin-reflect.jar",
482-
Regex("kotlin-reflect(-[0-9]+\\.[0-9]+\\.[0-9]+)\\.jar"), log)
490+
= findInHostClasspath(
491+
"kotlin-reflect.jar",
492+
Regex("kotlin-reflect(-[0-9]+\\.[0-9]+\\.[0-9]+)\\.jar"), log
493+
)
483494

484495
/** Tries to find the kotlin-script-runtime.jar in the host process' classpath */
485496
fun findKtScriptRt(log: ((String) -> Unit)? = null)
486-
= findInHostClasspath("kotlin-script-runtime.jar",
487-
Regex("kotlin-script-runtime(-[0-9]+\\.[0-9]+\\.[0-9]+)\\.jar"), log)
497+
= findInHostClasspath(
498+
"kotlin-script-runtime.jar",
499+
Regex("kotlin-script-runtime(-[0-9]+\\.[0-9]+\\.[0-9]+)\\.jar"), log
500+
)
488501

489502
/** Tries to find the kapt 3 jar in the host process' classpath */
490503
fun findKapt3(log: ((String) -> Unit)? = null)
491-
= findInHostClasspath("kotlin-annotation-processing(-embeddable).jar",
492-
Regex("kotlin-annotation-processing(-(embeddable|gradle|maven))?(-[0-9]+\\.[0-9]+\\.[0-9]+)?\\.jar"), log)
504+
= findInHostClasspath(
505+
"kotlin-annotation-processing(-embeddable).jar",
506+
Regex("kotlin-annotation-processing(-(embeddable|gradle|maven))?(-[0-9]+\\.[0-9]+\\.[0-9]+)?\\.jar"), log
507+
)
493508

494509

495510
/** Tries to find the tools.jar needed for kapt in the host process' classpath */

src/test/kotlin/KotlinTestProcessor.kt

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
package com.tschuchort.compiletest
2-
31
import com.squareup.kotlinpoet.FileSpec
42
import com.squareup.kotlinpoet.FunSpec
53
import com.squareup.kotlinpoet.TypeSpec
@@ -11,7 +9,7 @@ import javax.tools.Diagnostic
119

1210
annotation class Marker
1311

14-
class TestProcessor : AbstractProcessor() {
12+
class KotlinTestProcessor : AbstractProcessor() {
1513
companion object {
1614
const val KAPT_KOTLIN_GENERATED_OPTION_NAME = "kapt.kotlin.generated"
1715
const val GENERATE_KOTLIN_CODE_OPTION = "generate.kotlin.code"
@@ -25,7 +23,11 @@ class TestProcessor : AbstractProcessor() {
2523
private val generatedFilesSuffix by lazy { processingEnv.options[FILE_SUFFIX_OPTION] ?: "Generated"}
2624

2725
override fun getSupportedSourceVersion(): SourceVersion = SourceVersion.latest()
28-
override fun getSupportedOptions() = setOf(KAPT_KOTLIN_GENERATED_OPTION_NAME, GENERATE_KOTLIN_CODE_OPTION, GENERATE_ERRORS_OPTION)
26+
override fun getSupportedOptions() = setOf(
27+
KAPT_KOTLIN_GENERATED_OPTION_NAME,
28+
GENERATE_KOTLIN_CODE_OPTION,
29+
GENERATE_ERRORS_OPTION
30+
)
2931
override fun getSupportedAnnotationTypes(): Set<String> = setOf(Marker::class.java.canonicalName)
3032

3133
override fun init(processingEnv: ProcessingEnvironment) {
@@ -34,20 +36,21 @@ class TestProcessor : AbstractProcessor() {
3436
}
3537

3638
override fun process(annotations: Set<TypeElement>, roundEnv: RoundEnvironment): Boolean {
37-
for(annotatedElem in roundEnv.getElementsAnnotatedWith(Marker::class.java)) {
38-
val fileSpec = FileSpec.builder("com.tschuchort.compiletest", "GeneratedClass.kt")
39-
.addType(TypeSpec.classBuilder("GeneratedClass")
40-
.addFunction(FunSpec.builder(annotatedElem.simpleName.toString())
41-
.build()
42-
).build()
43-
).build()
39+
processingEnv.messager.printMessage(Diagnostic.Kind.WARNING, "kotlin processor was called")
4440

45-
writeKotlinFile(fileSpec)
46-
}
47-
48-
processingEnv.messager.printMessage(Diagnostic.Kind.WARNING, "kotlin processor was called")
41+
if(annotations.isNotEmpty())
42+
FileSpec.builder("", "KotlinGeneratedKotlinClass.kt")
43+
.addType(TypeSpec.classBuilder("KotlinGeneratedKotlinClass").apply {
44+
for(annotatedElem in roundEnv.getElementsAnnotatedWith(Marker::class.java)) {
45+
addFunction(FunSpec.builder(annotatedElem.simpleName.toString())
46+
.build()
47+
)
48+
}
49+
}.build()
50+
).build()
51+
.let { writeKotlinFile(it) }
4952

50-
return true
53+
return false
5154
}
5255

5356
private fun writeKotlinFile(fileSpec: FileSpec, fileName: String = fileSpec.name, packageName: String = fileSpec.packageName) {

src/test/kotlin/SmokeTests.kt

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
package com.tschuchort.compiletest
2-
31
import okio.Buffer
42
import org.assertj.core.api.Assertions.assertThat
53
import org.jetbrains.kotlin.cli.common.ExitCode
@@ -15,11 +13,13 @@ class SmokeTests {
1513

1614
@Test
1715
fun `compilation succeeds`() {
18-
val kSource = KotlinCompilation.SourceFile("kSource.kt",
19-
"""import com.tschuchort.compiletest.Marker
16+
val kSource = KotlinCompilation.SourceFile(
17+
"kSource.kt",
18+
"""//import Marker
2019
import javax.lang.model.SourceVersion
2120
import java.io.File
22-
import com.tschuchort.compiletest.GeneratedClass
21+
//import com.tschuchort.compiletest.KotlinGeneratedKotlinClass
22+
//import com.tschuchort.compiletest.JavaGeneratedKotlinClass
2323
2424
class KotClass {
2525
fun brr() {}
@@ -33,27 +33,44 @@ class SmokeTests {
3333
fun main(freeArgs: Array<String>) {
3434
File("")
3535
println("hello")
36-
GeneratedClass().foo()
36+
KotlinGeneratedKotlinClass().foo()
37+
KotlinGeneratedKotlinClass().bar()
38+
JavaGeneratedKotlinClass().foo()
39+
JavaGeneratedKotlinClass().bar()
3740
}
3841
""".trimIndent()
3942
)
4043

41-
val jSource = KotlinCompilation.SourceFile("JSource.java",
42-
"""
43-
import com.tschuchort.compiletest.Marker;
44+
val jSource = KotlinCompilation.SourceFile(
45+
"JSource.java",
46+
"""
47+
//import com.tschuchort.compiletest.KotlinGeneratedKotlinClass;
48+
//import com.tschuchort.compiletest.JavaGeneratedKotlinClass;
49+
4450
public class JSource {
51+
public JSource() {
52+
(new KotlinGeneratedKotlinClass()).foo();
53+
(new KotlinGeneratedKotlinClass()).bar();
54+
(new JavaGeneratedKotlinClass()).foo();
55+
(new JavaGeneratedKotlinClass()).bar();
56+
}
57+
4558
@Marker public void bar() {
4659
(new KotClass()).brr();
4760
}
4861
}
49-
""".trimIndent())
62+
""".trimIndent()
63+
)
5064

5165
val systemOutBuffer = Buffer()
5266

5367
val result = KotlinCompilation(
5468
workingDir = File("C:\\compile-testing"),
5569
sources = listOf(kSource, jSource),
56-
services = listOf(KotlinCompilation.Service(Processor::class, TestProcessor::class)),
70+
services = listOf(
71+
KotlinCompilation.Service(Processor::class, KotlinTestProcessor::class),
72+
KotlinCompilation.Service(Processor::class, JavaTestProcessor::class)
73+
),
5774
jdkHome = File("D:\\Program Files\\Java\\jdk1.8.0_25"),//getJavaHome(),
5875
//toolsJar = File("D:\\Program Files\\Java\\jdk1.8.0_25\\lib\\tools.jar"),
5976
inheritClassPath = true,

0 commit comments

Comments
 (0)