Skip to content

Commit

Permalink
refactor: Add mutableClassByOrNull()
Browse files Browse the repository at this point in the history
  • Loading branch information
LisoUseInAIKyrios committed Jan 28, 2025
1 parent 8f7911e commit 567feef
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 15 deletions.
8 changes: 8 additions & 0 deletions api/revanced-patcher.api
Original file line number Diff line number Diff line change
Expand Up @@ -313,13 +313,17 @@ public final class app/revanced/patcher/patch/BytecodePatchBuilder : app/revance
public final class app/revanced/patcher/patch/BytecodePatchContext : app/revanced/patcher/patch/PatchContext, java/io/Closeable {
public final fun classBy (Ljava/lang/String;)Lcom/android/tools/smali/dexlib2/iface/ClassDef;
public final fun classBy (Lkotlin/jvm/functions/Function1;)Lcom/android/tools/smali/dexlib2/iface/ClassDef;
public final fun classByOrNull (Ljava/lang/String;)Lcom/android/tools/smali/dexlib2/iface/ClassDef;
public final fun classByOrNull (Lkotlin/jvm/functions/Function1;)Lcom/android/tools/smali/dexlib2/iface/ClassDef;
public fun close ()V
public synthetic fun get ()Ljava/lang/Object;
public fun get ()Ljava/util/Set;
public final fun getClasses ()Lapp/revanced/patcher/util/PatchClasses;
public final fun mutableClassBy (Lcom/android/tools/smali/dexlib2/iface/ClassDef;)Lapp/revanced/patcher/util/proxy/mutableTypes/MutableClass;
public final fun mutableClassBy (Ljava/lang/String;)Lapp/revanced/patcher/util/proxy/mutableTypes/MutableClass;
public final fun mutableClassBy (Lkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/util/proxy/mutableTypes/MutableClass;
public final fun mutableClassByOrNull (Ljava/lang/String;)Lapp/revanced/patcher/util/proxy/mutableTypes/MutableClass;
public final fun mutableClassByOrNull (Lkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/util/proxy/mutableTypes/MutableClass;
public final fun navigate (Lcom/android/tools/smali/dexlib2/iface/reference/MethodReference;)Lapp/revanced/patcher/util/MethodNavigator;
public final fun proxy (Lcom/android/tools/smali/dexlib2/iface/ClassDef;)Lapp/revanced/patcher/util/proxy/mutableTypes/MutableClass;
}
Expand Down Expand Up @@ -652,10 +656,14 @@ public final class app/revanced/patcher/util/MethodNavigator {
public final class app/revanced/patcher/util/PatchClasses {
public final fun classBy (Ljava/lang/String;)Lcom/android/tools/smali/dexlib2/iface/ClassDef;
public final fun classBy (Lkotlin/jvm/functions/Function1;)Lcom/android/tools/smali/dexlib2/iface/ClassDef;
public final fun classByOrNull (Ljava/lang/String;)Lcom/android/tools/smali/dexlib2/iface/ClassDef;
public final fun classByOrNull (Lkotlin/jvm/functions/Function1;)Lcom/android/tools/smali/dexlib2/iface/ClassDef;
public final fun forEach (Lkotlin/jvm/functions/Function1;)V
public final fun mutableClassBy (Lcom/android/tools/smali/dexlib2/iface/ClassDef;)Lapp/revanced/patcher/util/proxy/mutableTypes/MutableClass;
public final fun mutableClassBy (Ljava/lang/String;)Lapp/revanced/patcher/util/proxy/mutableTypes/MutableClass;
public final fun mutableClassBy (Lkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/util/proxy/mutableTypes/MutableClass;
public final fun mutableClassByOrNull (Ljava/lang/String;)Lapp/revanced/patcher/util/proxy/mutableTypes/MutableClass;
public final fun mutableClassByOrNull (Lkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/util/proxy/mutableTypes/MutableClass;
}

public final class app/revanced/patcher/util/proxy/mutableTypes/MutableAnnotation : com/android/tools/smali/dexlib2/base/BaseAnnotation {
Expand Down
2 changes: 1 addition & 1 deletion src/main/kotlin/app/revanced/patcher/Fingerprint.kt
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ class Fingerprint internal constructor(
): Match? {
if (_matchOrNull != null) return _matchOrNull

return matchOrNull(classBy { method.definingClass == it.type }!!, method)
return matchOrNull(classBy(method.definingClass), method)
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ class BytecodePatchContext internal constructor(private val config: PatcherConfi
internal fun mergeExtension(bytecodePatch: BytecodePatch) {
bytecodePatch.extensionInputStream?.get()?.use { extensionStream ->
RawDexIO.readRawDexFile(extensionStream, 0, null).classes.forEach { classDef ->
val existingClass = classes.classBy(classDef.type) ?: run {
val existingClass = classes.classByOrNull(classDef.type) ?: run {
logger.fine { "Adding class \"$classDef\"" }

classes.addClass(classDef)
Expand Down Expand Up @@ -107,6 +107,23 @@ class BytecodePatchContext internal constructor(private val config: PatcherConfi
*/
fun classBy(predicate: (ClassDef) -> Boolean) = classes.classBy(predicate)

/**
* Find a class with a predicate.
*
* @param classType The full classname.
* @return An immutable instance of the class type.
* @see mutableClassBy
*/
fun classByOrNull(classType: String) = classes.classByOrNull(classType)

/**
* Find a class with a predicate.
*
* @param predicate A predicate to match the class.
* @return An immutable instance of the class type.
*/
fun classByOrNull(predicate: (ClassDef) -> Boolean) = classes.classByOrNull(predicate)

/**
* Find a class with a predicate.
*
Expand All @@ -131,6 +148,23 @@ class BytecodePatchContext internal constructor(private val config: PatcherConfi
*/
fun mutableClassBy(predicate: (ClassDef) -> Boolean) = classes.mutableClassBy(predicate)

/**
* Mutable class from a full class name.
* Returns `null` if class is not available, such as a built in Android or Java library.
*
* @param classType The full classname.
* @return A mutable version of the class type.
*/
fun mutableClassByOrNull(classType: String) = classes.mutableClassByOrNull(classType)

/**
* Find a mutable class with a predicate.
*
* @param predicate A predicate to match the class.
* @return A mutable class that matches the predicate.
*/
fun mutableClassByOrNull(predicate: (ClassDef) -> Boolean) = classes.mutableClassByOrNull(predicate)

/**
* @return The mutable instance of an immutable class.
*/
Expand Down
2 changes: 1 addition & 1 deletion src/main/kotlin/app/revanced/patcher/util/ClassMerger.kt
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ internal object ClassMerger {
callback(targetClass)

targetClass.superclass ?: return
this.mutableClassBy { targetClass.superclass == it.type }?.let {
mutableClassByOrNull(targetClass.superclass!!)?.let {
traverseClassHierarchy(it, callback)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ class MethodNavigator internal constructor(
*
* @return The last navigated method immutably.
*/
fun original(): Method = classes.classBy(lastNavigatedMethodReference.definingClass)!!.firstMethodBySignature
fun original(): Method = classes.classBy(lastNavigatedMethodReference.definingClass).firstMethodBySignature

/**
* Find the first [lastNavigatedMethodReference] in the class.
Expand Down
61 changes: 50 additions & 11 deletions src/main/kotlin/app/revanced/patcher/util/PatchClasses.kt
Original file line number Diff line number Diff line change
Expand Up @@ -42,32 +42,72 @@ class PatchClasses internal constructor(
* @return An immutable instance of the class type.
* @see mutableClassBy
*/
fun classBy(classType: String) = pool[classType]
fun classByOrNull(classType: String) = pool[classType]

/**
* Find a class with a predicate.
*
* @param predicate A predicate to match the class.
* @return An immutable instance of the class type, or null if not found.
*/
fun classByOrNull(predicate: (ClassDef) -> Boolean) = pool.values.find(predicate)

/**
* Find a class with a predicate.
*
* @param predicate A predicate to match the class.
* @return An immutable instance of the class type.
*/
fun classBy(predicate: (ClassDef) -> Boolean) = pool.values.find(predicate)
fun classBy(predicate: (ClassDef) -> Boolean) = classByOrNull(predicate)
?: throw PatchException("Could not find any class match")

/**
* Find a class with a predicate.
*
* @param classType The full classname.
* @return An immutable instance of the class type.
* @see mutableClassBy
*/
fun classBy(classType: String) = classByOrNull(classType)
?: throw PatchException("Could not find class: $classType")

/**
* Mutable class from a full class name.
* Returns `null` if class is not available, such as a built in Android or Java library.
*
* @param classDefType The full classname.
* @return A mutable version of the class type.
*/
fun mutableClassBy(classDefType: String) : MutableClass {
var classDef = pool[classDefType] ?: throw PatchException("Could not find class: $classDefType")
if (classDef is MutableClass) {
return classDef
}
fun mutableClassByOrNull(classDefType: String) : MutableClass? {
var classDef = pool[classDefType]
if (classDef == null) return null
if (classDef is MutableClass) return classDef

classDef = MutableClass(classDef)
pool[classDefType] = classDef
return classDef
}

/**
* Find a class with a predicate.
*
* @param classDefType The full classname.
* @return A mutable version of the class type.
*/
fun mutableClassBy(classDefType: String) = mutableClassByOrNull(classDefType)
?: throw PatchException("Could not find class: $classDefType")

/**
* Find a mutable class with a predicate.
*
* @param predicate A predicate to match the class.
* @return A mutable class that matches the predicate.
*/
fun mutableClassByOrNull(predicate: (ClassDef) -> Boolean) =
classByOrNull(predicate)?.let {
if (it is MutableClass) it else mutableClassBy(it.type)
}

/**
* @param classDef An immutable class.
* @return A mutable version of the class definition.
Expand All @@ -81,8 +121,7 @@ class PatchClasses internal constructor(
* @param predicate A predicate to match the class.
* @return A mutable class that matches the predicate.
*/
fun mutableClassBy(predicate: (ClassDef) -> Boolean) =
classBy(predicate)?.let {
if (it is MutableClass) it else mutableClassBy(it.type)
}
fun mutableClassBy(predicate: (ClassDef) -> Boolean) = mutableClassByOrNull(predicate)
?: throw PatchException("Could not find any class match")

}

0 comments on commit 567feef

Please sign in to comment.