mirror of
https://github.com/ReVanced/revanced-patcher.git
synced 2024-11-10 01:02:22 +01:00
feat: Add constructor to initialize patches without annotations
This commit is contained in:
parent
7aeae93f3d
commit
462fbe2cad
7 changed files with 154 additions and 24 deletions
|
@ -234,11 +234,14 @@ public abstract interface annotation class app/revanced/patcher/fingerprint/anno
|
|||
|
||||
public abstract class app/revanced/patcher/patch/BytecodePatch : app/revanced/patcher/patch/Patch {
|
||||
public fun <init> ()V
|
||||
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;Ljava/util/Set;ZZLjava/util/Set;)V
|
||||
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;Ljava/util/Set;ZZLjava/util/Set;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||
public fun <init> (Ljava/util/Set;)V
|
||||
public synthetic fun <init> (Ljava/util/Set;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||
}
|
||||
|
||||
public abstract class app/revanced/patcher/patch/Patch {
|
||||
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;Ljava/util/Set;ZZLkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||
public fun equals (Ljava/lang/Object;)Z
|
||||
public abstract fun execute (Lapp/revanced/patcher/data/Context;)V
|
||||
public final fun getCompatiblePackages ()Ljava/util/Set;
|
||||
|
@ -272,6 +275,8 @@ public final class app/revanced/patcher/patch/PatchResult {
|
|||
|
||||
public abstract class app/revanced/patcher/patch/ResourcePatch : app/revanced/patcher/patch/Patch {
|
||||
public fun <init> ()V
|
||||
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;Ljava/util/Set;ZZ)V
|
||||
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;Ljava/util/Set;ZZILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||
}
|
||||
|
||||
public abstract interface annotation class app/revanced/patcher/patch/annotation/CompatiblePackage : java/lang/annotation/Annotation {
|
||||
|
|
|
@ -12,6 +12,7 @@ import java.util.jar.JarFile
|
|||
import java.util.logging.Logger
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
|
||||
/**
|
||||
* A set of [Patch]es.
|
||||
*/
|
||||
|
@ -73,7 +74,7 @@ sealed class PatchBundleLoader private constructor(
|
|||
if (!silent) {
|
||||
logger.fine(
|
||||
"Patch class '$name' has no INSTANCE field, therefor not a singleton. " +
|
||||
"Will try to instantiate it.",
|
||||
"Attempting to instantiate it.",
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -83,7 +84,7 @@ sealed class PatchBundleLoader private constructor(
|
|||
if (!silent) {
|
||||
logger.severe(
|
||||
"Patch class '$name' is not singleton and has no suitable constructor, " +
|
||||
"therefor cannot be instantiated and will be ignored.",
|
||||
"therefor cannot be instantiated and is ignored.",
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,13 +1,61 @@
|
|||
package app.revanced.patcher.patch
|
||||
|
||||
import app.revanced.patcher.PatchClass
|
||||
import app.revanced.patcher.Patcher
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import java.io.Closeable
|
||||
|
||||
/**
|
||||
* A ReVanced [Patch] that works on [BytecodeContext].
|
||||
* A ReVanced [Patch] that accesses a [BytecodeContext].
|
||||
*
|
||||
* @param fingerprints A list of [MethodFingerprint]s which will be resolved before the patch is executed.
|
||||
* If an implementation of [Patch] also implements [Closeable]
|
||||
* it will be closed in reverse execution order of patches executed by ReVanced [Patcher].
|
||||
*/
|
||||
abstract class BytecodePatch(
|
||||
internal val fingerprints: Set<MethodFingerprint> = emptySet(),
|
||||
) : Patch<BytecodeContext>()
|
||||
@Suppress("unused")
|
||||
abstract class BytecodePatch : Patch<BytecodeContext> {
|
||||
/**
|
||||
* The fingerprints to resolve before executing the patch.
|
||||
*/
|
||||
internal val fingerprints: Set<MethodFingerprint>
|
||||
|
||||
/**
|
||||
* Create a new [BytecodePatch].
|
||||
*
|
||||
* @param fingerprints The fingerprints to resolve before executing the patch.
|
||||
*/
|
||||
constructor(fingerprints: Set<MethodFingerprint> = emptySet()) {
|
||||
this.fingerprints = fingerprints
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new [BytecodePatch].
|
||||
*
|
||||
* @param name The name of the patch.
|
||||
* @param description The description of the patch.
|
||||
* @param compatiblePackages The packages the patch is compatible with.
|
||||
* @param dependencies Other patches this patch depends on.
|
||||
* @param use Weather or not the patch should be used.
|
||||
* @param requiresIntegrations Weather or not the patch requires integrations.
|
||||
*/
|
||||
constructor(
|
||||
name: String? = null,
|
||||
description: String? = null,
|
||||
compatiblePackages: Set<CompatiblePackage>? = null,
|
||||
dependencies: Set<PatchClass>? = null,
|
||||
use: Boolean = true,
|
||||
requiresIntegrations: Boolean = false,
|
||||
fingerprints: Set<MethodFingerprint> = emptySet(),
|
||||
) : super(name, description, compatiblePackages, dependencies, use, requiresIntegrations) {
|
||||
this.fingerprints = fingerprints
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new [BytecodePatch].
|
||||
*/
|
||||
@Deprecated(
|
||||
"Use the constructor with fingerprints instead.",
|
||||
ReplaceWith("BytecodePatch(emptySet())"),
|
||||
)
|
||||
constructor() : this(emptySet())
|
||||
}
|
||||
|
|
|
@ -8,10 +8,10 @@ import app.revanced.patcher.data.Context
|
|||
import app.revanced.patcher.extensions.AnnotationExtensions.findAnnotationRecursively
|
||||
import app.revanced.patcher.patch.options.PatchOptions
|
||||
import java.io.Closeable
|
||||
import app.revanced.patcher.patch.annotation.Patch as PatchAnnotation
|
||||
|
||||
/**
|
||||
* A ReVanced patch.
|
||||
*
|
||||
* If an implementation of [Patch] also implements [Closeable]
|
||||
* it will be closed in reverse execution order of patches executed by ReVanced [Patcher].
|
||||
*
|
||||
|
@ -55,25 +55,41 @@ sealed class Patch<out T : Context<*>> {
|
|||
var requiresIntegrations = false
|
||||
private set
|
||||
|
||||
constructor(
|
||||
name: String?,
|
||||
description: String?,
|
||||
compatiblePackages: Set<CompatiblePackage>?,
|
||||
dependencies: Set<PatchClass>?,
|
||||
use: Boolean,
|
||||
requiresIntegrations: Boolean,
|
||||
) {
|
||||
this.name = name
|
||||
this.description = description
|
||||
this.compatiblePackages = compatiblePackages
|
||||
this.dependencies = dependencies
|
||||
this.use = use
|
||||
this.requiresIntegrations = requiresIntegrations
|
||||
}
|
||||
|
||||
constructor() {
|
||||
this::class.findAnnotationRecursively(app.revanced.patcher.patch.annotation.Patch::class)?.let { annotation ->
|
||||
this.name = annotation.name.ifEmpty { null }
|
||||
this.description = annotation.description.ifEmpty { null }
|
||||
this.compatiblePackages =
|
||||
annotation.compatiblePackages
|
||||
.map { CompatiblePackage(it.name, it.versions.toSet().ifEmpty { null }) }
|
||||
.toSet().ifEmpty { null }
|
||||
this.dependencies = annotation.dependencies.toSet().ifEmpty { null }
|
||||
this.use = annotation.use
|
||||
this.requiresIntegrations = annotation.requiresIntegrations
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The options of the patch associated by the options key.
|
||||
*/
|
||||
val options = PatchOptions()
|
||||
|
||||
init {
|
||||
this::class.findAnnotationRecursively(PatchAnnotation::class)?.let { annotation ->
|
||||
name = annotation.name.ifEmpty { null }
|
||||
description = annotation.description.ifEmpty { null }
|
||||
compatiblePackages =
|
||||
annotation.compatiblePackages
|
||||
.map { CompatiblePackage(it.name, it.versions.toSet().ifEmpty { null }) }
|
||||
.toSet().ifEmpty { null }
|
||||
dependencies = annotation.dependencies.toSet().ifEmpty { null }
|
||||
use = annotation.use
|
||||
requiresIntegrations = annotation.requiresIntegrations
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The execution function of the patch.
|
||||
*
|
||||
|
|
|
@ -1,8 +1,38 @@
|
|||
package app.revanced.patcher.patch
|
||||
|
||||
import app.revanced.patcher.PatchClass
|
||||
import app.revanced.patcher.Patcher
|
||||
import app.revanced.patcher.data.ResourceContext
|
||||
import java.io.Closeable
|
||||
|
||||
/**
|
||||
* A ReVanced [Patch] that works on [ResourceContext].
|
||||
* A ReVanced [Patch] that accesses a [ResourceContext].
|
||||
*
|
||||
* If an implementation of [Patch] also implements [Closeable]
|
||||
* it will be closed in reverse execution order of patches executed by ReVanced [Patcher].
|
||||
*/
|
||||
abstract class ResourcePatch : Patch<ResourceContext>()
|
||||
abstract class ResourcePatch : Patch<ResourceContext> {
|
||||
/**
|
||||
* Create a new [ResourcePatch].
|
||||
*/
|
||||
constructor()
|
||||
|
||||
/**
|
||||
* Create a new [ResourcePatch].
|
||||
*
|
||||
* @param name The name of the patch.
|
||||
* @param description The description of the patch.
|
||||
* @param compatiblePackages The packages the patch is compatible with.
|
||||
* @param dependencies Other patches this patch depends on.
|
||||
* @param use Weather or not the patch should be used.
|
||||
* @param requiresIntegrations Weather or not the patch requires integrations.
|
||||
*/
|
||||
constructor(
|
||||
name: String? = null,
|
||||
description: String? = null,
|
||||
compatiblePackages: Set<CompatiblePackage>? = null,
|
||||
dependencies: Set<PatchClass>? = null,
|
||||
use: Boolean = true,
|
||||
requiresIntegrations: Boolean = false,
|
||||
) : super(name, description, compatiblePackages, dependencies, use, requiresIntegrations)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
package app.revanced.patcher.patch
|
||||
|
||||
import app.revanced.patcher.data.ResourceContext
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
import kotlin.test.Test
|
||||
import app.revanced.patcher.patch.annotation.Patch as PatchAnnotation
|
||||
|
||||
object PatchInitializationTest {
|
||||
@Test
|
||||
fun `initialize using constructor`() {
|
||||
val patch =
|
||||
object : ResourcePatch(name = "Resource patch test") {
|
||||
override fun execute(context: ResourceContext) {}
|
||||
}
|
||||
|
||||
assert(patch.name == "Resource patch test")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `initialize using annotation`() {
|
||||
val patch =
|
||||
@PatchAnnotation("Resource patch test")
|
||||
object : ResourcePatch() {
|
||||
override fun execute(context: ResourceContext) {}
|
||||
}
|
||||
|
||||
assert(patch.name == "Resource patch test")
|
||||
}
|
||||
}
|
|
@ -90,6 +90,7 @@ internal class PatchOptionsTest {
|
|||
@Test
|
||||
fun `getting default value should work`() = assertDoesNotThrow { assertNull(OptionsTestPatch.resettableOption.default) }
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
private object OptionsTestPatch : BytecodePatch() {
|
||||
var booleanOption by booleanPatchOption(
|
||||
"bool",
|
||||
|
|
Loading…
Reference in a new issue