From c9371511b97b8a334f0e4221959823b87e251677 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Sat, 24 Jan 2026 19:55:52 +0100 Subject: [PATCH] suppress and other migratios --- .../kotlin/app/revanced/patcher/Matching.kt | 871 ++++++++++-------- 1 file changed, 487 insertions(+), 384 deletions(-) diff --git a/patcher/src/commonMain/kotlin/app/revanced/patcher/Matching.kt b/patcher/src/commonMain/kotlin/app/revanced/patcher/Matching.kt index 1459515..5aa1b0e 100644 --- a/patcher/src/commonMain/kotlin/app/revanced/patcher/Matching.kt +++ b/patcher/src/commonMain/kotlin/app/revanced/patcher/Matching.kt @@ -57,27 +57,44 @@ fun MethodImplementation.anyDebugItem(predicate: Predicate) = debugItems.an fun Iterable.anyInstruction(predicate: Predicate) = any(predicate) -typealias ClassDefPredicate = context(PredicateContext) ClassDef.() -> Boolean -typealias MethodPredicate = context(PredicateContext) Method.() -> Boolean -typealias BytecodePatchContextMethodPredicate = context(BytecodePatchContext, PredicateContext) Method.() -> Boolean -typealias BytecodePatchContextClassDefPredicate = context(BytecodePatchContext, PredicateContext) ClassDef.() -> Boolean +typealias ClassDefPredicate = context(PredicateContext) +ClassDef.() -> Boolean +typealias MethodPredicate = context(PredicateContext) +Method.() -> Boolean +typealias BytecodePatchContextMethodPredicate = context(BytecodePatchContext, PredicateContext) +Method.() -> Boolean +typealias BytecodePatchContextClassDefPredicate = context(BytecodePatchContext, PredicateContext) +ClassDef.() -> Boolean -inline fun PredicateContext.remember(key: Any, defaultValue: () -> V) = if (key in this) get(key) as V -else defaultValue().also { put(key, it) } +inline fun PredicateContext.remember( + key: Any, + defaultValue: () -> V, +) = if (key in this) { + get(key) as V +} else { + defaultValue().also { put(key, it) } +} private fun cachedReadOnlyProperty(block: BytecodePatchContext.(KProperty<*>) -> T) = object : ReadOnlyProperty { private val cache = HashMap(1) - override fun getValue(thisRef: BytecodePatchContext, property: KProperty<*>) = - if (thisRef in cache) cache.getValue(thisRef) - else cache.getOrPut(thisRef) { thisRef.block(property) } + override fun getValue( + thisRef: BytecodePatchContext, + property: KProperty<*>, + ) = if (thisRef in cache) { + cache.getValue(thisRef) + } else { + cache.getOrPut(thisRef) { thisRef.block(property) } + } } class MutablePredicateList internal constructor() : MutableList> by mutableListOf() -typealias DeclarativePredicate = context(PredicateContext) MutablePredicateList.() -> Unit -typealias BytecodePatchContextDeclarativePredicate = context(BytecodePatchContext, PredicateContext) MutablePredicateList.() -> Unit +typealias DeclarativePredicate = context(PredicateContext) +MutablePredicateList.() -> Unit +typealias BytecodePatchContextDeclarativePredicate = context(BytecodePatchContext, PredicateContext) +MutablePredicateList.() -> Unit fun T.declarativePredicate(build: Function>) = with(MutablePredicateList().apply(build)) { @@ -85,54 +102,52 @@ fun T.declarativePredicate(build: Function>) = } context(context: PredicateContext) -fun T.rememberDeclarativePredicate(key: Any, block: Function>) = - with(context.remember(key) { MutablePredicateList().apply(block) }) { - all(this@rememberDeclarativePredicate) - } +fun T.rememberDeclarativePredicate( + key: Any, + block: Function>, +) = with(context.remember(key) { MutablePredicateList().apply(block) }) { + all(this@rememberDeclarativePredicate) +} context(_: PredicateContext) -private fun T.rememberDeclarativePredicate( - predicate: DeclarativePredicate -) = rememberDeclarativePredicate("declarativePredicate") { predicate() } +private fun T.rememberDeclarativePredicate(predicate: DeclarativePredicate) = + rememberDeclarativePredicate("declarativePredicate") { predicate() } @JvmName("firstMethodOrNullInMethods") -fun Iterable.firstMethodOrNull( - methodReference: MethodReference -) = firstOrNull { MethodUtil.methodSignaturesMatch(methodReference, it) } +fun Iterable.firstMethodOrNull(methodReference: MethodReference) = + firstOrNull { MethodUtil.methodSignaturesMatch(methodReference, it) } @JvmName("firstMethodInMethods") -fun Iterable.firstMethod( - methodReference: MethodReference -) = requireNotNull(firstMethodOrNull(methodReference)) +fun Iterable.firstMethod(methodReference: MethodReference) = requireNotNull(firstMethodOrNull(methodReference)) @JvmName("firstMutableMethodOrNullInMethods") context(context: BytecodePatchContext) -fun Iterable.firstMutableMethodOrNull( - methodReference: MethodReference -) = firstMethodOrNull(methodReference)?.let { app.revanced.patcher.firstMutableMethod(it) } +fun Iterable.firstMutableMethodOrNull(methodReference: MethodReference) = + firstMethodOrNull(methodReference)?.let { app.revanced.patcher.firstMutableMethod(it) } @JvmName("firstMutableMethodInMethods") context(_: BytecodePatchContext) -fun Iterable.firstMutableMethod( - methodReference: MethodReference -) = requireNotNull(firstMutableMethodOrNull(methodReference)) +fun Iterable.firstMutableMethod(methodReference: MethodReference) = requireNotNull(firstMutableMethodOrNull(methodReference)) @JvmName("firstMethodOrNullInMethods") fun Iterable.firstMethodOrNull( vararg strings: String, predicate: MethodPredicate = { true }, -) = if (strings.isEmpty()) withPredicateContext { firstOrNull { it.predicate() } } -else withPredicateContext { - first { method -> - val instructions = method.instructionsOrNull ?: return@first false +) = if (strings.isEmpty()) { + withPredicateContext { firstOrNull { it.predicate() } } +} else { + withPredicateContext { + first { method -> + val instructions = method.instructionsOrNull ?: return@first false - // TODO: Check potential to optimize (Set or not). - // Maybe even use context maps, but the methods may not be present in the context yet. - val methodStrings = instructions.asSequence().mapNotNull { it.string }.toSet() + // TODO: Check potential to optimize (Set or not). + // Maybe even use context maps, but the methods may not be present in the context yet. + val methodStrings = instructions.asSequence().mapNotNull { it.string }.toSet() - if (strings.any { it !in methodStrings }) return@first false + if (strings.any { it !in methodStrings }) return@first false - method.predicate() + method.predicate() + } } } @@ -148,7 +163,8 @@ fun Iterable.firstMutableMethodOrNull( vararg strings: String, predicate: MethodPredicate = { true }, ) = firstMethodOrNull( - strings = strings, predicate + strings = strings, + predicate, )?.let { app.revanced.patcher.firstMutableMethod(it) } @JvmName("firstMutableMethodInMethods") @@ -160,65 +176,73 @@ fun Iterable.firstMutableMethod( @JvmName("firstMethodDeclarativelyOrNullInMethods") fun Iterable.firstMethodDeclarativelyOrNull( - vararg strings: String, predicate: DeclarativePredicate + vararg strings: String, + predicate: DeclarativePredicate = { }, ) = firstMethodOrNull(strings = strings) { rememberDeclarativePredicate(predicate) } @JvmName("firstMethodDeclarativelyInMethods") fun Iterable.firstMethodDeclaratively( - vararg strings: String, predicate: DeclarativePredicate + vararg strings: String, + predicate: DeclarativePredicate = { }, ) = requireNotNull(firstMethodDeclarativelyOrNull(strings = strings, predicate)) @JvmName("firstMutableMethodDeclarativelyOrNullInMethods") context(_: BytecodePatchContext) fun Iterable.firstMutableMethodDeclarativelyOrNull( - vararg strings: String, predicate: DeclarativePredicate + vararg strings: String, + predicate: DeclarativePredicate = { }, ) = firstMutableMethodOrNull(strings = strings) { rememberDeclarativePredicate(predicate) } @JvmName("firstMutableMethodDeclarativelyInMethods") context(_: BytecodePatchContext) fun Iterable.firstMutableMethodDeclaratively( - vararg strings: String, predicate: DeclarativePredicate + vararg strings: String, + predicate: DeclarativePredicate = { }, ) = requireNotNull(firstMutableMethodDeclarativelyOrNull(strings = strings, predicate)) - @JvmName("firstMethodOrNullInClassDefs") -fun Iterable.firstMethodOrNull( - methodReference: MethodReference -) = asSequence().flatMap { it.methods.asSequence() }.asIterable().firstMethodOrNull(methodReference) +fun Iterable.firstMethodOrNull(methodReference: MethodReference) = + asSequence().flatMap { it.methods.asSequence() }.asIterable().firstMethodOrNull(methodReference) @JvmName("firstMethodInClassDefs") -fun Iterable.firstMethod( - methodReference: MethodReference -) = requireNotNull(firstMethodOrNull(methodReference)) +fun Iterable.firstMethod(methodReference: MethodReference) = requireNotNull(firstMethodOrNull(methodReference)) @JvmName("firstMutableMethodOrNullInClassDefs") context(_: BytecodePatchContext) -fun Iterable.firstMutableMethodOrNull( - methodReference: MethodReference -) = asSequence().flatMap { it.methods.asSequence() }.asIterable().firstMutableMethodOrNull(methodReference) +fun Iterable.firstMutableMethodOrNull(methodReference: MethodReference) = + asSequence().flatMap { it.methods.asSequence() }.asIterable().firstMutableMethodOrNull(methodReference) @JvmName("firstMutableMethodInClassDefs") context(_: BytecodePatchContext) -fun Iterable.firstMutableMethod( - methodReference: MethodReference -) = requireNotNull(firstMutableMethodOrNull(methodReference)) +fun Iterable.firstMutableMethod(methodReference: MethodReference) = requireNotNull(firstMutableMethodOrNull(methodReference)) @JvmName("firstMethodOrNullInClassDefs") -fun Iterable.firstMethodOrNull( - predicate: MethodPredicate = { true }, -) = asSequence().flatMap { it.methods.asSequence() }.asIterable() - .firstMethodOrNull(strings = emptyArray(), predicate) +fun Iterable.firstMethodOrNull(predicate: MethodPredicate = { true }): Method? { + forEach { classDef -> + with(classDef) { + classDef.methods.firstMethodOrNull { predicate() }?.let { return it } + } + } + + return null +} @JvmName("firstMethodInClassDefs") -fun Iterable.firstMethod( - predicate: MethodPredicate = { true }, -) = requireNotNull(firstMethodOrNull(predicate)) +fun Iterable.firstMethod(predicate: MethodPredicate = { true }) = requireNotNull(firstMethodOrNull(predicate)) @JvmName("firstMethodOrNullInClassDefs") fun Iterable.firstMethodOrNull( vararg strings: String, predicate: MethodPredicate = { true }, -) = asSequence().flatMap { it.methods.asSequence() }.asIterable().firstMethodOrNull(strings = strings, predicate) +): Method? { + forEach { classDef -> + with(classDef) { + classDef.methods.firstMethodOrNull(strings = strings) { predicate() }?.let { return it } + } + } + + return null +} @JvmName("firstMethodInClassDefs") fun Iterable.firstMethod( @@ -232,7 +256,8 @@ fun Iterable.firstMutableMethodOrNull( vararg strings: String, predicate: MethodPredicate = { true }, ) = firstMethodOrNull( - strings = strings, predicate + strings = strings, + predicate, )?.let { app.revanced.patcher.firstMutableMethod(it) } @JvmName("firstMutableMethodInClassDefs") @@ -243,54 +268,47 @@ fun Iterable.firstMutableMethod( ) = requireNotNull(firstMutableMethodOrNull(strings = strings, predicate)) @JvmName("firstMethodDeclarativelyOrNullInClassDefs") -fun Iterable.firstMethodDeclarativelyOrNull( - predicate: DeclarativePredicate -) = firstMethodOrNull { rememberDeclarativePredicate(predicate) } +fun Iterable.firstMethodDeclarativelyOrNull(predicate: DeclarativePredicate) = + firstMethodOrNull { rememberDeclarativePredicate(predicate) } @JvmName("firstMethodDeclarativelyInClassDefs") -fun Iterable.firstMethodDeclaratively( - predicate: DeclarativePredicate -) = requireNotNull(firstMethodDeclarativelyOrNull(predicate)) +fun Iterable.firstMethodDeclaratively(predicate: DeclarativePredicate) = + requireNotNull(firstMethodDeclarativelyOrNull(predicate)) @JvmName("firstMethodDeclarativelyOrNullInClassDefs") context(context: BytecodePatchContext) fun Iterable.firstMethodDeclarativelyOrNull( - vararg strings: String, predicate: DeclarativePredicate + vararg strings: String, + predicate: DeclarativePredicate = { }, ) = firstMethodOrNull(strings = strings) { rememberDeclarativePredicate(predicate) } @JvmName("firstMethodDeclarativelyInClassDefs") context(context: BytecodePatchContext) fun Iterable.firstMethodDeclaratively( - vararg strings: String, predicate: DeclarativePredicate + vararg strings: String, + predicate: DeclarativePredicate = { }, ) = requireNotNull(firstMethodDeclarativelyOrNull(strings = strings, predicate)) @JvmName("firstMutableMethodDeclarativelyOrNullInClassDefs") context(context: BytecodePatchContext) fun Iterable.firstMutableMethodDeclarativelyOrNull( - vararg strings: String, predicate: DeclarativePredicate + vararg strings: String, + predicate: DeclarativePredicate = { }, ) = firstMutableMethodOrNull(strings = strings) { rememberDeclarativePredicate(predicate) } @JvmName("firstMethodOrNullInClassDef") -fun ClassDef.firstMethodOrNull( - methodReference: MethodReference -) = methods.firstMethodOrNull(methodReference) +fun ClassDef.firstMethodOrNull(methodReference: MethodReference) = methods.firstMethodOrNull(methodReference) @JvmName("firstMethodInClassDef") -fun ClassDef.firstMethod( - methodReference: MethodReference -) = requireNotNull(firstMethodOrNull(methodReference)) +fun ClassDef.firstMethod(methodReference: MethodReference) = requireNotNull(firstMethodOrNull(methodReference)) @JvmName("firstMutableMethodOrNullInClassDef") context(_: BytecodePatchContext) -fun ClassDef.firstMutableMethodOrNull( - methodReference: MethodReference -) = methods.firstMutableMethodOrNull(methodReference) +fun ClassDef.firstMutableMethodOrNull(methodReference: MethodReference) = methods.firstMutableMethodOrNull(methodReference) @JvmName("firstMutableMethodInClassDef") context(_: BytecodePatchContext) -fun ClassDef.firstMutableMethod( - methodReference: MethodReference -) = requireNotNull(firstMutableMethodOrNull(methodReference)) +fun ClassDef.firstMutableMethod(methodReference: MethodReference) = requireNotNull(firstMutableMethodOrNull(methodReference)) @JvmName("firstMethodOrNullInClassDef") fun ClassDef.firstMethodOrNull( @@ -320,119 +338,130 @@ fun ClassDef.firstMutableMethod( @JvmName("firstMethodDeclarativelyOrNullInClassDef") fun ClassDef.firstMethodDeclarativelyOrNull( - vararg strings: String, predicate: DeclarativePredicate + vararg strings: String, + predicate: DeclarativePredicate = { }, ) = methods.firstMethodDeclarativelyOrNull(strings = strings, predicate) @JvmName("firstMethodDeclarativelyInClassDef") fun ClassDef.firstMethodDeclaratively( - vararg strings: String, predicate: DeclarativePredicate + vararg strings: String, + predicate: DeclarativePredicate = { }, ) = requireNotNull(firstMethodDeclarativelyOrNull(strings = strings, predicate)) @JvmName("firstMutableMethodDeclarativelyOrNullInClassDef") context(_: BytecodePatchContext) fun ClassDef.firstMutableMethodDeclarativelyOrNull( - vararg strings: String, predicate: DeclarativePredicate + vararg strings: String, + predicate: DeclarativePredicate = { }, ) = methods.firstMutableMethodDeclarativelyOrNull(strings = strings, predicate) @JvmName("firstMutableMethodDeclarativelyInClassDef") context(_: BytecodePatchContext) fun ClassDef.firstMutableMethodDeclaratively( - vararg strings: String, predicate: DeclarativePredicate + vararg strings: String, + predicate: DeclarativePredicate = { }, ) = requireNotNull(firstMutableMethodDeclarativelyOrNull(strings = strings, predicate)) @JvmName("firstClassDefOrNullInClassDefs") fun Iterable.firstClassDefOrNull( - type: String? = null, predicate: ClassDefPredicate = { true } + type: String? = null, + predicate: ClassDefPredicate = { true }, ) = withPredicateContext { - if (type == null) firstOrNull { it.predicate() } - else firstOrNull { it.type == type && it.predicate() } + if (type == null) { + firstOrNull { it.predicate() } + } else { + firstOrNull { it.type == type && it.predicate() } + } } @JvmName("firstClassDefInClassDefs") fun Iterable.firstClassDef( - type: String? = null, predicate: ClassDefPredicate = { true } + type: String? = null, + predicate: ClassDefPredicate = { true }, ) = requireNotNull(firstClassDefOrNull(type, predicate)) @JvmName("firstMutableClassDefOrNullInClassDefs") context(context: BytecodePatchContext) fun Iterable.firstMutableClassDefOrNull( - type: String? = null, predicate: ClassDefPredicate = { true } -) = if (type == null) firstClassDefOrNull(type, predicate) -else { + type: String? = null, + predicate: ClassDefPredicate = { true }, +) = if (type == null) { + firstClassDefOrNull(type, predicate) +} else { context.classDefs[type].takeIf { withPredicateContext { it?.predicate() == true } } }?.let { context.classDefs.getOrReplaceMutable(it) } @JvmName("firstMutableClassDefInClassDefs") context(_: BytecodePatchContext) fun Iterable.firstMutableClassDef( - type: String? = null, predicate: ClassDefPredicate = { true } + type: String? = null, + predicate: ClassDefPredicate = { true }, ) = requireNotNull(firstMutableClassDefOrNull(type, predicate)) @JvmName("firstClassDefDeclarativelyOrNullInClassDefs") fun Iterable.firstClassDefDeclarativelyOrNull( - type: String? = null, predicate: DeclarativePredicate + type: String? = null, + predicate: DeclarativePredicate = { }, ) = firstClassDefOrNull(type) { rememberDeclarativePredicate(predicate) } @JvmName("firstClassDefDeclarativelyInClassDefs") fun Iterable.firstClassDefDeclaratively( - type: String? = null, predicate: DeclarativePredicate + type: String? = null, + predicate: DeclarativePredicate = { }, ) = requireNotNull(firstClassDefDeclarativelyOrNull(type, predicate)) @JvmName("firstMutableClassDefDeclarativelyOrNullInClassDefs") context(_: BytecodePatchContext) fun Iterable.firstMutableClassDefDeclarativelyOrNull( - type: String? = null, predicate: DeclarativePredicate + type: String? = null, + predicate: DeclarativePredicate = { }, ) = firstMutableClassDefOrNull(type) { rememberDeclarativePredicate(predicate) } @JvmName("firstMutableClassDefDeclarativelyInClassDefs") context(_: BytecodePatchContext) fun Iterable.firstMutableClassDefDeclaratively( - type: String? = null, predicate: DeclarativePredicate + type: String? = null, + predicate: DeclarativePredicate = { }, ) = requireNotNull(firstMutableClassDefDeclarativelyOrNull(type, predicate)) +context(_: BytecodePatchContext) +fun firstMethodOrNull(methodReference: MethodReference) = + firstClassDefOrNull(methodReference.definingClass)?.methods?.firstMethodOrNull(methodReference) context(_: BytecodePatchContext) -fun firstMethodOrNull( - methodReference: MethodReference -) = firstClassDefOrNull(methodReference.definingClass)?.methods?.firstMethodOrNull(methodReference) +fun firstMethod(method: MethodReference) = requireNotNull(firstMethodOrNull(method)) context(_: BytecodePatchContext) -fun firstMethod( - method: MethodReference -) = requireNotNull(firstMethodOrNull(method)) +fun firstMutableMethodOrNull(methodReference: MethodReference): MutableMethod? = + firstMutableClassDefOrNull(methodReference.definingClass)?.methods?.first { + MethodUtil.methodSignaturesMatch( + methodReference, + it, + ) + } context(_: BytecodePatchContext) -fun firstMutableMethodOrNull( - methodReference: MethodReference -): MutableMethod? = firstMutableClassDefOrNull(methodReference.definingClass)?.methods?.first { - MethodUtil.methodSignaturesMatch( - methodReference, it - ) -} - -context(_: BytecodePatchContext) -fun firstMutableMethod( - method: MethodReference -) = requireNotNull(firstMutableMethodOrNull(method)) +fun firstMutableMethod(method: MethodReference) = requireNotNull(firstMutableMethodOrNull(method)) context(context: BytecodePatchContext) fun firstMethodOrNull( vararg strings: String, predicate: MethodPredicate = { true }, -): Method? = withPredicateContext { - if (strings.isEmpty()) return context.classDefs.firstMethodOrNull(predicate) +): Method? = + withPredicateContext { + if (strings.isEmpty()) return context.classDefs.firstMethodOrNull(predicate) - // TODO: Get rid of duplicates, but this isn't needed for functionality. Perhaps worse performance-wise? - val strings = strings.toSet() + // TODO: Get rid of duplicates, but this isn't needed for functionality. Perhaps worse performance-wise? + val strings = strings.toSet() - val methodsWithStrings = strings.mapNotNull { context.classDefs.methodsByString[it] } - if (methodsWithStrings.size != strings.size) return null + val methodsWithStrings = strings.mapNotNull { context.classDefs.methodsByString[it] } + if (methodsWithStrings.size != strings.size) return null - return methodsWithStrings.minBy { it.size }.firstOrNull { method -> - val containsAllOtherStrings = methodsWithStrings.all { method in it } - containsAllOtherStrings && method.predicate() + return methodsWithStrings.minBy { it.size }.firstOrNull { method -> + val containsAllOtherStrings = methodsWithStrings.all { method in it } + containsAllOtherStrings && method.predicate() + } } -} context(_: BytecodePatchContext) fun firstMethod( @@ -450,24 +479,17 @@ fun firstMutableMethodOrNull( context(_: BytecodePatchContext) fun firstMutableMethod( - vararg strings: String, predicate: MethodPredicate = { true } + vararg strings: String, + predicate: MethodPredicate = { true }, ) = requireNotNull(firstMutableMethodOrNull(strings = strings, predicate)) -fun gettingFirstMethodOrNull( - method: MethodReference -) = cachedReadOnlyProperty { firstMethodOrNull(method) } +fun gettingFirstMethodOrNull(method: MethodReference) = cachedReadOnlyProperty { firstMethodOrNull(method) } -fun gettingFirstMethod( - method: MethodReference -) = cachedReadOnlyProperty { firstMethod(method) } +fun gettingFirstMethod(method: MethodReference) = cachedReadOnlyProperty { firstMethod(method) } -fun gettingFirstMutableMethodOrNull( - method: MethodReference -) = cachedReadOnlyProperty { firstMutableMethodOrNull(method) } +fun gettingFirstMutableMethodOrNull(method: MethodReference) = cachedReadOnlyProperty { firstMutableMethodOrNull(method) } -fun gettingFirstMutableMethod( - method: MethodReference -) = cachedReadOnlyProperty { firstMutableMethod(method) } +fun gettingFirstMutableMethod(method: MethodReference) = cachedReadOnlyProperty { firstMutableMethod(method) } fun gettingFirstMethodOrNull( vararg strings: String, @@ -491,242 +513,296 @@ fun gettingFirstMutableMethod( context(_: BytecodePatchContext) fun firstMethodDeclarativelyOrNull( - vararg strings: String, predicate: DeclarativePredicate = { } + vararg strings: String, + predicate: DeclarativePredicate = { }, ) = firstMethodOrNull(strings = strings) { rememberDeclarativePredicate(predicate) } context(_: BytecodePatchContext) fun firstMethodDeclaratively( - vararg strings: String, predicate: DeclarativePredicate = { } + vararg strings: String, + predicate: DeclarativePredicate = { }, ) = requireNotNull(firstMethodDeclarativelyOrNull(strings = strings, predicate)) context(_: BytecodePatchContext) fun firstMutableMethodDeclarativelyOrNull( - vararg strings: String, predicate: DeclarativePredicate = { } + vararg strings: String, + predicate: DeclarativePredicate = { }, ) = firstMutableMethodOrNull(strings = strings) { rememberDeclarativePredicate(predicate) } context(_: BytecodePatchContext) fun firstMutableMethodDeclaratively( - vararg strings: String, predicate: DeclarativePredicate = { } + vararg strings: String, + predicate: DeclarativePredicate = { }, ) = requireNotNull(firstMutableMethodDeclarativelyOrNull(strings = strings, predicate)) fun gettingFirstMethodDeclarativelyOrNull( - vararg strings: String, predicate: BytecodePatchContextDeclarativePredicate = { } + vararg strings: String, + predicate: BytecodePatchContextDeclarativePredicate = { }, ) = gettingFirstMethodOrNull(strings = strings) { rememberDeclarativePredicate { predicate() } } fun gettingFirstMethodDeclaratively( - vararg strings: String, predicate: BytecodePatchContextDeclarativePredicate = { } + vararg strings: String, + predicate: BytecodePatchContextDeclarativePredicate = { }, ) = gettingFirstMethod(strings = strings) { rememberDeclarativePredicate { predicate() } } fun gettingFirstMutableMethodDeclarativelyOrNull( - vararg strings: String, predicate: BytecodePatchContextDeclarativePredicate = { } + vararg strings: String, + predicate: BytecodePatchContextDeclarativePredicate = { }, ) = gettingFirstMutableMethodOrNull(strings = strings) { rememberDeclarativePredicate { predicate() } } fun gettingFirstMutableMethodDeclaratively( - vararg strings: String, predicate: BytecodePatchContextDeclarativePredicate = { } + vararg strings: String, + predicate: BytecodePatchContextDeclarativePredicate = { }, ) = gettingFirstMutableMethod(strings = strings) { rememberDeclarativePredicate { predicate() } } - context(context: BytecodePatchContext) fun firstClassDefOrNull( - type: String? = null, predicate: ClassDefPredicate = { true } -) = if (type == null) context.classDefs.firstClassDefOrNull(type, predicate) -else withPredicateContext { context.classDefs[type]?.takeIf { it.predicate() } } + type: String? = null, + predicate: ClassDefPredicate = { true }, +) = if (type == null) { + context.classDefs.firstClassDefOrNull(type, predicate) +} else { + withPredicateContext { context.classDefs[type]?.takeIf { it.predicate() } } +} context(_: BytecodePatchContext) fun firstClassDef( - type: String? = null, predicate: ClassDefPredicate = { true } + type: String? = null, + predicate: ClassDefPredicate = { true }, ) = requireNotNull(firstClassDefOrNull(type, predicate)) context(context: BytecodePatchContext) fun firstMutableClassDefOrNull( - type: String? = null, predicate: ClassDefPredicate = { true } + type: String? = null, + predicate: ClassDefPredicate = { true }, ) = firstClassDefOrNull(type, predicate)?.let { context.classDefs.getOrReplaceMutable(it) } context(_: BytecodePatchContext) fun firstMutableClassDef( - type: String? = null, predicate: ClassDefPredicate = { true } + type: String? = null, + predicate: ClassDefPredicate = { true }, ) = requireNotNull(firstMutableClassDefOrNull(type, predicate)) fun gettingFirstClassDefOrNull( - type: String? = null, predicate: BytecodePatchContextClassDefPredicate = { true } + type: String? = null, + predicate: BytecodePatchContextClassDefPredicate = { true }, ) = cachedReadOnlyProperty { firstClassDefOrNull(type) { predicate() } } fun gettingFirstClassDef( - type: String? = null, predicate: BytecodePatchContextClassDefPredicate = { true } + type: String? = null, + predicate: BytecodePatchContextClassDefPredicate = { true }, ) = cachedReadOnlyProperty { firstClassDef(type) { predicate() } } fun gettingFirstMutableClassDefOrNull( - type: String? = null, predicate: BytecodePatchContextClassDefPredicate = { true } + type: String? = null, + predicate: BytecodePatchContextClassDefPredicate = { true }, ) = cachedReadOnlyProperty { firstMutableClassDefOrNull(type) { predicate() } } fun gettingFirstMutableClassDef( - type: String? = null, predicate: BytecodePatchContextClassDefPredicate = { true } + type: String? = null, + predicate: BytecodePatchContextClassDefPredicate = { true }, ) = cachedReadOnlyProperty { firstMutableClassDef(type) { predicate() } } context(_: BytecodePatchContext) fun firstClassDefDeclarativelyOrNull( - type: String? = null, predicate: DeclarativePredicate = { } + type: String? = null, + predicate: DeclarativePredicate = { }, ) = firstClassDefOrNull(type) { rememberDeclarativePredicate(predicate) } context(_: BytecodePatchContext) fun firstClassDefDeclaratively( - type: String? = null, predicate: DeclarativePredicate = { } + type: String? = null, + predicate: DeclarativePredicate = { }, ) = firstClassDef(type) { rememberDeclarativePredicate(predicate) } context(_: BytecodePatchContext) fun firstMutableClassDefDeclarativelyOrNull( - type: String? = null, predicate: DeclarativePredicate = { } + type: String? = null, + predicate: DeclarativePredicate = { }, ) = firstMutableClassDefOrNull(type) { rememberDeclarativePredicate(predicate) } context(_: BytecodePatchContext) fun firstMutableClassDefDeclaratively( - type: String? = null, predicate: DeclarativePredicate = { } + type: String? = null, + predicate: DeclarativePredicate = { }, ) = firstMutableClassDef(type) { rememberDeclarativePredicate(predicate) } fun gettingFirstClassDefDeclarativelyOrNull( - type: String? = null, predicate: BytecodePatchContextDeclarativePredicate = { } + type: String? = null, + predicate: BytecodePatchContextDeclarativePredicate = { }, ) = gettingFirstClassDefOrNull { rememberDeclarativePredicate { predicate() } } fun gettingFirstClassDefDeclaratively( - type: String? = null, predicate: BytecodePatchContextDeclarativePredicate = { } + type: String? = null, + predicate: BytecodePatchContextDeclarativePredicate = { }, ) = gettingFirstClassDef { rememberDeclarativePredicate { predicate() } } fun gettingFirstMutableClassDefDeclarativelyOrNull( - type: String? = null, predicate: BytecodePatchContextDeclarativePredicate = { } + type: String? = null, + predicate: BytecodePatchContextDeclarativePredicate = { }, ) = gettingFirstMutableClassDefOrNull { rememberDeclarativePredicate { predicate() } } fun gettingFirstMutableClassDefDeclaratively( - type: String? = null, predicate: BytecodePatchContextDeclarativePredicate = { } + type: String? = null, + predicate: BytecodePatchContextDeclarativePredicate = { }, ) = gettingFirstMutableClassDef { rememberDeclarativePredicate { predicate() } } - class PredicateContext internal constructor() : MutableMap by mutableMapOf() private inline fun withPredicateContext(block: PredicateContext.() -> T) = PredicateContext().block() typealias IndexedMatcherPredicate = T.(lastMatchedIndex: Int, currentIndex: Int, setNextIndex: (Int?) -> Unit) -> Boolean -fun indexedMatcher(vararg items: IndexedMatcherPredicate) = IndexedMatcher().apply { - items.forEach { +it } -} +fun indexedMatcher(vararg items: IndexedMatcherPredicate) = + IndexedMatcher().apply { + items.forEach { +it } + } fun indexedMatcher(build: Function>) = IndexedMatcher().apply(build) fun Iterable.matchIndexed(build: Function>) = indexedMatcher(build)(this) context(_: PredicateContext) -fun Iterable.matchIndexed(key: Any, build: Function>) = - indexedMatcher()(key, this, build) +fun Iterable.matchIndexed( + key: Any, + build: Function>, +) = indexedMatcher()(key, this, build) context(_: PredicateContext) fun Iterable.matchIndexed( - key: Any, vararg items: IndexedMatcherPredicate + key: Any, + vararg items: IndexedMatcherPredicate, ) = indexedMatcher()(key, this) { items.forEach { +it } } -fun at(index: Int, predicate: IndexedMatcherPredicate): IndexedMatcherPredicate = +fun at( + index: Int, + predicate: IndexedMatcherPredicate, +): IndexedMatcherPredicate = { lastMatchedIndex, currentIndex, setNextIndex -> currentIndex == index && predicate(lastMatchedIndex, currentIndex, setNextIndex) } -fun at(index: Int, predicate: Predicate) = at(index) { _, _, _ -> predicate() } +fun at( + index: Int, + predicate: Predicate, +) = at(index) { _, _, _ -> predicate() } fun after( - range: IntRange = 1..1, predicate: IndexedMatcherPredicate -): IndexedMatcherPredicate = predicate@{ lastMatchedIndex, currentIndex, setNextIndex -> - val distance = currentIndex - lastMatchedIndex + range: IntRange = 1..1, + predicate: IndexedMatcherPredicate, +): IndexedMatcherPredicate = + predicate@{ lastMatchedIndex, currentIndex, setNextIndex -> + val distance = currentIndex - lastMatchedIndex - setNextIndex( - when { - distance < range.first -> lastMatchedIndex + range.first - distance > range.last -> -1 - else -> return@predicate predicate(lastMatchedIndex, currentIndex, setNextIndex) - } - ) + setNextIndex( + when { + distance < range.first -> lastMatchedIndex + range.first + distance > range.last -> -1 + else -> return@predicate predicate(lastMatchedIndex, currentIndex, setNextIndex) + }, + ) - false -} + false + } -fun after(range: IntRange = 1..1, predicate: Predicate) = after(range) { _, _, _ -> predicate() } +fun after( + range: IntRange = 1..1, + predicate: Predicate, +) = after(range) { _, _, _ -> predicate() } -fun after(predicate: IndexedMatcherPredicate) = after(1..1) { lastMatchedIndex, currentIndex, setNextIndex -> - predicate(lastMatchedIndex, currentIndex, setNextIndex) -} +fun after(predicate: IndexedMatcherPredicate) = + after(1..1) { lastMatchedIndex, currentIndex, setNextIndex -> + predicate(lastMatchedIndex, currentIndex, setNextIndex) + } fun after(predicate: Predicate) = after { _, _, _ -> predicate() } -fun afterAtLeast(steps: Int = 1, predicate: IndexedMatcherPredicate) = - after(steps..steps) { lastMatchedIndex, currentIndex, setNextIndex -> - predicate(lastMatchedIndex, currentIndex, setNextIndex) - } - -fun afterAtLeast(steps: Int = 1, predicate: Predicate) = - after(steps..Int.MAX_VALUE) { _, _, _ -> predicate() } - -fun afterAtMost(steps: Int = 1, predicate: IndexedMatcherPredicate) = - after(1..steps) { lastMatchedIndex, currentIndex, setNextIndex -> - predicate(lastMatchedIndex, currentIndex, setNextIndex) - } - -fun afterAtMost(steps: Int = 1, predicate: Predicate) = after(1..steps) { _, _, _ -> predicate() } - -fun after(steps: Int = 1, predicate: IndexedMatcherPredicate) = - after(steps..steps) { lastMatchedIndex, currentIndex, setNextIndex -> - predicate(lastMatchedIndex, currentIndex, setNextIndex) - } - -fun after(steps: Int = 1, predicate: Predicate) = after(steps..steps) { _, _, _ -> predicate() } - -fun anyOf( - vararg predicates: IndexedMatcherPredicate -): IndexedMatcherPredicate = { currentIndex, lastMatchedIndex, setNextIndex -> - predicates.any { predicate -> predicate(currentIndex, lastMatchedIndex, setNextIndex) } +fun afterAtLeast( + steps: Int = 1, + predicate: IndexedMatcherPredicate, +) = after(steps..steps) { lastMatchedIndex, currentIndex, setNextIndex -> + predicate(lastMatchedIndex, currentIndex, setNextIndex) } -fun allOf( - vararg predicates: IndexedMatcherPredicate -): IndexedMatcherPredicate = { currentIndex, lastMatchedIndex, setNextIndex -> - predicates.all { predicate -> predicate(currentIndex, lastMatchedIndex, setNextIndex) } +fun afterAtLeast( + steps: Int = 1, + predicate: Predicate, +) = after(steps..Int.MAX_VALUE) { _, _, _ -> predicate() } + +fun afterAtMost( + steps: Int = 1, + predicate: IndexedMatcherPredicate, +) = after(1..steps) { lastMatchedIndex, currentIndex, setNextIndex -> + predicate(lastMatchedIndex, currentIndex, setNextIndex) } -fun noneOf( - vararg predicates: IndexedMatcherPredicate -): IndexedMatcherPredicate = { currentIndex, lastMatchedIndex, setNextIndex -> - predicates.none { predicate -> predicate(currentIndex, lastMatchedIndex, setNextIndex) } +fun afterAtMost( + steps: Int = 1, + predicate: Predicate, +) = after(1..steps) { _, _, _ -> predicate() } + +fun after( + steps: Int = 1, + predicate: IndexedMatcherPredicate, +) = after(steps..steps) { lastMatchedIndex, currentIndex, setNextIndex -> + predicate(lastMatchedIndex, currentIndex, setNextIndex) } +fun after( + steps: Int = 1, + predicate: Predicate, +) = after(steps..steps) { _, _, _ -> predicate() } + +fun anyOf(vararg predicates: IndexedMatcherPredicate): IndexedMatcherPredicate = + { currentIndex, lastMatchedIndex, setNextIndex -> + predicates.any { predicate -> predicate(currentIndex, lastMatchedIndex, setNextIndex) } + } + +fun allOf(vararg predicates: IndexedMatcherPredicate): IndexedMatcherPredicate = + { currentIndex, lastMatchedIndex, setNextIndex -> + predicates.all { predicate -> predicate(currentIndex, lastMatchedIndex, setNextIndex) } + } + +fun noneOf(vararg predicates: IndexedMatcherPredicate): IndexedMatcherPredicate = + { currentIndex, lastMatchedIndex, setNextIndex -> + predicates.none { predicate -> predicate(currentIndex, lastMatchedIndex, setNextIndex) } + } + fun unorderedAllOf(vararg predicates: IndexedMatcherPredicate): Array> { // Track which predicate index was used. val usedPredicateIndices = mutableListOf() var lastPatternIndex = -1 - return (0 until predicates.size).map> { patternIndex -> - predicate@{ lastMatchedIndex, currentIndex, setNextIndex -> - // Detect backtracking: if revisiting an earlier pattern position, truncate the list to that position. - if (patternIndex <= lastPatternIndex) { - while (usedPredicateIndices.size > patternIndex) { - usedPredicateIndices.removeLast() + return (0 until predicates.size) + .map> { patternIndex -> + predicate@{ lastMatchedIndex, currentIndex, setNextIndex -> + // Detect backtracking: if revisiting an earlier pattern position, truncate the list to that position. + if (patternIndex <= lastPatternIndex) { + while (usedPredicateIndices.size > patternIndex) { + usedPredicateIndices.removeLast() + } } - } - lastPatternIndex = patternIndex + lastPatternIndex = patternIndex - // Try each unused predicate - for (predicateIndex in predicates.indices) { - if (predicateIndex in usedPredicateIndices) continue + // Try each unused predicate + for (predicateIndex in predicates.indices) { + if (predicateIndex in usedPredicateIndices) continue - if (predicates[predicateIndex](lastMatchedIndex, currentIndex) { nextIndex -> - // Backtracking is not possible in an unordered matcher. - // If backtracking is requested, just set to max value to end searching. - if (nextIndex != -1) setNextIndex(Int.MAX_VALUE) - }) { - usedPredicateIndices += predicateIndex - return@predicate true + if (predicates[predicateIndex](lastMatchedIndex, currentIndex) { nextIndex -> + // Backtracking is not possible in an unordered matcher. + // If backtracking is requested, just set to max value to end searching. + if (nextIndex != -1) setNextIndex(Int.MAX_VALUE) + } + ) { + usedPredicateIndices += predicateIndex + return@predicate true + } } - } - false - } - }.toTypedArray() + false + } + }.toTypedArray() } class IndexedMatcher : Matcher>() { @@ -750,14 +826,18 @@ class IndexedMatcher : Matcher>() { val lastMatchedIndex: Int, val previousFrame: Frame?, var nextHayIndex: Int, - val matchedIndex: Int + val matchedIndex: Int, ) val stack = ArrayDeque() stack.add( Frame( - patternIndex = 0, lastMatchedIndex = -1, previousFrame = null, nextHayIndex = 0, matchedIndex = -1 - ) + patternIndex = 0, + lastMatchedIndex = -1, + previousFrame = null, + nextHayIndex = 0, + matchedIndex = -1, + ), ) while (stack.isNotEmpty()) { @@ -780,27 +860,32 @@ class IndexedMatcher : Matcher>() { lastMatchedIndex = i, previousFrame = frame, nextHayIndex = i + 1, - matchedIndex = i + matchedIndex = i, ).also { if (it.patternIndex == size) { - indices += buildList(size) { - var frame: Frame? = it - while (frame != null && frame.matchedIndex != -1) { - add(frame.matchedIndex) - frame = frame.previousFrame - } - }.asReversed() + indices += + buildList(size) { + var frame: Frame? = it + while (frame != null && frame.matchedIndex != -1) { + add(frame.matchedIndex) + frame = frame.previousFrame + } + }.asReversed() return true } }.let(stack::add) } - frame.nextHayIndex = when (val nextIndex = nextIndex) { - null -> frame.nextHayIndex + 1 - -1 -> 0 // Frame will be removed next loop. - else -> nextIndex - } + frame.nextHayIndex = + when (val nextIndex = nextIndex) { + null -> frame.nextHayIndex + 1 + + -1 -> 0 + + // Frame will be removed next loop. + else -> nextIndex + } } return false @@ -814,7 +899,9 @@ operator fun > U.unaryPlus() = matcher.add(this) context(context: PredicateContext) inline operator fun > M.invoke( - key: Any, iterable: Iterable, builder: Function + key: Any, + iterable: Iterable, + builder: Function, ) = context.remember(key) { apply(builder) }(iterable) abstract class Matcher : MutableList by mutableListOf() { @@ -853,205 +940,217 @@ fun MutablePredicateList.any(target: T): Boolean = any { target.it() } fun MutablePredicateList.accessFlags(vararg flags: AccessFlags) = predicate { accessFlags(flags = flags) } -fun MutablePredicateList.returnType( - predicate: Predicate -) = predicate { returnType.predicate() } +fun MutablePredicateList.returnType(predicate: Predicate) = predicate { returnType.predicate() } fun MutablePredicateList.returnType( - returnType: String, compare: String.(String) -> Boolean = String::startsWith + returnType: String, + compare: String.(String) -> Boolean = String::startsWith, ) = predicate { this.returnType.compare(returnType) } -fun MutablePredicateList.name( - predicate: Predicate -) = predicate { name.predicate() } +fun MutablePredicateList.name(predicate: Predicate) = predicate { name.predicate() } fun MutablePredicateList.name( - name: String, compare: String.(String) -> Boolean = String::equals + name: String, + compare: String.(String) -> Boolean = String::equals, ) = predicate { this.name.compare(name) } -fun MutablePredicateList.definingClass( - predicate: Predicate -) = predicate { definingClass.predicate() } +fun MutablePredicateList.definingClass(predicate: Predicate) = predicate { definingClass.predicate() } fun MutablePredicateList.definingClass( - definingClass: String, compare: String.(String) -> Boolean = String::equals + definingClass: String, + compare: String.(String) -> Boolean = String::equals, ) = predicate { this.definingClass.compare(definingClass) } -fun MutablePredicateList.parameterTypes(vararg parameterTypePrefixes: String) = predicate { - parameterTypes.size == parameterTypePrefixes.size && parameterTypes.zip(parameterTypePrefixes) - .all { (a, b) -> a.startsWith(b) } -} +fun MutablePredicateList.parameterTypes(vararg parameterTypePrefixes: String) = + predicate { + parameterTypes.size == parameterTypePrefixes.size && + parameterTypes + .zip(parameterTypePrefixes) + .all { (a, b) -> a.startsWith(b) } + } -fun MutablePredicateList.strings( - build: Function> -) { +fun MutablePredicateList.strings(build: Function>) { val match = indexedMatcher(build) predicate { implementation { match(instructions) } } } context(matcher: IndexedMatcher) -fun MutablePredicateList.strings( - build: Function> -) { +fun MutablePredicateList.strings(build: Function>) { matcher.build() predicate { implementation { matcher(instructions) } } } -//fun MutablePredicateList.strings( +// fun MutablePredicateList.strings( // vararg predicates: IndexedMatcherPredicate -//) = strings { predicates.forEach { +it } } +// ) = strings { predicates.forEach { +it } } // -//context(matcher: IndexedMatcher) -//fun MutablePredicateList.strings( +// context(matcher: IndexedMatcher) +// fun MutablePredicateList.strings( // vararg predicates: IndexedMatcherPredicate -//) = strings { predicates.forEach { +it } } +// ) = strings { predicates.forEach { +it } } // // -//fun MutablePredicateList.strings( +// fun MutablePredicateList.strings( // vararg strings: String -//) = strings(predicates = strings.map { string(it) }.toTypedArray()) +// ) = strings(predicates = strings.map { string(it) }.toTypedArray()) // -//context( +// context( // stringsList: MutableList, // matcher: IndexedMatcherPredicate) -//fun MutablePredicateList.strings( +// fun MutablePredicateList.strings( // vararg strings: String -//) { +// ) { // stringsList += strings // // strings(predicates = strings.map { string(it) }.toTypedArray()) -//} +// } -fun MutablePredicateList.instructions( - build: Function> -) { +fun MutablePredicateList.instructions(build: Function>) { val match = indexedMatcher(build) predicate { implementation { match(instructions) } } } -fun MutablePredicateList.instructions( - vararg predicates: IndexedMatcherPredicate -) = instructions { - predicates.forEach { +it } -} +fun MutablePredicateList.instructions(vararg predicates: IndexedMatcherPredicate) = + instructions { + predicates.forEach { +it } + } context(matcher: IndexedMatcher) -fun MutablePredicateList.instructions( - build: Function> -) { +fun MutablePredicateList.instructions(build: Function>) { matcher.build() predicate { implementation { matcher(instructions) } } } context(matcher: IndexedMatcher) -fun MutablePredicateList.instructions( - vararg predicates: IndexedMatcherPredicate -) = instructions { predicates.forEach { +it } } +fun MutablePredicateList.instructions(vararg predicates: IndexedMatcherPredicate) = + instructions { predicates.forEach { +it } } -fun MutablePredicateList.instructions( - vararg predicates: Predicate -) = instructions { predicates.forEach { add { _, _, _ -> it() } } } +fun MutablePredicateList.instructions(vararg predicates: Predicate) = + instructions { predicates.forEach { add { _, _, _ -> it() } } } fun MutablePredicateList.custom(block: Predicate) { predicate { block() } } -fun MutablePredicateList.opcodes( - vararg opcodes: Opcode -) = instructions { opcodes.forEach { +it() } } +fun MutablePredicateList.opcodes(vararg opcodes: Opcode) = instructions { opcodes.forEach { +it() } } context(matcher: IndexedMatcher) -fun MutablePredicateList.opcodes( - vararg opcodes: Opcode -) = instructions { opcodes.forEach { +it() } } +fun MutablePredicateList.opcodes(vararg opcodes: Opcode) = instructions { opcodes.forEach { +it() } } -inline fun `is`( - crossinline predicate: Predicate = { true } -): IndexedMatcherPredicate = { _, _, _ -> (this as? T)?.predicate() == true } +inline fun `is`(crossinline predicate: Predicate = { true }): IndexedMatcherPredicate = + { _, _, _ -> (this as? T)?.predicate() == true } -fun instruction(predicate: Predicate = { true }): IndexedMatcherPredicate = - { _, _, _ -> predicate() } +fun instruction(predicate: Predicate = { true }): IndexedMatcherPredicate = { _, _, _ -> predicate() } -fun registers(predicate: Predicate = { true }): IndexedMatcherPredicate = { _, _, _ -> - when (this) { - is RegisterRangeInstruction -> IntArray(registerCount) { startRegister + it }.predicate() +fun registers(predicate: Predicate = { true }): IndexedMatcherPredicate = + { _, _, _ -> + when (this) { + is RegisterRangeInstruction -> { + IntArray(registerCount) { startRegister + it }.predicate() + } - is FiveRegisterInstruction -> intArrayOf( - registerC, - registerD, - registerE, - registerF, - registerG - ).predicate() + is FiveRegisterInstruction -> { + intArrayOf( + registerC, + registerD, + registerE, + registerF, + registerG, + ).predicate() + } - is ThreeRegisterInstruction -> intArrayOf(registerA, registerB, registerC).predicate() + is ThreeRegisterInstruction -> { + intArrayOf(registerA, registerB, registerC).predicate() + } - is TwoRegisterInstruction -> intArrayOf(registerA, registerB).predicate() + is TwoRegisterInstruction -> { + intArrayOf(registerA, registerB).predicate() + } - is OneRegisterInstruction -> intArrayOf(registerA).predicate() + is OneRegisterInstruction -> { + intArrayOf(registerA).predicate() + } - else -> false + else -> { + false + } + } } -} fun registers( - vararg registers: Int, compare: IntArray.(registers: IntArray) -> Boolean = { registers -> + vararg registers: Int, + compare: IntArray.(registers: IntArray) -> Boolean = { registers -> this.size >= registers.size && registers.indices.all { this[it] == registers[it] } - } + }, ) = registers({ compare(registers) }) -fun literal(predicate: Predicate = { true }): IndexedMatcherPredicate = - { _, _, _ -> wideLiteral?.predicate() == true } +fun literal(predicate: Predicate = { true }): IndexedMatcherPredicate = { _, _, _ -> wideLiteral?.predicate() == true } -fun literal(literal: Long, compare: Long.(Long) -> Boolean = Long::equals) = literal { compare(literal) } +fun literal( + literal: Long, + compare: Long.(Long) -> Boolean = Long::equals, +) = literal { compare(literal) } operator fun Long.invoke(compare: Long.(Long) -> Boolean = Long::equals) = literal(this, compare) -inline fun reference( - crossinline predicate: Predicate = { true } -): IndexedMatcherPredicate = { _, _, _ -> (reference as? T)?.predicate() == true } +inline fun reference(crossinline predicate: Predicate = { true }): IndexedMatcherPredicate = + { _, _, _ -> (reference as? T)?.predicate() == true } fun reference( - reference: String, compare: String.(String) -> Boolean = String::equals + reference: String, + compare: String.(String) -> Boolean = String::equals, ): IndexedMatcherPredicate = { _, _, _ -> this.reference?.toString()?.compare(reference) == true } -fun field(predicate: Predicate = { true }): IndexedMatcherPredicate = { _, _, _ -> - fieldReference?.predicate() == true -} +fun field(predicate: Predicate = { true }): IndexedMatcherPredicate = + { _, _, _ -> + fieldReference?.predicate() == true + } -fun field(name: String, compare: String.(String) -> Boolean = String::equals) = - field { this.name.compare(name) } +fun field( + name: String, + compare: String.(String) -> Boolean = String::equals, +) = field { this.name.compare(name) } -fun type(predicate: Predicate = { true }): IndexedMatcherPredicate = - { _, _, _ -> type?.predicate() == true } +fun type(predicate: Predicate = { true }): IndexedMatcherPredicate = { _, _, _ -> type?.predicate() == true } -fun type(type: String, compare: String.(type: String) -> Boolean = String::equals) = type { compare(type) } +fun type( + type: String, + compare: String.(type: String) -> Boolean = String::equals, +) = type { compare(type) } -fun method(predicate: Predicate = { true }): IndexedMatcherPredicate = { _, _, _ -> - methodReference?.predicate() == true -} +fun method(predicate: Predicate = { true }): IndexedMatcherPredicate = + { _, _, _ -> + methodReference?.predicate() == true + } -fun method(name: String, compare: String.(String) -> Boolean = String::equals) = - method { this.name.compare(name) } +fun method( + name: String, + compare: String.(String) -> Boolean = String::equals, +) = method { this.name.compare(name) } -fun string(predicate: Predicate = { true }): IndexedMatcherPredicate = { _, _, _ -> - string?.predicate() == true -} +fun string(predicate: Predicate = { true }): IndexedMatcherPredicate = + { _, _, _ -> + string?.predicate() == true + } context(stringsList: MutableList) fun string( - string: String, compare: String.(String) -> Boolean = String::equals + string: String, + compare: String.(String) -> Boolean = String::equals, ): IndexedMatcherPredicate { if (compare == String::equals) stringsList += string return string { compare(string) } } -fun string(string: String, compare: String.(String) -> Boolean = String::equals) = string { compare(string) } +fun string( + string: String, + compare: String.(String) -> Boolean = String::equals, +) = string { compare(string) } operator fun String.invoke(compare: String.(String) -> Boolean = String::equals) = string(this, compare) @@ -1060,28 +1159,28 @@ operator fun String.invoke(compare: String.(String) -> Boolean = String::equals) operator fun Opcode.invoke(): IndexedMatcherPredicate = { _, _, _ -> opcode == this@invoke } - typealias BuildCompositeDeclarativePredicate = - context( + context( BytecodePatchContext, PredicateContext, IndexedMatcher, MutableList - ) - MutablePredicateList.() -> Unit + ) + MutablePredicateList.() -> Unit fun firstMethodComposite( - vararg strings: String, build: BuildCompositeDeclarativePredicate + vararg strings: String, + build: BuildCompositeDeclarativePredicate = { }, ) = MatchBuilder(strings = strings, build) class MatchBuilder private constructor( private val strings: MutableList, indexedMatcher: IndexedMatcher = indexedMatcher(), - build: BuildCompositeDeclarativePredicate, + build: BuildCompositeDeclarativePredicate = { }, ) { - internal constructor( - vararg strings: String, build: BuildCompositeDeclarativePredicate + vararg strings: String, + build: BuildCompositeDeclarativePredicate = { }, ) : this(strings = mutableListOf(elements = strings), build = build) private val predicate: BytecodePatchContextDeclarativePredicate = { @@ -1091,7 +1190,8 @@ class MatchBuilder private constructor( val indices = indexedMatcher.indices private val BytecodePatchContext.cachedImmutableMethodOrNull by gettingFirstMethodDeclarativelyOrNull( - strings = strings.toTypedArray(), predicate + strings = strings.toTypedArray(), + predicate, ) private val BytecodePatchContext.cachedImmutableClassDefOrNull by cachedReadOnlyProperty { @@ -1133,9 +1233,12 @@ class MatchBuilder private constructor( val classDef get() = requireNotNull(classDefOrNull) context(context: BytecodePatchContext) - fun match(classDef: ClassDef) = Match( - context, classDef.firstMethodDeclarativelyOrNull { predicate() }, indices - ) + fun match(classDef: ClassDef) = + Match( + context, + classDef.firstMethodDeclarativelyOrNull { predicate() }, + indices, + ) } class Match(