diff --git a/src/main/kotlin/api/AsmMetadataLoading.kt b/src/main/kotlin/api/AsmMetadataLoading.kt index b7a4d303..f106c1de 100644 --- a/src/main/kotlin/api/AsmMetadataLoading.kt +++ b/src/main/kotlin/api/AsmMetadataLoading.kt @@ -39,7 +39,7 @@ internal fun ClassNode.isEffectivelyPublic(classVisibility: ClassVisibility?) = private val ClassNode.innerClassNode: InnerClassNode? get() = innerClasses.singleOrNull { it.name == name } -private fun ClassNode.isLocal() = outerMethod != null +private fun ClassNode.isLocal() = outerClass != null // using outerMethod is unreliable, because even for local classes outerMethod can sometimes be null private fun ClassNode.isInner() = innerClassNode != null private fun ClassNode.isWhenMappings() = isSynthetic(access) && name.endsWith("\$WhenMappings") private fun ClassNode.isSyntheticAnnotationClass() = isSynthetic(access) && name.contains("\$annotationImpl\$") diff --git a/src/test/kotlin/tests/PrecompiledCasesTest.kt b/src/test/kotlin/tests/PrecompiledCasesTest.kt new file mode 100644 index 00000000..c1cec4f7 --- /dev/null +++ b/src/test/kotlin/tests/PrecompiledCasesTest.kt @@ -0,0 +1,40 @@ +/* + * Copyright 2016-2025 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.tests + +import kotlinx.validation.api.* +import org.junit.* +import org.junit.rules.TestName +import java.io.File +import java.nio.file.Path +import kotlin.io.path.ExperimentalPathApi +import kotlin.io.path.walk + +class PrecompiledCasesTest { + + companion object { + val baseOutputPath = File("src/test/resources/precompiled") + } + + @Rule + @JvmField + val testName = TestName() + + @Test fun parcelable() { snapshotAPIAndCompare(testName.methodName) } + + @OptIn(ExperimentalPathApi::class) + private fun snapshotAPIAndCompare(testClassRelativePath: String, nonPublicMarkers: Set = emptySet()) { + val testClasses = baseOutputPath.toPath().walk().map(Path::toFile).toList() + check(testClasses.isNotEmpty()) { "No class files are found in path: $baseOutputPath" } + + val testClassStreams = testClasses.asSequence().filter { it.name.endsWith(".class") }.map { it.inputStream() } + val classes = testClassStreams.loadApiFromJvmClasses() + val additionalPackages = classes.extractAnnotatedPackages(nonPublicMarkers) + val api = classes.filterOutNonPublic(nonPublicPackages = additionalPackages).filterOutAnnotated(nonPublicMarkers) + val target = baseOutputPath.resolve(testClassRelativePath).resolve(testName.methodName + ".txt") + api.dumpAndCompareWith(target) + } +} diff --git a/src/test/resources/precompiled/parcelable/Country$Creator.class b/src/test/resources/precompiled/parcelable/Country$Creator.class new file mode 100644 index 00000000..a2adb565 Binary files /dev/null and b/src/test/resources/precompiled/parcelable/Country$Creator.class differ diff --git a/src/test/resources/precompiled/parcelable/parcelable.txt b/src/test/resources/precompiled/parcelable/parcelable.txt new file mode 100644 index 00000000..e69de29b