From 80c2e809251cdb04d2dd3b3bfdbb8844bdfa31fa Mon Sep 17 00:00:00 2001 From: Sculas Date: Wed, 7 Sep 2022 22:31:15 +0200 Subject: [PATCH] feat: deprecation for patches --- .../kotlin/app/revanced/patcher/Patcher.kt | 5 +++++ .../revanced/patcher/annotation/Deprecated.kt | 20 +++++++++++++++++++ .../extensions/AnnotationExtensions.kt | 18 ++++++++++------- 3 files changed, 36 insertions(+), 7 deletions(-) create mode 100644 src/main/kotlin/app/revanced/patcher/annotation/Deprecated.kt diff --git a/src/main/kotlin/app/revanced/patcher/Patcher.kt b/src/main/kotlin/app/revanced/patcher/Patcher.kt index c202dc6f..eb83ec65 100644 --- a/src/main/kotlin/app/revanced/patcher/Patcher.kt +++ b/src/main/kotlin/app/revanced/patcher/Patcher.kt @@ -4,6 +4,7 @@ import app.revanced.patcher.data.Data import app.revanced.patcher.data.PackageMetadata import app.revanced.patcher.data.impl.findIndexed import app.revanced.patcher.extensions.PatchExtensions.dependencies +import app.revanced.patcher.extensions.PatchExtensions.deprecated import app.revanced.patcher.extensions.PatchExtensions.patchName import app.revanced.patcher.extensions.nullOutputStream import app.revanced.patcher.fingerprint.method.utils.MethodFingerprintUtils.resolve @@ -289,6 +290,10 @@ class Patcher(private val options: PatcherOptions) { return PatchResultError("'$patchName' is a resource patch, but resource patching is disabled") } + patch.deprecated?.let { (reason, replacement) -> + logger.warn("'$patchName' is deprecated: '$reason'" + if (replacement != null) ". Use '$replacement' instead." else "") + } + // TODO: find a solution for this val data = if (isResourcePatch) { data.resourceData diff --git a/src/main/kotlin/app/revanced/patcher/annotation/Deprecated.kt b/src/main/kotlin/app/revanced/patcher/annotation/Deprecated.kt new file mode 100644 index 00000000..a6e3021e --- /dev/null +++ b/src/main/kotlin/app/revanced/patcher/annotation/Deprecated.kt @@ -0,0 +1,20 @@ +package app.revanced.patcher.annotation + +import app.revanced.patcher.data.Data +import app.revanced.patcher.patch.Patch +import kotlin.reflect.KClass + +/** + * Declares a [Patch] deprecated for removal. + * @param reason The reason why the patch is deprecated. + * @param replacement The replacement for the deprecated patch, if any. + */ +@Target(AnnotationTarget.CLASS) +@Retention(AnnotationRetention.RUNTIME) +@MustBeDocumented +@Repeatable +annotation class PatchDeprecated( + val reason: String, + val replacement: KClass> = Patch::class + // Values cannot be nullable in annotations, so this will have to do. +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patcher/extensions/AnnotationExtensions.kt b/src/main/kotlin/app/revanced/patcher/extensions/AnnotationExtensions.kt index cf5ecf4c..c01945fa 100644 --- a/src/main/kotlin/app/revanced/patcher/extensions/AnnotationExtensions.kt +++ b/src/main/kotlin/app/revanced/patcher/extensions/AnnotationExtensions.kt @@ -1,9 +1,6 @@ package app.revanced.patcher.extensions -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version +import app.revanced.patcher.annotation.* import app.revanced.patcher.data.Data import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.patch.OptionsContainer @@ -45,9 +42,16 @@ object PatchExtensions { val Class>.description get() = recursiveAnnotation(Description::class)?.description val Class>.dependencies get() = recursiveAnnotation(app.revanced.patcher.patch.annotations.DependsOn::class)?.dependencies val Class>.compatiblePackages get() = recursiveAnnotation(Compatibility::class)?.compatiblePackages - val Class>.options get() = kotlin.companionObjectInstance?.let { - (it as? OptionsContainer)?.options - } + val Class>.options + get() = kotlin.companionObjectInstance?.let { + (it as? OptionsContainer)?.options + } + val Class>.deprecated: Pair>?>? + get() = recursiveAnnotation(PatchDeprecated::class)?.let { + it.reason to it.replacement.let { cl -> + if (cl == Patch::class) null else cl + } + } @JvmStatic fun Class>.dependsOn(patch: Class>): Boolean {