Skip to content

Commit

Permalink
feat: Add constructor to initialize patches without annotations
Browse files Browse the repository at this point in the history
  • Loading branch information
oSumAtrIX committed Nov 29, 2023
1 parent 7aeae93 commit 462fbe2
Show file tree
Hide file tree
Showing 7 changed files with 152 additions and 22 deletions.
5 changes: 5 additions & 0 deletions api/revanced-patcher.api
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 {
Expand Down
5 changes: 3 additions & 2 deletions src/main/kotlin/app/revanced/patcher/PatchBundleLoader.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import java.util.jar.JarFile
import java.util.logging.Logger
import kotlin.reflect.KClass


/**
* A set of [Patch]es.
*/
Expand Down Expand Up @@ -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.",
)
}

Expand All @@ -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.",
)
}

Expand Down
58 changes: 53 additions & 5 deletions src/main/kotlin/app/revanced/patcher/patch/BytecodePatch.kt
Original file line number Diff line number Diff line change
@@ -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())
}
42 changes: 29 additions & 13 deletions src/main/kotlin/app/revanced/patcher/patch/Patch.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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].
*
Expand Down Expand Up @@ -55,25 +55,41 @@ sealed class Patch<out T : Context<*>> {
var requiresIntegrations = false
private set

/**
* The options of the patch associated by the options key.
*/
val options = PatchOptions()
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
}

init {
this::class.findAnnotationRecursively(PatchAnnotation::class)?.let { annotation ->
name = annotation.name.ifEmpty { null }
description = annotation.description.ifEmpty { null }
compatiblePackages =
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 }
dependencies = annotation.dependencies.toSet().ifEmpty { null }
use = annotation.use
requiresIntegrations = annotation.requiresIntegrations
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()

/**
* The execution function of the patch.
*
Expand Down
34 changes: 32 additions & 2 deletions src/main/kotlin/app/revanced/patcher/patch/ResourcePatch.kt
Original file line number Diff line number Diff line change
@@ -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)
}
Original file line number Diff line number Diff line change
@@ -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")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down

0 comments on commit 462fbe2

Please sign in to comment.