feat: Add PatchOption#valueType to handle type erasure

Without this new property, it is not possible to infer the type without abusing `ClassCastException` at runtime to infer the type of the option value.

BREAKING CHANGE: This changes the signature of the `PatchOption` constructor.
This commit is contained in:
oSumAtrIX 2023-10-24 22:30:12 +02:00
parent dc09ea639f
commit a46e948b5a
No known key found for this signature in database
GPG key ID: A9B3094ACDB604B4
3 changed files with 38 additions and 11 deletions

View file

@ -289,7 +289,7 @@ public abstract interface annotation class app/revanced/patcher/patch/annotation
public class app/revanced/patcher/patch/options/PatchOption {
public static final field PatchExtensions Lapp/revanced/patcher/patch/options/PatchOption$PatchExtensions;
public fun <init> (Ljava/lang/String;Ljava/lang/Object;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)V
public fun <init> (Ljava/lang/String;Ljava/lang/Object;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLjava/lang/String;Lkotlin/jvm/functions/Function2;)V
public final fun getDefault ()Ljava/lang/Object;
public final fun getDescription ()Ljava/lang/String;
public final fun getKey ()Ljava/lang/String;
@ -298,6 +298,7 @@ public class app/revanced/patcher/patch/options/PatchOption {
public final fun getValidator ()Lkotlin/jvm/functions/Function2;
public final fun getValue ()Ljava/lang/Object;
public final fun getValue (Ljava/lang/Object;Lkotlin/reflect/KProperty;)Ljava/lang/Object;
public final fun getValueType ()Ljava/lang/String;
public final fun getValues ()Ljava/util/Map;
public fun reset ()V
public final fun setValue (Ljava/lang/Object;)V

View file

@ -12,6 +12,7 @@ import kotlin.reflect.KProperty
* @param title The title.
* @param description A description.
* @param required Whether the option is required.
* @param valueType The type of the option value (to handle type erasure).
* @param validator The function to validate the option value.
* @param T The value type of the option.
*/
@ -23,6 +24,7 @@ open class PatchOption<T>(
val title: String?,
val description: String?,
val required: Boolean,
val valueType: String,
val validator: PatchOption<T>.(T?) -> Boolean
) {
/**
@ -110,7 +112,9 @@ open class PatchOption<T>(
description: String? = null,
required: Boolean = false,
validator: PatchOption<String>.(String?) -> Boolean = { true }
) = PatchOption(key, default, values, title, description, required, validator).also { registerOption(it) }
) = PatchOption(
key, default, values, title, description, required, "String", validator
).also { registerOption(it) }
/**
* Create a new [PatchOption] with an integer value and add it to the current [Patch].
@ -135,7 +139,9 @@ open class PatchOption<T>(
description: String? = null,
required: Boolean = false,
validator: PatchOption<Int?>.(Int?) -> Boolean = { true }
) = PatchOption(key, default, values, title, description, required, validator).also { registerOption(it) }
) = PatchOption(
key, default, values, title, description, required, "Int", validator
).also { registerOption(it) }
/**
* Create a new [PatchOption] with a boolean value and add it to the current [Patch].
@ -160,7 +166,9 @@ open class PatchOption<T>(
description: String? = null,
required: Boolean = false,
validator: PatchOption<Boolean?>.(Boolean?) -> Boolean = { true }
) = PatchOption(key, default, values, title, description, required, validator).also { registerOption(it) }
) = PatchOption(key, default, values, title, description, required, "Boolean", validator).also {
registerOption(it)
}
/**
* Create a new [PatchOption] with a float value and add it to the current [Patch].
@ -185,7 +193,9 @@ open class PatchOption<T>(
description: String? = null,
required: Boolean = false,
validator: PatchOption<Float?>.(Float?) -> Boolean = { true }
) = PatchOption(key, default, values, title, description, required, validator).also { registerOption(it) }
) = PatchOption(
key, default, values, title, description, required, "Float", validator
).also { registerOption(it) }
/**
* Create a new [PatchOption] with a long value and add it to the current [Patch].
@ -210,7 +220,9 @@ open class PatchOption<T>(
description: String? = null,
required: Boolean = false,
validator: PatchOption<Long?>.(Long?) -> Boolean = { true }
) = PatchOption(key, default, values, title, description, required, validator).also { registerOption(it) }
) = PatchOption(
key, default, values, title, description, required, "Long", validator
).also { registerOption(it) }
/**
* Create a new [PatchOption] with a string array value and add it to the current [Patch].
@ -235,7 +247,9 @@ open class PatchOption<T>(
description: String? = null,
required: Boolean = false,
validator: PatchOption<Array<String>?>.(Array<String>?) -> Boolean = { true }
) = PatchOption(key, default, values, title, description, required, validator).also { registerOption(it) }
) = PatchOption(
key, default, values, title, description, required, "StringArray", validator
).also { registerOption(it) }
/**
* Create a new [PatchOption] with an integer array value and add it to the current [Patch].
@ -260,7 +274,9 @@ open class PatchOption<T>(
description: String? = null,
required: Boolean = false,
validator: PatchOption<Array<Int>?>.(Array<Int>?) -> Boolean = { true }
) = PatchOption(key, default, values, title, description, required, validator).also { registerOption(it) }
) = PatchOption(
key, default, values, title, description, required, "IntArray", validator
).also { registerOption(it) }
/**
* Create a new [PatchOption] with a boolean array value and add it to the current [Patch].
@ -285,7 +301,9 @@ open class PatchOption<T>(
description: String? = null,
required: Boolean = false,
validator: PatchOption<Array<Boolean>?>.(Array<Boolean>?) -> Boolean = { true }
) = PatchOption(key, default, values, title, description, required, validator).also { registerOption(it) }
) = PatchOption(
key, default, values, title, description, required, "BooleanArray", validator
).also { registerOption(it) }
/**
* Create a new [PatchOption] with a float array value and add it to the current [Patch].
@ -310,7 +328,9 @@ open class PatchOption<T>(
description: String? = null,
required: Boolean = false,
validator: PatchOption<Array<Float>?>.(Array<Float>?) -> Boolean = { true }
) = PatchOption(key, default, values, title, description, required, validator).also { registerOption(it) }
) = PatchOption(
key, default, values, title, description, required, "FloatArray", validator
).also { registerOption(it) }
/**
* Create a new [PatchOption] with a long array value and add it to the current [Patch].
@ -335,7 +355,9 @@ open class PatchOption<T>(
description: String? = null,
required: Boolean = false,
validator: PatchOption<Array<Long>?>.(Array<Long>?) -> Boolean = { true }
) = PatchOption(key, default, values, title, description, required, validator).also { registerOption(it) }
) = PatchOption(
key, default, values, title, description, required, "LongArray", validator
).also { registerOption(it) }
private fun <P : Patch<*>> P.registerOption(option: PatchOption<*>) = option.also { options.register(it) }
}

View file

@ -85,6 +85,10 @@ internal class PatchOptionsTest {
}
}
@Test
fun `option types should be known`() =
assertTrue(OptionsTestPatch.options["array"].valueType == "StringArray")
@Test
fun `getting default value should work`() =
assertDoesNotThrow { assertNull(OptionsTestPatch.resettableOption.default) }