From 58ff464192e4a5d4a8a005c178dec9038199d062 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Fri, 28 Nov 2025 17:43:51 +0100 Subject: [PATCH] feat: Simplify composite API --- .../kotlin/app/revanced/patcher/Matching.kt | 120 +++++------------- 1 file changed, 34 insertions(+), 86 deletions(-) diff --git a/src/main/kotlin/app/revanced/patcher/Matching.kt b/src/main/kotlin/app/revanced/patcher/Matching.kt index 3e56193..85b3037 100644 --- a/src/main/kotlin/app/revanced/patcher/Matching.kt +++ b/src/main/kotlin/app/revanced/patcher/Matching.kt @@ -6,10 +6,8 @@ import app.revanced.patcher.Matcher.MatchContext import app.revanced.patcher.dex.mutable.MutableMethod import app.revanced.patcher.extensions.accessFlags import app.revanced.patcher.patch.BytecodePatchContext -import app.revanced.patcher.patch.gettingBytecodePatch import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.HiddenApiRestriction -import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.* import com.android.tools.smali.dexlib2.iface.Annotation import com.android.tools.smali.dexlib2.iface.instruction.Instruction @@ -361,22 +359,6 @@ class IndexedMatcher() : Matcher Boolean) = add { _, _ -> predicate() } } -class DeclarativePredicateBuilder { - private val children = mutableListOf Boolean>() - - fun anyOf(block: DeclarativePredicateBuilder.() -> Unit) { - val child = DeclarativePredicateBuilder().apply(block) - children += { child.children.any { it() } } - } - - fun predicate(block: T.() -> Boolean) { - children += block - } - - fun all(target: T): Boolean = children.all { target.it() } - fun any(target: T): Boolean = children.all { target.it() } -} - fun T.declarativePredicate(build: DeclarativePredicateBuilder.() -> Unit) = DeclarativePredicateBuilder().apply(build).all(this) @@ -517,88 +499,54 @@ fun gettingFirstMethodMutableByDeclarativePredicate( ) = requireNotNull(gettingFirstMethodMutableByDeclarativePredicateOrNull(*strings, predicate = predicate)) -class CompositionBuilder() { - val indexedMatcher = IndexedMatcher() +class DeclarativePredicateBuilder internal constructor() { + private val children = mutableListOf Boolean>() - var accessFlagsPredicate: (DeclarativePredicateBuilder.() -> Unit)? = null - var returnsPredicate: (DeclarativePredicateBuilder.() -> Unit)? = null - var parameterTypesPredicate: (DeclarativePredicateBuilder.() -> Unit)? = null - var instructionsPredicate: (context(MatchContext) DeclarativePredicateBuilder.() -> Unit)? = null - var customPredicate: (context(MatchContext) DeclarativePredicateBuilder.() -> Unit)? = null - - fun accessFlags(vararg flags: AccessFlags) { - accessFlagsPredicate = { predicate { accessFlags(*flags) } } + fun anyOf(block: DeclarativePredicateBuilder.() -> Unit) { + val child = DeclarativePredicateBuilder().apply(block) + children += { child.children.any { it() } } } - fun returns(returnType: String) { - returnsPredicate = { predicate { this.returnType.startsWith(returnType) } } + fun predicate(block: T.() -> Boolean) { + children += block } - fun parameterTypes(vararg parameterTypes: String) { - parameterTypesPredicate = { - predicate { - this.parameterTypes.size == parameterTypes.size && this.parameterTypes.zip(parameterTypes) - .all { (a, b) -> a.startsWith(b) } - } - } - } + fun all(target: T): Boolean = children.all { target.it() } + fun any(target: T): Boolean = children.all { target.it() } +} - fun instructions(build: context(MatchContext, Method) IndexedMatcher.() -> Unit) { - instructionsPredicate = { - predicate { - implementation { indexedMatcher(this@CompositionBuilder.hashCode(), instructions) { build() } } - } - } - } +fun firstMethodComposite( + predicate: + context(MatchContext, Method, IndexedMatcher) DeclarativePredicateBuilder.() -> Unit +) = with(indexedMatcher()) { Composition(indices = this.indices) { predicate() } } - fun custom(block: context(MatchContext) Method.() -> Boolean) { - customPredicate = { predicate { block() } } - } +fun DeclarativePredicateBuilder.accessFlags(vararg flags: AccessFlags) { + predicate { accessFlags(*flags) } +} +fun DeclarativePredicateBuilder.returns(returnType: String) { + predicate { this.returnType.startsWith(returnType) } +} - fun build() = Composition(indexedMatcher) { - accessFlagsPredicate?.invoke(this) - returnsPredicate?.invoke(this) - parameterTypesPredicate?.invoke(this) - with(contextOf()) { - instructionsPredicate?.invoke(this@with, this@Composition) - customPredicate?.invoke(this@with, this@Composition) - } - } +fun DeclarativePredicateBuilder.parameterTypes(vararg parameterTypes: String) = predicate { + this.parameterTypes.size == parameterTypes.size && this.parameterTypes.zip(parameterTypes) + .all { (a, b) -> a.startsWith(b) } +} + +context(_: MatchContext, indexedMatcher: IndexedMatcher) +fun DeclarativePredicateBuilder.instructions( + build: context(MatchContext, Method) IndexedMatcher.() -> Unit +) = predicate { implementation { indexedMatcher(indexedMatcher.hashCode(), instructions) { build() } } } + +context(_: MatchContext) +fun DeclarativePredicateBuilder.custom(block: context(MatchContext) Method.() -> Boolean) { + predicate { block() } } class Composition internal constructor( - private val indexedMatcher: IndexedMatcher, + val indices: List, predicate: context(MatchContext, Method) DeclarativePredicateBuilder.() -> Unit ) { val methodOrNull by gettingFirstMethodMutableByDeclarativePredicateOrNull(predicate) val method = requireNotNull(methodOrNull) - val indices get() = indexedMatcher.indices -} - -fun composeFirstMethod(predicate: CompositionBuilder.() -> Unit) = CompositionBuilder().apply(predicate).build() - -val methodComposition = composeFirstMethod { - accessFlags(AccessFlags.PUBLIC) - instructions { - head { opcode == Opcode.RETURN } - fun opcode(opcode: Opcode) = add { this.opcode == opcode } - opcode(Opcode.NOP) - } -} - -val patch by gettingBytecodePatch { - execute { - val mutableMethod = methodComposition.method - methodComposition.indices.first() // Opcode == return - - firstClassDef(mutableMethod.definingClass).methods - firstClassDefMutable { type == mutableMethod.definingClass } - firstClassDefByDeclarativePredicateOrNull { - anyOf { - predicate { type == mutableMethod.definingClass } - predicate { type == "Ltest;" } - } - } - } }