Skip to content

Commit

Permalink
Synthetic annotations support (#72)
Browse files Browse the repository at this point in the history
* Update Kotlin to 1.6.0
* Ignore synthetic annotation classes generated in-place for instantiation

Fixes #71
  • Loading branch information
qwwdfsad committed Dec 6, 2021
1 parent 5d48180 commit 93c05e2
Show file tree
Hide file tree
Showing 11 changed files with 61 additions and 36 deletions.
15 changes: 9 additions & 6 deletions build.gradle.kts
Expand Up @@ -67,10 +67,10 @@ val kotlinVersion: String by project
dependencies {
implementation(gradleApi())
implementation("org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.3.0")
implementation("org.ow2.asm:asm:9.0")
implementation("org.ow2.asm:asm-tree:9.0")
implementation("org.ow2.asm:asm:9.2")
implementation("org.ow2.asm:asm-tree:9.2")
implementation("com.googlecode.java-diff-utils:diffutils:1.3.0")
compileOnly("org.jetbrains.kotlin.multiplatform:org.jetbrains.kotlin.multiplatform.gradle.plugin:1.3.61")
compileOnly("org.jetbrains.kotlin.multiplatform:org.jetbrains.kotlin.multiplatform.gradle.plugin:1.6.0")

// The test needs the full kotlin multiplatform plugin loaded as it has no visibility of previously loaded plugins,
// unlike the regular way gradle loads plugins.
Expand All @@ -84,11 +84,14 @@ dependencies {
"functionalTestImplementation"(kotlin("test-junit"))
}

tasks.withType<KotlinCompile>().configureEach {
tasks.compileKotlin {
kotlinOptions.apply {
languageVersion = "1.4"
apiVersion = "1.4"
jvmTarget = "1.8"
allWarningsAsErrors = true
// TODO revert that when updating Kotlin. This flag also affects kts files and prevents
// the project from build due to "w: Language version 1.4 is deprecated and its support will be removed"
// allWarningsAsErrors = true
// Suppress the warning about kotlin-reflect 1.3 and kotlin-stdlib 1.4 in the classpath.
// It's incorrect in this case because we're limiting API version to 1.3 anyway.
freeCompilerArgs += "-Xskip-runtime-version-check"
Expand All @@ -103,7 +106,7 @@ java {
tasks {
compileTestKotlin {
kotlinOptions {
languageVersion = "1.4"
languageVersion = "1.6"
}
}
test {
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
@@ -1,5 +1,5 @@
version=0.8.0-SNAPSHOT
group=org.jetbrains.kotlinx

kotlinVersion=1.5.0
kotlinVersion=1.6.0
pluginPublishVersion=0.10.1
Expand Up @@ -30,6 +30,7 @@ internal fun BaseKotlinGradleTest.test(fn: BaseKotlinScope.() -> Unit): GradleRu
.withProjectDir(rootProjectDir)
.withPluginClasspath()
.withArguments(baseKotlinScope.runner.arguments)
.addPluginTestRuntimeClasspath()
// disabled because of: https://github.com/gradle/gradle/issues/6862
// .withDebug(baseKotlinScope.runner.debug)
}
Expand Down Expand Up @@ -140,3 +141,11 @@ internal fun readFileList(fileName: String): String {
return File(resource.toURI()).readText()
}

private fun GradleRunner.addPluginTestRuntimeClasspath() = apply {
val cpResource = javaClass.classLoader.getResourceAsStream("plugin-classpath.txt")
?.let { InputStreamReader(it) }
?: throw IllegalStateException("Could not find classpath resource")

val pluginClasspath = pluginClasspath + cpResource.readLines().map { File(it) }
withPluginClasspath(pluginClasspath)
}

This file was deleted.

Expand Up @@ -44,7 +44,7 @@ internal class MultiPlatformSingleJvmTargetTest : BaseKotlinGradleTest() {
resolve("examples/classes/Subsub2Class.kt")
}

}.addPluginTestRuntimeClasspath()
}

runner.build().apply {
assertTaskSuccess(":apiCheck")
Expand Down Expand Up @@ -76,7 +76,7 @@ internal class MultiPlatformSingleJvmTargetTest : BaseKotlinGradleTest() {
resolve("examples/classes/Subsub2Class.kt")
}

}.addPluginTestRuntimeClasspath()
}

runner.buildAndFail().apply {
assertTaskFailure(":jvmApiCheck")
Expand Down Expand Up @@ -104,7 +104,7 @@ internal class MultiPlatformSingleJvmTargetTest : BaseKotlinGradleTest() {
resolve("examples/classes/Subsub2Class.kt")
}

}.addPluginTestRuntimeClasspath()
}

runner.build().apply {
assertTaskSuccess(":apiDump")
Expand Down
Expand Up @@ -51,7 +51,7 @@ internal class MultipleJvmTargetsTest : BaseKotlinGradleTest() {
resolve("examples/classes/Subsub2Class.kt")
}

}.addPluginTestRuntimeClasspath()
}

runner.build().apply {
assertTaskSuccess(":apiCheck")
Expand Down Expand Up @@ -90,7 +90,7 @@ internal class MultipleJvmTargetsTest : BaseKotlinGradleTest() {
resolve("examples/classes/Subsub2Class.kt")
}

}.addPluginTestRuntimeClasspath()
}

runner.buildAndFail().apply {
assertTaskNotRun(":apiCheck")
Expand Down Expand Up @@ -118,7 +118,7 @@ internal class MultipleJvmTargetsTest : BaseKotlinGradleTest() {
resolve("examples/classes/Subsub2Class.kt")
}

}.addPluginTestRuntimeClasspath()
}
runner.build().apply {
assertTaskSuccess(":apiDump")
assertTaskSuccess(":jvmApiDump")
Expand Down
3 changes: 2 additions & 1 deletion src/main/kotlin/api/AsmMetadataLoading.kt
Expand Up @@ -27,18 +27,19 @@ fun isStatic(access: Int) = access and Opcodes.ACC_STATIC != 0
fun isFinal(access: Int) = access and Opcodes.ACC_FINAL != 0
fun isSynthetic(access: Int) = access and Opcodes.ACC_SYNTHETIC != 0


fun ClassNode.isEffectivelyPublic(classVisibility: ClassVisibility?) =
isPublic(access)
&& !isLocal()
&& !isWhenMappings()
&& !isSyntheticAnnotationClass()
&& (classVisibility?.isPublic(isPublishedApi()) ?: true)


val ClassNode.innerClassNode: InnerClassNode? get() = innerClasses.singleOrNull { it.name == name }
fun ClassNode.isLocal() = outerMethod != null
fun ClassNode.isInner() = innerClassNode != null
fun ClassNode.isWhenMappings() = isSynthetic(access) && name.endsWith("\$WhenMappings")
fun ClassNode.isSyntheticAnnotationClass() = isSynthetic(access) && name.contains("\$annotationImpl\$")

val ClassNode.effectiveAccess: Int get() = innerClassNode?.access ?: access
val ClassNode.outerClassName: String? get() = innerClassNode?.outerName
Expand Down
17 changes: 17 additions & 0 deletions src/test/kotlin/cases/annotations/annotation.kt
@@ -0,0 +1,17 @@
/*
* Copyright 2016-2021 JetBrains s.r.o.
* Use of this source code is governed by the Apache 2.0 License that can be found in the LICENSE.txt file.
*/

package cases.annotations

annotation class Foo(val i: Int)

private class Bar {
val foo: Foo = Foo(1) // Same module
val e = Volatile() // Cross-module

fun bar() {
foo()
}
}
4 changes: 4 additions & 0 deletions src/test/kotlin/cases/annotations/annotations.txt
@@ -0,0 +1,4 @@
public abstract interface annotation class cases/annotations/Foo : java/lang/annotation/Annotation {
public abstract fun i ()I
}

11 changes: 11 additions & 0 deletions src/test/kotlin/cases/annotations/inlineFunctionWithAnnotation.kt
@@ -0,0 +1,11 @@
/*
* Copyright 2016-2021 JetBrains s.r.o.
* Use of this source code is governed by the Apache 2.0 License that can be found in the LICENSE.txt file.
*/

package cases.annotations

@Suppress("NOTHING_TO_INLINE")
internal inline fun foo() {
Foo(42)
}
2 changes: 2 additions & 0 deletions src/test/kotlin/tests/CasesPublicAPITest.kt
Expand Up @@ -24,6 +24,8 @@ class CasesPublicAPITest {
@[Rule JvmField]
val testName = TestName()

@Test fun annotations() { snapshotAPIAndCompare(testName.methodName) }

@Test fun companions() { snapshotAPIAndCompare(testName.methodName) }

@Test fun default() { snapshotAPIAndCompare(testName.methodName) }
Expand Down

0 comments on commit 93c05e2

Please sign in to comment.