From 6ba98f7fe62963864cc0caea27a52747ec0524f8 Mon Sep 17 00:00:00 2001 From: Ilya Gorbunov Date: Wed, 30 Mar 2016 20:30:59 +0300 Subject: [PATCH] Binary compatibility validator: filter out empty facades *after* members are flattened from non-public part superclasses. Use stable member sort order for members flattened from non-public superclasses, rewrite test to make order matter. --- .../PublicApiDump.kt | 19 +++++++------------ .../org.jetbrains.kotlin.tools/asmUtils.kt | 15 ++++++++++++++- .../src/test/kotlin/cases/java/Facade.java | 4 ++-- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/libraries/tools/binary-compatibility-validator/src/main/kotlin/org.jetbrains.kotlin.tools/PublicApiDump.kt b/libraries/tools/binary-compatibility-validator/src/main/kotlin/org.jetbrains.kotlin.tools/PublicApiDump.kt index 0bdaba4e425..77706b11cc6 100644 --- a/libraries/tools/binary-compatibility-validator/src/main/kotlin/org.jetbrains.kotlin.tools/PublicApiDump.kt +++ b/libraries/tools/binary-compatibility-validator/src/main/kotlin/org.jetbrains.kotlin.tools/PublicApiDump.kt @@ -5,7 +5,6 @@ import org.objectweb.asm.tree.* import java.io.File import java.io.InputStream import java.util.jar.JarFile -import kotlin.comparisons.compareBy fun main(args: Array) { var src = args[0] @@ -36,19 +35,13 @@ fun getBinaryAPI(classStreams: Sequence, visibilityMap: Map.filterOutNonPublic(): List return this.copy(memberSignatures = memberSignatures + inheritedStaticSignatures, supertypes = supertypes - superName) } - return filter { it -> it.isPublicAndAccessible() }.map { it.flattenNonPublicBases() } + return filter { it.isPublicAndAccessible() } + .map { it.flattenNonPublicBases() } + .filterNot { it.isFileOrMultipartFacade && it.memberSignatures.isEmpty()} } fun List.dump() = dump(to = System.out) fun List.dump(to: T): T = to.apply { this@dump.forEach { append(it.signature).appendln(" {") - it.memberSignatures.forEach { append("\t").appendln(it.signature) } + it.memberSignatures.sortedWith(MEMBER_SORT_ORDER).forEach { append("\t").appendln(it.signature) } appendln("}\n") }} diff --git a/libraries/tools/binary-compatibility-validator/src/main/kotlin/org.jetbrains.kotlin.tools/asmUtils.kt b/libraries/tools/binary-compatibility-validator/src/main/kotlin/org.jetbrains.kotlin.tools/asmUtils.kt index 2fbfa5eb5bd..749ec3b6502 100644 --- a/libraries/tools/binary-compatibility-validator/src/main/kotlin/org.jetbrains.kotlin.tools/asmUtils.kt +++ b/libraries/tools/binary-compatibility-validator/src/main/kotlin/org.jetbrains.kotlin.tools/asmUtils.kt @@ -2,6 +2,7 @@ package org.jetbrains.kotlin.tools import org.objectweb.asm.Opcodes import org.objectweb.asm.tree.* +import kotlin.comparisons.* val ACCESS_NAMES = mapOf( Opcodes.ACC_PUBLIC to "public", @@ -21,7 +22,8 @@ data class ClassBinarySignature( val supertypes: List, val memberSignatures: List, val access: AccessFlags, - val isEffectivelyPublic: Boolean) { + val isEffectivelyPublic: Boolean, + val isFileOrMultipartFacade: Boolean) { val signature: String get() = "${access.getModifierString()} class $name" + if (supertypes.isEmpty()) "" else " : ${supertypes.joinToString()}" @@ -79,6 +81,17 @@ data class FieldBinarySignature( } } +val MemberBinarySignature.kind: Int get() = when (this) { + is FieldBinarySignature -> 1 + is MethodBinarySignature -> 2 + else -> error("Unsupported $this") +} + +val MEMBER_SORT_ORDER = compareBy( + { it.kind }, + { it.name }, + { it.desc } +) data class AccessFlags(val access: Int) { diff --git a/libraries/tools/binary-compatibility-validator/src/test/kotlin/cases/java/Facade.java b/libraries/tools/binary-compatibility-validator/src/test/kotlin/cases/java/Facade.java index 21b0d9f4c69..d7757d5131a 100644 --- a/libraries/tools/binary-compatibility-validator/src/test/kotlin/cases/java/Facade.java +++ b/libraries/tools/binary-compatibility-validator/src/test/kotlin/cases/java/Facade.java @@ -1,10 +1,10 @@ package cases.java; class Part1 { - public static void publicMethod(String param) { } + public static void publicMethod(int param) { } public static class Part2 extends Part1 { - public static void publicMethod(int param) { } + public static void publicMethod(String param) { } } }