From 5f5977e2e93a16729a9441c123fa1c358ed1503c Mon Sep 17 00:00:00 2001 From: Jiaxiang Chen Date: Thu, 28 Jul 2022 23:56:46 -0700 Subject: [PATCH] Force resolve outermost class for Java nested classes. This is a temporary workaround for https://github.com/google/ksp/issues/1034 --- .../ksp/processing/impl/ResolverImpl.kt | 14 +++++++++++ .../devtools/ksp/test/JavaNestedClassIT.kt | 22 ++++++++++++++++ .../javaNestedClass/build.gradle.kts | 8 ++++++ .../javaNestedClass/settings.gradle.kts | 19 ++++++++++++++ .../test-processor/build.gradle.kts | 25 +++++++++++++++++++ .../src/main/kotlin/ValidateProcessor.kt | 24 ++++++++++++++++++ ...ols.ksp.processing.SymbolProcessorProvider | 1 + .../javaNestedClass/workload/build.gradle.kts | 20 +++++++++++++++ .../workload/src/main/java/com/example/A.kt | 4 +++ .../src/main/java/com/example/JavaClass.java | 12 +++++++++ 10 files changed, 149 insertions(+) create mode 100644 integration-tests/src/test/kotlin/com/google/devtools/ksp/test/JavaNestedClassIT.kt create mode 100644 integration-tests/src/test/resources/javaNestedClass/build.gradle.kts create mode 100644 integration-tests/src/test/resources/javaNestedClass/settings.gradle.kts create mode 100644 integration-tests/src/test/resources/javaNestedClass/test-processor/build.gradle.kts create mode 100644 integration-tests/src/test/resources/javaNestedClass/test-processor/src/main/kotlin/ValidateProcessor.kt create mode 100644 integration-tests/src/test/resources/javaNestedClass/test-processor/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider create mode 100644 integration-tests/src/test/resources/javaNestedClass/workload/build.gradle.kts create mode 100644 integration-tests/src/test/resources/javaNestedClass/workload/src/main/java/com/example/A.kt create mode 100644 integration-tests/src/test/resources/javaNestedClass/workload/src/main/java/com/example/JavaClass.java diff --git a/compiler-plugin/src/main/kotlin/com/google/devtools/ksp/processing/impl/ResolverImpl.kt b/compiler-plugin/src/main/kotlin/com/google/devtools/ksp/processing/impl/ResolverImpl.kt index a2e505dd23..61b1e66e44 100644 --- a/compiler-plugin/src/main/kotlin/com/google/devtools/ksp/processing/impl/ResolverImpl.kt +++ b/compiler-plugin/src/main/kotlin/com/google/devtools/ksp/processing/impl/ResolverImpl.kt @@ -64,6 +64,9 @@ import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaTypeParameterDesc import org.jetbrains.kotlin.load.java.lazy.types.JavaTypeResolver import org.jetbrains.kotlin.load.java.lazy.types.toAttributes import org.jetbrains.kotlin.load.java.sources.JavaSourceElement +import org.jetbrains.kotlin.load.java.structure.JavaClass +import org.jetbrains.kotlin.load.java.structure.JavaClassifierType +import org.jetbrains.kotlin.load.java.structure.classId import org.jetbrains.kotlin.load.java.structure.impl.JavaArrayTypeImpl import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl import org.jetbrains.kotlin.load.java.structure.impl.JavaConstructorImpl @@ -624,6 +627,17 @@ class ResolverImpl( } // Construct resolver context for the PsiType var resolverContext = lazyJavaResolverContext + // TODO: fix in compiler. + // Temporary work around for https://github.com/google/ksp/issues/1034 + // Force resolve outer most class for Java nested classes. + javaType.safeAs()?.classifier.safeAs()?.let { + var outerMost = it.outerClass + while (outerMost?.outerClass != null) { + outerMost = outerMost.outerClass + } + outerMost?.classId?.let { lazyJavaResolverContext.components.finder.findClass(it) } + } + for (e in stack) { when (e) { is KSFunctionDeclarationJavaImpl -> { diff --git a/integration-tests/src/test/kotlin/com/google/devtools/ksp/test/JavaNestedClassIT.kt b/integration-tests/src/test/kotlin/com/google/devtools/ksp/test/JavaNestedClassIT.kt new file mode 100644 index 0000000000..14cd09037a --- /dev/null +++ b/integration-tests/src/test/kotlin/com/google/devtools/ksp/test/JavaNestedClassIT.kt @@ -0,0 +1,22 @@ +package com.google.devtools.ksp.test + +import org.gradle.testkit.runner.GradleRunner +import org.gradle.testkit.runner.TaskOutcome +import org.junit.Assert +import org.junit.Rule +import org.junit.Test + +class JavaNestedClassIT { + @Rule + @JvmField + val project: TemporaryTestProject = TemporaryTestProject("javaNestedClass") + + @Test + fun testJavaNestedClass() { + + val gradleRunner = GradleRunner.create().withProjectDir(project.root) + + val resultCleanBuild = gradleRunner.withArguments("clean", "build").build() + Assert.assertEquals(TaskOutcome.SUCCESS, resultCleanBuild.task(":workload:build")?.outcome) + } +} diff --git a/integration-tests/src/test/resources/javaNestedClass/build.gradle.kts b/integration-tests/src/test/resources/javaNestedClass/build.gradle.kts new file mode 100644 index 0000000000..c5737a2e0d --- /dev/null +++ b/integration-tests/src/test/resources/javaNestedClass/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/javaNestedClass/settings.gradle.kts b/integration-tests/src/test/resources/javaNestedClass/settings.gradle.kts new file mode 100644 index 0000000000..5cb08c92f5 --- /dev/null +++ b/integration-tests/src/test/resources/javaNestedClass/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 = "javaNestedClass" + +include(":workload") +include(":test-processor") diff --git a/integration-tests/src/test/resources/javaNestedClass/test-processor/build.gradle.kts b/integration-tests/src/test/resources/javaNestedClass/test-processor/build.gradle.kts new file mode 100644 index 0000000000..75c6c7c5ab --- /dev/null +++ b/integration-tests/src/test/resources/javaNestedClass/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/javaNestedClass/test-processor/src/main/kotlin/ValidateProcessor.kt b/integration-tests/src/test/resources/javaNestedClass/test-processor/src/main/kotlin/ValidateProcessor.kt new file mode 100644 index 0000000000..d6845f2e55 --- /dev/null +++ b/integration-tests/src/test/resources/javaNestedClass/test-processor/src/main/kotlin/ValidateProcessor.kt @@ -0,0 +1,24 @@ +import com.google.devtools.ksp.getClassDeclarationByName +import com.google.devtools.ksp.processing.* +import com.google.devtools.ksp.symbol.* +import com.google.devtools.ksp.validate + +class ValidateProcessor(env: SymbolProcessorEnvironment) : SymbolProcessor { + var logger: KSPLogger = env.logger + + override fun process(resolver: Resolver): List { + val javaClass = resolver.getClassDeclarationByName("com.example.JavaClass")!! + if (!javaClass.validate()) { + logger.error("Failed to validate $javaClass") + } + return emptyList() + } +} + +class ValidateProcessorProvider : SymbolProcessorProvider { + override fun create( + env: SymbolProcessorEnvironment + ): SymbolProcessor { + return ValidateProcessor(env) + } +} diff --git a/integration-tests/src/test/resources/javaNestedClass/test-processor/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider b/integration-tests/src/test/resources/javaNestedClass/test-processor/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider new file mode 100644 index 0000000000..6af81c2a79 --- /dev/null +++ b/integration-tests/src/test/resources/javaNestedClass/test-processor/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider @@ -0,0 +1 @@ +ValidateProcessorProvider diff --git a/integration-tests/src/test/resources/javaNestedClass/workload/build.gradle.kts b/integration-tests/src/test/resources/javaNestedClass/workload/build.gradle.kts new file mode 100644 index 0000000000..f0ea52b0e3 --- /dev/null +++ b/integration-tests/src/test/resources/javaNestedClass/workload/build.gradle.kts @@ -0,0 +1,20 @@ +val testRepo: String by project + +plugins { + id("com.google.devtools.ksp") + kotlin("jvm") +} + +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")) +} diff --git a/integration-tests/src/test/resources/javaNestedClass/workload/src/main/java/com/example/A.kt b/integration-tests/src/test/resources/javaNestedClass/workload/src/main/java/com/example/A.kt new file mode 100644 index 0000000000..ebf0688c55 --- /dev/null +++ b/integration-tests/src/test/resources/javaNestedClass/workload/src/main/java/com/example/A.kt @@ -0,0 +1,4 @@ +package com.example + +fun main() { +} diff --git a/integration-tests/src/test/resources/javaNestedClass/workload/src/main/java/com/example/JavaClass.java b/integration-tests/src/test/resources/javaNestedClass/workload/src/main/java/com/example/JavaClass.java new file mode 100644 index 0000000000..6b2be54589 --- /dev/null +++ b/integration-tests/src/test/resources/javaNestedClass/workload/src/main/java/com/example/JavaClass.java @@ -0,0 +1,12 @@ +package com.example; + +public class JavaClass { + + public int b2; + + public ENUM e; + + public enum ENUM { + R,G,B + } +}