diff --git a/build.gradle.kts b/build.gradle.kts index 352d0ebd..9fc60319 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -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. @@ -84,11 +84,14 @@ dependencies { "functionalTestImplementation"(kotlin("test-junit")) } -tasks.withType().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" @@ -103,7 +106,7 @@ java { tasks { compileTestKotlin { kotlinOptions { - languageVersion = "1.4" + languageVersion = "1.6" } } test { diff --git a/gradle.properties b/gradle.properties index 3475bc7e..c102b30d 100644 --- a/gradle.properties +++ b/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 diff --git a/src/functionalTest/kotlin/kotlinx/validation/api/testDsl.kt b/src/functionalTest/kotlin/kotlinx/validation/api/TestDsl.kt similarity index 90% rename from src/functionalTest/kotlin/kotlinx/validation/api/testDsl.kt rename to src/functionalTest/kotlin/kotlinx/validation/api/TestDsl.kt index d3d7f31e..b88da146 100644 --- a/src/functionalTest/kotlin/kotlinx/validation/api/testDsl.kt +++ b/src/functionalTest/kotlin/kotlinx/validation/api/TestDsl.kt @@ -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) } @@ -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) +} diff --git a/src/functionalTest/kotlin/kotlinx/validation/api/pluginTestRuntimeClasspath.kt b/src/functionalTest/kotlin/kotlinx/validation/api/pluginTestRuntimeClasspath.kt deleted file mode 100644 index f11901e5..00000000 --- a/src/functionalTest/kotlin/kotlinx/validation/api/pluginTestRuntimeClasspath.kt +++ /dev/null @@ -1,22 +0,0 @@ -/* - * 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 kotlinx.validation.api - -import org.gradle.testkit.runner.GradleRunner -import java.io.File -import java.io.InputStreamReader - - -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) - -} diff --git a/src/functionalTest/kotlin/kotlinx/validation/test/MultiPlatformSingleJvmTargetTest.kt b/src/functionalTest/kotlin/kotlinx/validation/test/MultiPlatformSingleJvmTargetTest.kt index ebc7876d..22cf9ab2 100644 --- a/src/functionalTest/kotlin/kotlinx/validation/test/MultiPlatformSingleJvmTargetTest.kt +++ b/src/functionalTest/kotlin/kotlinx/validation/test/MultiPlatformSingleJvmTargetTest.kt @@ -44,7 +44,7 @@ internal class MultiPlatformSingleJvmTargetTest : BaseKotlinGradleTest() { resolve("examples/classes/Subsub2Class.kt") } - }.addPluginTestRuntimeClasspath() + } runner.build().apply { assertTaskSuccess(":apiCheck") @@ -76,7 +76,7 @@ internal class MultiPlatformSingleJvmTargetTest : BaseKotlinGradleTest() { resolve("examples/classes/Subsub2Class.kt") } - }.addPluginTestRuntimeClasspath() + } runner.buildAndFail().apply { assertTaskFailure(":jvmApiCheck") @@ -104,7 +104,7 @@ internal class MultiPlatformSingleJvmTargetTest : BaseKotlinGradleTest() { resolve("examples/classes/Subsub2Class.kt") } - }.addPluginTestRuntimeClasspath() + } runner.build().apply { assertTaskSuccess(":apiDump") diff --git a/src/functionalTest/kotlin/kotlinx/validation/test/MultipleJvmTargetsTest.kt b/src/functionalTest/kotlin/kotlinx/validation/test/MultipleJvmTargetsTest.kt index 9b27a773..e718f67f 100644 --- a/src/functionalTest/kotlin/kotlinx/validation/test/MultipleJvmTargetsTest.kt +++ b/src/functionalTest/kotlin/kotlinx/validation/test/MultipleJvmTargetsTest.kt @@ -51,7 +51,7 @@ internal class MultipleJvmTargetsTest : BaseKotlinGradleTest() { resolve("examples/classes/Subsub2Class.kt") } - }.addPluginTestRuntimeClasspath() + } runner.build().apply { assertTaskSuccess(":apiCheck") @@ -90,7 +90,7 @@ internal class MultipleJvmTargetsTest : BaseKotlinGradleTest() { resolve("examples/classes/Subsub2Class.kt") } - }.addPluginTestRuntimeClasspath() + } runner.buildAndFail().apply { assertTaskNotRun(":apiCheck") @@ -118,7 +118,7 @@ internal class MultipleJvmTargetsTest : BaseKotlinGradleTest() { resolve("examples/classes/Subsub2Class.kt") } - }.addPluginTestRuntimeClasspath() + } runner.build().apply { assertTaskSuccess(":apiDump") assertTaskSuccess(":jvmApiDump") diff --git a/src/main/kotlin/api/AsmMetadataLoading.kt b/src/main/kotlin/api/AsmMetadataLoading.kt index 321986c5..fc7149af 100644 --- a/src/main/kotlin/api/AsmMetadataLoading.kt +++ b/src/main/kotlin/api/AsmMetadataLoading.kt @@ -27,11 +27,11 @@ 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) @@ -39,6 +39,7 @@ val ClassNode.innerClassNode: InnerClassNode? get() = innerClasses.singleOrNull 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 diff --git a/src/test/kotlin/cases/annotations/annotation.kt b/src/test/kotlin/cases/annotations/annotation.kt new file mode 100644 index 00000000..077a9844 --- /dev/null +++ b/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() + } +} diff --git a/src/test/kotlin/cases/annotations/annotations.txt b/src/test/kotlin/cases/annotations/annotations.txt new file mode 100644 index 00000000..b084dbcc --- /dev/null +++ b/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 +} + diff --git a/src/test/kotlin/cases/annotations/inlineFunctionWithAnnotation.kt b/src/test/kotlin/cases/annotations/inlineFunctionWithAnnotation.kt new file mode 100644 index 00000000..e3a17244 --- /dev/null +++ b/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) +} diff --git a/src/test/kotlin/tests/CasesPublicAPITest.kt b/src/test/kotlin/tests/CasesPublicAPITest.kt index 47d5ae5a..d01917d0 100644 --- a/src/test/kotlin/tests/CasesPublicAPITest.kt +++ b/src/test/kotlin/tests/CasesPublicAPITest.kt @@ -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) }