diff --git a/CHANGELOG.md b/CHANGELOG.md index b260f267..cb1e04c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ **Added** - Add `--summary-only` flag. +- Support diffing bytecode versions for classes. **Fixed** - Significantly improve `.jar` diff performance. diff --git a/formats/api/formats.api b/formats/api/formats.api index 9d248958..65d8ed54 100644 --- a/formats/api/formats.api +++ b/formats/api/formats.api @@ -234,8 +234,9 @@ public abstract interface class com/jakewharton/diffuse/format/BinaryFormat { public final class com/jakewharton/diffuse/format/Class { public static final field Companion Lcom/jakewharton/diffuse/format/Class$Companion; - public synthetic fun (Ljava/lang/String;Ljava/util/List;Ljava/util/List;Lkotlin/jvm/internal/DefaultConstructorMarker;)V + public synthetic fun (Ljava/lang/String;ILjava/util/List;Ljava/util/List;Lkotlin/jvm/internal/DefaultConstructorMarker;)V public fun equals (Ljava/lang/Object;)Z + public final fun getBytecodeVersion ()I public final fun getDeclaredMembers ()Ljava/util/List; public final fun getDescriptor-BeHrSHk ()Ljava/lang/String; public final fun getReferencedMembers ()Ljava/util/List; diff --git a/formats/src/main/kotlin/com/jakewharton/diffuse/format/Class.kt b/formats/src/main/kotlin/com/jakewharton/diffuse/format/Class.kt index df6a67d1..c45ff9b1 100644 --- a/formats/src/main/kotlin/com/jakewharton/diffuse/format/Class.kt +++ b/formats/src/main/kotlin/com/jakewharton/diffuse/format/Class.kt @@ -12,16 +12,19 @@ import org.objectweb.asm.Opcodes class Class private constructor( val descriptor: TypeDescriptor, + val bytecodeVersion: Int, val declaredMembers: List, val referencedMembers: List, ) { override fun toString() = descriptor.toString() - override fun hashCode() = Objects.hash(descriptor, declaredMembers, referencedMembers) + override fun hashCode() = + Objects.hash(descriptor, bytecodeVersion, declaredMembers, referencedMembers) override fun equals(other: Any?) = other is Class && descriptor == other.descriptor && + bytecodeVersion == other.bytecodeVersion && declaredMembers == other.declaredMembers && referencedMembers == other.referencedMembers @@ -36,15 +39,33 @@ private constructor( val declaredVisitor = DeclaredMembersVisitor(type, referencedVisitor) reader.accept(declaredVisitor, 0) - return Class(type, declaredVisitor.members.sorted(), referencedVisitor.members.sorted()) + return Class( + type, + declaredVisitor.version, + declaredVisitor.members.sorted(), + referencedVisitor.members.sorted(), + ) } } } private class DeclaredMembersVisitor(val type: TypeDescriptor, val methodVisitor: MethodVisitor) : ClassVisitor(Opcodes.ASM9) { + var version: Int = 0 val members = mutableListOf() + override fun visit( + version: Int, + access: Int, + name: String, + signature: String?, + superName: String?, + interfaces: Array?, + ) { + this.version = version + super.visit(version, access, name, signature, superName, interfaces) + } + override fun visitMethod( access: Int, name: String, diff --git a/reports/src/main/kotlin/com/jakewharton/diffuse/diff/JarsDiff.kt b/reports/src/main/kotlin/com/jakewharton/diffuse/diff/JarsDiff.kt index ebdeba53..b402e235 100644 --- a/reports/src/main/kotlin/com/jakewharton/diffuse/diff/JarsDiff.kt +++ b/reports/src/main/kotlin/com/jakewharton/diffuse/diff/JarsDiff.kt @@ -18,6 +18,10 @@ internal class JarsDiff( val newMapping: ApiMapping, ) { val classes = componentDiff(oldJars, newJars) { it.classes.map(Class::descriptor) } + val bytecodeVersions = + componentDiff(oldJars, newJars) { jar -> + jar.classes.map { "${it.descriptor}: ${it.bytecodeVersion}" } + } val methods = componentDiff(oldJars, newJars) { it.members.filterIsInstance() } val declaredMethods = componentDiff(oldJars, newJars) { it.declaredMembers.filterIsInstance() } @@ -29,7 +33,7 @@ internal class JarsDiff( val referencedFields = componentDiff(oldJars, newJars) { it.referencedMembers.filterIsInstance() } - val changed = methods.changed || fields.changed + val changed = bytecodeVersions.changed || methods.changed || fields.changed } internal fun JarsDiff.toSummaryTable(name: String) = @@ -72,6 +76,7 @@ internal fun JarsDiff.toSummaryTable(name: String) = internal fun JarsDiff.toDetailReport() = buildString { // TODO appendComponentDiff("STRINGS", strings)? appendComponentDiff("CLASSES", classes) + appendComponentDiff("BYTECODE VERSIONS", bytecodeVersions) appendComponentDiff("METHODS", methods) appendComponentDiff("FIELDS", fields) }