From 1cbfacfe299be84b8216eb2bcb56b887558bd6dc Mon Sep 17 00:00:00 2001 From: Jiaxiang Chen Date: Mon, 10 Apr 2023 21:45:52 -0700 Subject: [PATCH] workaround for classpath snapshot issue --- .../devtools/ksp/gradle/KspSubplugin.kt | 5 +- .../com/google/devtools/ksp/test/KAPT3IT.kt | 49 +++ .../src/test/resources/kapt3/build.gradle.kts | 8 + .../test/resources/kapt3/gradle.properties | 2 + .../test/resources/kapt3/settings.gradle.kts | 19 ++ .../kapt3/test-processor/build.gradle.kts | 25 ++ .../test-processor/src/main/kotlin/Builder.kt | 3 + .../src/main/kotlin/BuilderProcessor.kt | 105 +++++++ .../src/main/kotlin/RewriteProcessor.kt | 31 ++ .../src/main/kotlin/TestProcessor.kt | 284 ++++++++++++++++++ ...ols.ksp.processing.SymbolProcessorProvider | 2 + .../resources/kapt3/workload/build.gradle.kts | 27 ++ .../workload/src/main/java/com/example/A.kt | 16 + .../src/main/java/com/example/AClass.kt | 17 ++ .../src/main/java/com/example/BClass.java | 14 + 15 files changed, 606 insertions(+), 1 deletion(-) create mode 100644 integration-tests/src/test/kotlin/com/google/devtools/ksp/test/KAPT3IT.kt create mode 100644 integration-tests/src/test/resources/kapt3/build.gradle.kts create mode 100644 integration-tests/src/test/resources/kapt3/gradle.properties create mode 100644 integration-tests/src/test/resources/kapt3/settings.gradle.kts create mode 100644 integration-tests/src/test/resources/kapt3/test-processor/build.gradle.kts create mode 100644 integration-tests/src/test/resources/kapt3/test-processor/src/main/kotlin/Builder.kt create mode 100644 integration-tests/src/test/resources/kapt3/test-processor/src/main/kotlin/BuilderProcessor.kt create mode 100644 integration-tests/src/test/resources/kapt3/test-processor/src/main/kotlin/RewriteProcessor.kt create mode 100644 integration-tests/src/test/resources/kapt3/test-processor/src/main/kotlin/TestProcessor.kt create mode 100644 integration-tests/src/test/resources/kapt3/test-processor/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider create mode 100644 integration-tests/src/test/resources/kapt3/workload/build.gradle.kts create mode 100644 integration-tests/src/test/resources/kapt3/workload/src/main/java/com/example/A.kt create mode 100644 integration-tests/src/test/resources/kapt3/workload/src/main/java/com/example/AClass.kt create mode 100644 integration-tests/src/test/resources/kapt3/workload/src/main/java/com/example/BClass.java diff --git a/gradle-plugin/src/main/kotlin/com/google/devtools/ksp/gradle/KspSubplugin.kt b/gradle-plugin/src/main/kotlin/com/google/devtools/ksp/gradle/KspSubplugin.kt index 4fe28cacaa..1ee68bc9f9 100644 --- a/gradle-plugin/src/main/kotlin/com/google/devtools/ksp/gradle/KspSubplugin.kt +++ b/gradle-plugin/src/main/kotlin/com/google/devtools/ksp/gradle/KspSubplugin.kt @@ -368,7 +368,10 @@ class KspGradleSubplugin @Inject internal constructor(private val registry: Tool kotlinCompileTask.project.files( Callable { kotlinCompileTask.libraries.filter { - !kspOutputDir.isParentOf(it) + // manually exclude KAPT generated class folder from class path snapshot. + // TODO: remove in 1.9.0. + + !kspOutputDir.isParentOf(it) && !(it.isDirectory && it.listFiles()?.isEmpty() == true) } } ) diff --git a/integration-tests/src/test/kotlin/com/google/devtools/ksp/test/KAPT3IT.kt b/integration-tests/src/test/kotlin/com/google/devtools/ksp/test/KAPT3IT.kt new file mode 100644 index 0000000000..78fe22f6ab --- /dev/null +++ b/integration-tests/src/test/kotlin/com/google/devtools/ksp/test/KAPT3IT.kt @@ -0,0 +1,49 @@ +package com.google.devtools.ksp.test + +import org.gradle.testkit.runner.BuildResult +import org.gradle.testkit.runner.GradleRunner +import org.gradle.testkit.runner.TaskOutcome +import org.junit.Assert +import org.junit.Rule +import org.junit.Test +import java.io.File +import java.util.jar.JarFile + +class KAPT3IT { + @Rule + @JvmField + val project: TemporaryTestProject = TemporaryTestProject("kapt3") + + private fun GradleRunner.buildAndCheck(vararg args: String, extraCheck: (BuildResult) -> Unit = {}) = + buildAndCheckOutcome(*args, outcome = TaskOutcome.SUCCESS, extraCheck = extraCheck) + + private fun GradleRunner.buildAndCheckOutcome( + vararg args: String, + outcome: TaskOutcome, + extraCheck: (BuildResult) -> Unit = {} + ) { + val result = this.withArguments(*args).build() + + Assert.assertEquals(outcome, result.task(":workload:build")?.outcome) + + val artifact = File(project.root, "workload/build/libs/workload-1.0-SNAPSHOT.jar") + Assert.assertTrue(artifact.exists()) + + JarFile(artifact).use { jarFile -> + Assert.assertTrue(jarFile.getEntry("TestProcessor.log").size > 0) + Assert.assertTrue(jarFile.getEntry("hello/HELLO.class").size > 0) + Assert.assertTrue(jarFile.getEntry("com/example/AClassBuilder.class").size > 0) + } + + extraCheck(result) + } + + @Test + fun testWithKAPT3() { + val gradleRunner = GradleRunner.create().withProjectDir(project.root) + gradleRunner.buildAndCheck("--build-cache", "build") + val Akt = File(project.root, "workload/src/main/java/com/example/A.kt") + Akt.appendText("class Void") + gradleRunner.buildAndCheck("--build-cache", "build") + } +} diff --git a/integration-tests/src/test/resources/kapt3/build.gradle.kts b/integration-tests/src/test/resources/kapt3/build.gradle.kts new file mode 100644 index 0000000000..c5737a2e0d --- /dev/null +++ b/integration-tests/src/test/resources/kapt3/build.gradle.kts @@ -0,0 +1,8 @@ +plugins { + kotlin("jvm") +} + +repositories { + mavenCentral() + maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/bootstrap/") +} diff --git a/integration-tests/src/test/resources/kapt3/gradle.properties b/integration-tests/src/test/resources/kapt3/gradle.properties new file mode 100644 index 0000000000..b21575eafc --- /dev/null +++ b/integration-tests/src/test/resources/kapt3/gradle.properties @@ -0,0 +1,2 @@ +org.gradle.jvmargs=-Xmx4096M -XX:MaxMetaspaceSize=1024m +org.gradle.unsafe.configuration-cache.max-problems=5000 \ No newline at end of file diff --git a/integration-tests/src/test/resources/kapt3/settings.gradle.kts b/integration-tests/src/test/resources/kapt3/settings.gradle.kts new file mode 100644 index 0000000000..fabec1cb31 --- /dev/null +++ b/integration-tests/src/test/resources/kapt3/settings.gradle.kts @@ -0,0 +1,19 @@ +pluginManagement { + val kotlinVersion: String by settings + val kspVersion: String by settings + val testRepo: String by settings + plugins { + id("com.google.devtools.ksp") version kspVersion + kotlin("jvm") version kotlinVersion + } + repositories { + maven(testRepo) + gradlePluginPortal() + maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/bootstrap/") + } +} + +rootProject.name = "kapt3" + +include(":workload") +include(":test-processor") diff --git a/integration-tests/src/test/resources/kapt3/test-processor/build.gradle.kts b/integration-tests/src/test/resources/kapt3/test-processor/build.gradle.kts new file mode 100644 index 0000000000..75c6c7c5ab --- /dev/null +++ b/integration-tests/src/test/resources/kapt3/test-processor/build.gradle.kts @@ -0,0 +1,25 @@ +val kspVersion: String by project +val testRepo: String by project + +plugins { + kotlin("jvm") +} + +group = "com.example" +version = "1.0-SNAPSHOT" + +repositories { + maven(testRepo) + mavenCentral() + maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/bootstrap/") +} + +dependencies { + implementation(kotlin("stdlib")) + implementation("com.squareup:javapoet:1.12.1") + implementation("com.google.devtools.ksp:symbol-processing-api:$kspVersion") +} + +sourceSets.main { + java.srcDirs("src/main/kotlin") +} diff --git a/integration-tests/src/test/resources/kapt3/test-processor/src/main/kotlin/Builder.kt b/integration-tests/src/test/resources/kapt3/test-processor/src/main/kotlin/Builder.kt new file mode 100644 index 0000000000..9434b3627d --- /dev/null +++ b/integration-tests/src/test/resources/kapt3/test-processor/src/main/kotlin/Builder.kt @@ -0,0 +1,3 @@ +package com.example.annotation + +annotation class Builder diff --git a/integration-tests/src/test/resources/kapt3/test-processor/src/main/kotlin/BuilderProcessor.kt b/integration-tests/src/test/resources/kapt3/test-processor/src/main/kotlin/BuilderProcessor.kt new file mode 100644 index 0000000000..6298a2e087 --- /dev/null +++ b/integration-tests/src/test/resources/kapt3/test-processor/src/main/kotlin/BuilderProcessor.kt @@ -0,0 +1,105 @@ + +import com.google.devtools.ksp.containingFile +import com.google.devtools.ksp.processing.* +import com.google.devtools.ksp.symbol.* +import com.google.devtools.ksp.validate +import java.io.OutputStream + +fun OutputStream.appendText(str: String) { + this.write(str.toByteArray()) +} + +class BuilderProcessor : SymbolProcessor { + lateinit var codeGenerator: CodeGenerator + lateinit var logger: KSPLogger + + fun init( + options: Map, + kotlinVersion: KotlinVersion, + codeGenerator: CodeGenerator, + logger: KSPLogger, + ) { + this.codeGenerator = codeGenerator + this.logger = logger + } + + override fun process(resolver: Resolver): List { + val symbols = resolver.getSymbolsWithAnnotation("com.example.annotation.Builder") + val ret = symbols.filter { !it.validate() } + symbols + .filter { it is KSClassDeclaration && it.validate() } + .forEach { it.accept(BuilderVisitor(), Unit) } + return ret.toList() + } + + inner class BuilderVisitor : KSVisitorVoid() { + override fun visitClassDeclaration(classDeclaration: KSClassDeclaration, data: Unit) { + classDeclaration.primaryConstructor?.accept(this, data) + } + + override fun visitFunctionDeclaration(function: KSFunctionDeclaration, data: Unit) { + val parent = function.parentDeclaration as KSClassDeclaration + val packageName = parent.containingFile!!.packageName.asString() + val className = "${parent.simpleName.asString()}Builder" + + // For regression testing https://github.com/google/ksp/pull/467 + codeGenerator.createNewFile( + Dependencies(true, function.containingFile!!), + "", + "META-INF/proguard/builder-$className", + "pro" + ).use { proguardFile -> + proguardFile.appendText("-keep class $packageName.$className { *; }") + } + + val file = codeGenerator.createNewFile( + Dependencies(true, function.containingFile!!), packageName, className + ) + file.appendText("package $packageName\n\n") + file.appendText("import hello.HELLO\n\n") + file.appendText("class $className{\n") + function.parameters.forEach { + val name = it.name!!.asString() + val typeName = StringBuilder(it.type.resolve().declaration.qualifiedName?.asString() ?: "") + val typeArgs = it.type.element!!.typeArguments + if (it.type.element!!.typeArguments.toList().isNotEmpty()) { + typeName.append("<") + typeName.append( + typeArgs.map { + val type = it.type?.resolve() + "${it.variance.label} ${type?.declaration?.qualifiedName?.asString() ?: "ERROR"}" + + if (type?.nullability == Nullability.NULLABLE) "?" else "" + }.joinToString(", ") + ) + typeName.append(">") + } + file.appendText(" private var $name: $typeName? = null\n") + file.appendText(" internal fun with${name.capitalize()}($name: $typeName): $className {\n") + file.appendText(" this.$name = $name\n") + file.appendText(" return this\n") + file.appendText(" }\n\n") + } + file.appendText(" internal fun build(): ${parent.qualifiedName!!.asString()} {\n") + file.appendText(" return ${parent.qualifiedName!!.asString()}(") + file.appendText( + function.parameters.map { + "${it.name!!.asString()}!!" + }.joinToString(", ") + ) + file.appendText(")\n") + file.appendText(" }\n") + file.appendText("}\n") + file.close() + } + } +} + +class TestProcessorProvider : SymbolProcessorProvider { + override fun create( + env: SymbolProcessorEnvironment, + ): SymbolProcessor { + return BuilderProcessor().apply { + init(env.options, env.kotlinVersion, env.codeGenerator, env.logger) + } + } +} diff --git a/integration-tests/src/test/resources/kapt3/test-processor/src/main/kotlin/RewriteProcessor.kt b/integration-tests/src/test/resources/kapt3/test-processor/src/main/kotlin/RewriteProcessor.kt new file mode 100644 index 0000000000..91121c6811 --- /dev/null +++ b/integration-tests/src/test/resources/kapt3/test-processor/src/main/kotlin/RewriteProcessor.kt @@ -0,0 +1,31 @@ + +import com.google.devtools.ksp.processing.* +import com.google.devtools.ksp.symbol.* + +class RewriteProcessor : SymbolProcessor { + lateinit var codeGenerator: CodeGenerator + + fun init( + options: Map, + kotlinVersion: KotlinVersion, + codeGenerator: CodeGenerator, + logger: KSPLogger + ) { + this.codeGenerator = codeGenerator + } + + override fun process(resolver: Resolver): List { + val fileKt = codeGenerator.createNewFile(Dependencies(false), "hello", "HELLO", "java") + return emptyList() + } +} + +class RewriteProcessorProvider : SymbolProcessorProvider { + override fun create( + env: SymbolProcessorEnvironment + ): SymbolProcessor { + return RewriteProcessor().apply { + init(env.options, env.kotlinVersion, env.codeGenerator, env.logger) + } + } +} diff --git a/integration-tests/src/test/resources/kapt3/test-processor/src/main/kotlin/TestProcessor.kt b/integration-tests/src/test/resources/kapt3/test-processor/src/main/kotlin/TestProcessor.kt new file mode 100644 index 0000000000..324982cbc1 --- /dev/null +++ b/integration-tests/src/test/resources/kapt3/test-processor/src/main/kotlin/TestProcessor.kt @@ -0,0 +1,284 @@ + +import com.google.devtools.ksp.containingFile +import com.google.devtools.ksp.processing.* +import com.google.devtools.ksp.symbol.* +import java.io.OutputStream + +class TestProcessor : SymbolProcessor { + lateinit var codeGenerator: CodeGenerator + lateinit var file: OutputStream + var invoked = false + + fun emit(s: String, indent: String) { + file.appendText("$indent$s\n") + } + + fun init( + options: Map, + kotlinVersion: KotlinVersion, + codeGenerator: CodeGenerator, + logger: KSPLogger + ) { + logger.warn("This is a harmless warning.") + this.codeGenerator = codeGenerator + file = codeGenerator.createNewFile(Dependencies(false), "", "TestProcessor", "log") + emit("TestProcessor: init($options)", "") + + val javaFile = codeGenerator.createNewFile(Dependencies(false), "", "Generated", "java") + javaFile.appendText("class Generated {}") + } + + override fun process(resolver: Resolver): List { + if (invoked) { + return emptyList() + } + val fileKt = codeGenerator.createNewFile(Dependencies(false), "hello", "HELLO", "java") + fileKt.appendText("package hello;\n") + fileKt.appendText("public class HELLO{\n") + fileKt.appendText("public int foo() { return 1234; }\n") + fileKt.appendText("}") + + val files = resolver.getAllFiles() + emit("TestProcessor: process()", "") + val visitor = TestVisitor() + for (file in files) { + emit("TestProcessor: processing ${file.fileName}", "") + file.accept(visitor, "") + } + invoked = true + return emptyList() + } + + inner class TestVisitor : KSVisitor { + + override fun visitReferenceElement(element: KSReferenceElement, data: String) { + } + + override fun visitModifierListOwner(modifierListOwner: KSModifierListOwner, data: String) { + TODO("Not yet implemented") + } + + override fun visitNode(node: KSNode, data: String) { + TODO("Not yet implemented") + } + + override fun visitPropertyAccessor(accessor: KSPropertyAccessor, data: String) { + TODO("Not yet implemented") + } + + override fun visitDynamicReference(reference: KSDynamicReference, data: String) { + TODO("Not yet implemented") + } + + override fun visitDefNonNullReference(reference: KSDefNonNullReference, data: String) { + TODO("Not yet implemented") + } + + val visited = HashSet() + + private fun checkVisited(symbol: Any): Boolean { + return if (visited.contains(symbol)) { + true + } else { + visited.add(symbol) + false + } + } + + private fun invokeCommonDeclarationApis(declaration: KSDeclaration, indent: String) { + emit( + "${declaration.modifiers.joinToString(" ")} ${declaration.simpleName.asString()}", indent + ) + declaration.annotations.map { it.accept(this, "$indent ") } + if (declaration.parentDeclaration != null) + emit(" enclosing: ${declaration.parentDeclaration!!.qualifiedName?.asString()}", indent) + declaration.containingFile?.let { emit("${it.packageName.asString()}.${it.fileName}", indent) } + declaration.typeParameters.map { it.accept(this, "$indent ") } + } + + override fun visitFile(file: KSFile, data: String) { +// if (!file.packageName.asString().startsWith("eu.kanade.tachiyomi.data")) { +// return +// } + if (checkVisited(file)) return + file.annotations.forEach { it.accept(this, "$data ") } + emit(file.packageName.asString(), data) + for (declaration in file.declarations) { + declaration.accept(this, data) + } + } + + override fun visitAnnotation(annotation: KSAnnotation, data: String) { + if (checkVisited(annotation)) return + emit("annotation", data) + annotation.annotationType.accept(this, "$data ") + annotation.arguments.forEach { it.accept(this, "$data ") } + } + + override fun visitCallableReference(reference: KSCallableReference, data: String) { + if (checkVisited(reference)) return + emit("element: ", data) + reference.functionParameters.forEach { it.accept(this, "$data ") } + reference.receiverType?.accept(this, "$data receiver") + reference.returnType.accept(this, "$data ") + } + + override fun visitPropertyGetter(getter: KSPropertyGetter, data: String) { + if (checkVisited(getter)) return + emit("propertyGetter: ", data) + getter.annotations.forEach { it.accept(this, "$data ") } + emit(getter.modifiers.joinToString(" "), data) + getter.returnType?.accept(this, "$data ") + } + + override fun visitPropertySetter(setter: KSPropertySetter, data: String) { + if (checkVisited(setter)) return + emit("propertySetter: ", data) + setter.annotations.forEach { it.accept(this, "$data ") } + emit(setter.modifiers.joinToString(" "), data) +// setter.parameter.accept(this, "$data ") + } + + override fun visitTypeArgument(typeArgument: KSTypeArgument, data: String) { + if (checkVisited(typeArgument)) return + typeArgument.annotations.forEach { it.accept(this, "$data ") } + emit( + when (typeArgument.variance) { + Variance.STAR -> "*" + Variance.COVARIANT -> "out" + Variance.CONTRAVARIANT -> "in" + else -> "" + }, + data + ) + typeArgument.type?.accept(this, "$data ") + } + + override fun visitTypeParameter(typeParameter: KSTypeParameter, data: String) { + if (checkVisited(typeParameter)) return + typeParameter.annotations.forEach { it.accept(this, "$data ") } + if (typeParameter.isReified) { + emit("reified ", data) + } + emit( + when (typeParameter.variance) { + Variance.COVARIANT -> "out " + Variance.CONTRAVARIANT -> "in " + else -> "" + } + typeParameter.name.asString(), + data + ) + if (typeParameter.bounds.toList().isNotEmpty()) { + typeParameter.bounds.forEach { it.accept(this, "$data ") } + } + } + + override fun visitValueParameter(valueParameter: KSValueParameter, data: String) { + if (checkVisited(valueParameter)) return + valueParameter.annotations.forEach { it.accept(this, "$data ") } + if (valueParameter.isVararg) { + emit("vararg", "$data ") + } + if (valueParameter.isNoInline) { + emit("noinline", "$data ") + } + if (valueParameter.isCrossInline) { + emit("crossinline ", "$data ") + } + emit(valueParameter.name?.asString() ?: "_", "$data ") + valueParameter.type.accept(this, "$data ") + } + + override fun visitFunctionDeclaration(function: KSFunctionDeclaration, data: String) { + if (checkVisited(function)) return + invokeCommonDeclarationApis(function, data) + for (declaration in function.declarations) { + declaration.accept(this, "$data ") + } + function.parameters.forEach { it.accept(this, "$data ") } + function.typeParameters.forEach { it.accept(this, "$data ") } + function.extensionReceiver?.accept(this, "$data extension:") + emit("returnType:", data) + function.returnType?.accept(this, "$data ") + } + + override fun visitClassDeclaration(classDeclaration: KSClassDeclaration, data: String) { + if (checkVisited(classDeclaration)) return + invokeCommonDeclarationApis(classDeclaration, data) + emit(classDeclaration.classKind.type, data) + for (declaration in classDeclaration.declarations) { + declaration.accept(this, "$data ") + } + classDeclaration.superTypes.forEach { it.accept(this, "$data ") } + classDeclaration.primaryConstructor?.accept(this, "$data ") + } + + override fun visitPropertyDeclaration(property: KSPropertyDeclaration, data: String) { + if (checkVisited(property)) return + invokeCommonDeclarationApis(property, data) + property.type.accept(this, "$data ") + property.extensionReceiver?.accept(this, "$data extension:") + property.setter?.accept(this, "$data ") + property.getter?.accept(this, "$data ") + } + + override fun visitTypeReference(typeReference: KSTypeReference, data: String) { + if (checkVisited(typeReference)) return + typeReference.annotations.forEach { it.accept(this, "$data ") } + val type = typeReference.resolve() + type.let { + emit("resolved to: ${it.declaration.qualifiedName?.asString()}", data) + } + // resolved.accept(this, "$data ") + // TODO: KSTypeReferenceJavaImpl hasn't completed yet. + try { + typeReference.element?.accept(this, "$data ") + } catch (e: IllegalStateException) { + emit("TestProcessor: exception: $e", data) + } + } + + override fun visitAnnotated(annotated: KSAnnotated, data: String) { + } + + override fun visitDeclaration(declaration: KSDeclaration, data: String) { + } + + override fun visitDeclarationContainer(declarationContainer: KSDeclarationContainer, data: String) { + } + + override fun visitParenthesizedReference(reference: KSParenthesizedReference, data: String) { + } + + override fun visitClassifierReference(reference: KSClassifierReference, data: String) { + if (checkVisited(reference)) return + if (reference.typeArguments.toList().isNotEmpty()) { + reference.typeArguments.forEach { it.accept(this, "$data ") } + } + } + + override fun visitTypeAlias(typeAlias: KSTypeAlias, data: String) { + } + + override fun visitValueArgument(valueArgument: KSValueArgument, data: String) { + if (checkVisited(valueArgument)) return + val name = valueArgument.name?.asString() ?: "" + emit("$name: ${valueArgument.value}", data) + valueArgument.annotations.forEach { it.accept(this, "$data ") } + } + } +} + +class TestProcessorProvider2 : SymbolProcessorProvider { + override fun create( + env: SymbolProcessorEnvironment + ): SymbolProcessor { + return TestProcessor().apply { + init(env.options, env.kotlinVersion, env.codeGenerator, env.logger) + + env.logger.warn("language version: ${env.kotlinVersion}") + env.logger.warn("api version: ${env.apiVersion}") + env.logger.warn("compiler version: ${env.compilerVersion}") + } + } +} diff --git a/integration-tests/src/test/resources/kapt3/test-processor/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider b/integration-tests/src/test/resources/kapt3/test-processor/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider new file mode 100644 index 0000000000..3a1528c96c --- /dev/null +++ b/integration-tests/src/test/resources/kapt3/test-processor/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider @@ -0,0 +1,2 @@ +TestProcessorProvider +TestProcessorProvider2 diff --git a/integration-tests/src/test/resources/kapt3/workload/build.gradle.kts b/integration-tests/src/test/resources/kapt3/workload/build.gradle.kts new file mode 100644 index 0000000000..d2fedb08b5 --- /dev/null +++ b/integration-tests/src/test/resources/kapt3/workload/build.gradle.kts @@ -0,0 +1,27 @@ +val testRepo: String by project + +plugins { + id("com.google.devtools.ksp") + kotlin("jvm") + kotlin("kapt") +} + +version = "1.0-SNAPSHOT" + +repositories { + maven(testRepo) + mavenCentral() + maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/bootstrap/") +} + +dependencies { + implementation(kotlin("stdlib")) + implementation(project(":test-processor")) + ksp(project(":test-processor")) + kapt("com.google.auto.service:auto-service:1.0") +} + +ksp { + arg("option1", "value1") + arg("option2", "value2") +} diff --git a/integration-tests/src/test/resources/kapt3/workload/src/main/java/com/example/A.kt b/integration-tests/src/test/resources/kapt3/workload/src/main/java/com/example/A.kt new file mode 100644 index 0000000000..e5fa7f9755 --- /dev/null +++ b/integration-tests/src/test/resources/kapt3/workload/src/main/java/com/example/A.kt @@ -0,0 +1,16 @@ +package com.example + +import hello.HELLO + +fun main() { + val hello = HELLO() + println(hello.foo()) + + val builder = AClassBuilder() + builder + .withA(1) + .withB("foo") + .withC(2.3) + val aClass: AClass = builder.build() + println(aClass.foo()) +} diff --git a/integration-tests/src/test/resources/kapt3/workload/src/main/java/com/example/AClass.kt b/integration-tests/src/test/resources/kapt3/workload/src/main/java/com/example/AClass.kt new file mode 100644 index 0000000000..180dbe6a2a --- /dev/null +++ b/integration-tests/src/test/resources/kapt3/workload/src/main/java/com/example/AClass.kt @@ -0,0 +1,17 @@ +package com.example + +import com.example.annotation.Builder +import hello.HELLO + +@Builder +class AClass(private val a: Int, val b: String, val c: Double, val d: HELLO) { + val p = "$a, $b, $c" + fun foo() = HELLO() + val hello = HELLO() + var hello2: HELLO = HELLO() + get() { return hello2 } + private set + class innerClass + + val generic = innerClass() +} diff --git a/integration-tests/src/test/resources/kapt3/workload/src/main/java/com/example/BClass.java b/integration-tests/src/test/resources/kapt3/workload/src/main/java/com/example/BClass.java new file mode 100644 index 0000000000..fcfbcbcf32 --- /dev/null +++ b/integration-tests/src/test/resources/kapt3/workload/src/main/java/com/example/BClass.java @@ -0,0 +1,14 @@ +package com.example; + +import com.example.annotation.Builder; +import hello.HELLO; +import java.util.List; + +@Builder +public class BClass { + public HELLO hello; + public HELLO helloFun(){ + return null; + } + public List list = null; +} \ No newline at end of file