Skip to content

Commit

Permalink
Fix except msg issues in finders
Browse files Browse the repository at this point in the history
Optimize expect msg for finders
Add newInstanceBestMatch & newInstance for ClassUtils
Add getMemberModifiersString in Utils
Bump libs version
  • Loading branch information
KyuubiRan committed Aug 25, 2023
1 parent 8242758 commit e5f143e
Show file tree
Hide file tree
Showing 17 changed files with 170 additions and 37 deletions.
19 changes: 18 additions & 1 deletion EzXHelper/api/EzXHelper.api
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ public final class com/github/kyuubiran/ezxhelper/ClassHelper {
public final fun invokeStaticMethodBestMatch (Ljava/lang/String;Ljava/lang/Class;[Ljava/lang/Object;)Ljava/lang/Object;
public static synthetic fun invokeStaticMethodBestMatch$default (Lcom/github/kyuubiran/ezxhelper/ClassHelper;Ljava/lang/String;Ljava/lang/Class;[Ljava/lang/Object;ILjava/lang/Object;)Ljava/lang/Object;
public final fun isPrimitiveTypeMatch (Ljava/lang/Class;)Z
public final fun newInstance-9Ha6kD0 ([Ljava/lang/Class;[Ljava/lang/Object;)Ljava/lang/Object;
public static synthetic fun newInstance-9Ha6kD0$default (Lcom/github/kyuubiran/ezxhelper/ClassHelper;[Ljava/lang/Class;[Ljava/lang/Object;ILjava/lang/Object;)Ljava/lang/Object;
public final fun newInstanceBestMatch ([Ljava/lang/Object;)Ljava/lang/Object;
public final fun setStaticObject (Ljava/lang/String;Ljava/lang/Object;)V
public final fun setStaticObjectUntilSuperclass (Ljava/lang/String;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)V
public static synthetic fun setStaticObjectUntilSuperclass$default (Lcom/github/kyuubiran/ezxhelper/ClassHelper;Ljava/lang/String;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
Expand Down Expand Up @@ -72,6 +75,9 @@ public final class com/github/kyuubiran/ezxhelper/ClassUtils {
public static final fun loadFirstClass ([Ljava/lang/String;)Ljava/lang/Class;
public static final fun loadFirstClassOrNull (Ljava/lang/ClassLoader;[Ljava/lang/String;)Ljava/lang/Class;
public static final fun loadFirstClassOrNull ([Ljava/lang/String;)Ljava/lang/Class;
public final fun newInstance-VVUCtX8 (Ljava/lang/Class;[Ljava/lang/Class;[Ljava/lang/Object;)Ljava/lang/Object;
public static synthetic fun newInstance-VVUCtX8$default (Lcom/github/kyuubiran/ezxhelper/ClassUtils;Ljava/lang/Class;[Ljava/lang/Class;[Ljava/lang/Object;ILjava/lang/Object;)Ljava/lang/Object;
public final fun newInstanceBestMatch (Ljava/lang/Class;[Ljava/lang/Object;)Ljava/lang/Object;
public static final fun setStaticObject (Ljava/lang/Class;Ljava/lang/String;Ljava/lang/Object;)V
public static final fun setStaticObjectUntilSuperclass (Ljava/lang/Class;Ljava/lang/String;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)V
public static synthetic fun setStaticObjectUntilSuperclass$default (Ljava/lang/Class;Ljava/lang/String;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
Expand Down Expand Up @@ -441,6 +447,7 @@ public final class com/github/kyuubiran/ezxhelper/finders/ConstructorFinder : co
public static final fun fromSequence (Lkotlin/sequences/Sequence;)Lcom/github/kyuubiran/ezxhelper/finders/ConstructorFinder;
public static final fun fromVararg ([Ljava/lang/reflect/Constructor;)Lcom/github/kyuubiran/ezxhelper/finders/ConstructorFinder;
public synthetic fun getExceptionTypes (Ljava/lang/reflect/Member;)[Ljava/lang/Class;
public fun getName ()Ljava/lang/String;
public synthetic fun getParameterTypes (Ljava/lang/reflect/Member;)[Ljava/lang/Class;
}

Expand Down Expand Up @@ -475,6 +482,7 @@ public final class com/github/kyuubiran/ezxhelper/finders/FieldFinder : com/gith
public static final fun fromIterable (Ljava/lang/Iterable;)Lcom/github/kyuubiran/ezxhelper/finders/FieldFinder;
public static final fun fromSequence (Lkotlin/sequences/Sequence;)Lcom/github/kyuubiran/ezxhelper/finders/FieldFinder;
public static final fun fromVararg ([Ljava/lang/reflect/Field;)Lcom/github/kyuubiran/ezxhelper/finders/FieldFinder;
public fun getName ()Ljava/lang/String;
}

public final class com/github/kyuubiran/ezxhelper/finders/FieldFinder$-Static {
Expand Down Expand Up @@ -510,6 +518,7 @@ public final class com/github/kyuubiran/ezxhelper/finders/MethodFinder : com/git
public static final fun fromSequence (Lkotlin/sequences/Sequence;)Lcom/github/kyuubiran/ezxhelper/finders/MethodFinder;
public static final fun fromVararg ([Ljava/lang/reflect/Method;)Lcom/github/kyuubiran/ezxhelper/finders/MethodFinder;
public synthetic fun getExceptionTypes (Ljava/lang/reflect/Member;)[Ljava/lang/Class;
public fun getName ()Ljava/lang/String;
public synthetic fun getParameterTypes (Ljava/lang/reflect/Member;)[Ljava/lang/Class;
}

Expand All @@ -527,7 +536,7 @@ public final class com/github/kyuubiran/ezxhelper/finders/MethodFinder$-Static {
public final synthetic fun methodFinder ([Ljava/lang/reflect/Method;)Lcom/github/kyuubiran/ezxhelper/finders/MethodFinder;
}

public abstract class com/github/kyuubiran/ezxhelper/finders/base/BaseFinder {
public abstract class com/github/kyuubiran/ezxhelper/finders/base/BaseFinder : com/github/kyuubiran/ezxhelper/interfaces/INamed {
public fun <init> (Lkotlin/sequences/Sequence;)V
protected final fun applyThis (Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
public final fun contact (Lcom/github/kyuubiran/ezxhelper/finders/base/BaseFinder;)Ljava/lang/Object;
Expand Down Expand Up @@ -638,6 +647,10 @@ public abstract interface class com/github/kyuubiran/ezxhelper/interfaces/IMetho
public abstract fun onMethodHooked (Lde/robv/android/xposed/XC_MethodHook$MethodHookParam;)V
}

public abstract interface class com/github/kyuubiran/ezxhelper/interfaces/INamed {
public abstract fun getName ()Ljava/lang/String;
}

public abstract interface class com/github/kyuubiran/ezxhelper/interfaces/IOnValueChangedEvent {
public abstract fun onValueChanged (Ljava/lang/Object;)V
}
Expand All @@ -662,6 +675,7 @@ public final class com/github/kyuubiran/ezxhelper/misc/FinderExceptionMessage {
public final fun append (Ljava/lang/String;Z)V
public static synthetic fun append$default (Lcom/github/kyuubiran/ezxhelper/misc/FinderExceptionMessage;Ljava/lang/String;ZILjava/lang/Object;)V
public final fun condition (Ljava/lang/String;)V
public final fun ctor (Lcom/github/kyuubiran/ezxhelper/interfaces/INamed;Ljava/lang/String;)V
public final fun getExceptionMessageBuilder ()Ljava/lang/StringBuilder;
public final fun getMsg ()Ljava/lang/String;
}
Expand Down Expand Up @@ -695,6 +709,9 @@ public final class com/github/kyuubiran/ezxhelper/misc/Utils {
public static synthetic fun findDexClassLoader$default (Ljava/lang/ClassLoader;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldalvik/system/BaseDexClassLoader;
public static final fun getAllClassesList (Ljava/lang/ClassLoader;Lkotlin/jvm/functions/Function1;)Ljava/util/List;
public static synthetic fun getAllClassesList$default (Ljava/lang/ClassLoader;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ljava/util/List;
public final fun getMEMBER_MODIFIER_STRING_MAP ()Ljava/util/Map;
public final fun getMemberModifiersString (IZ)Ljava/lang/String;
public static synthetic fun getMemberModifiersString$default (Lcom/github/kyuubiran/ezxhelper/misc/Utils;IZILjava/lang/Object;)Ljava/lang/String;
public static final fun restartHostApp (Landroid/app/Activity;)V
}

Expand Down
4 changes: 2 additions & 2 deletions EzXHelper/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ plugins {
id 'signing'
}

def versionName = "2.0.6"
def versionName = "2.0.7"

android {
compileSdkVersion = 33
buildToolsVersion = "33.0.0"
buildToolsVersion = "33.0.1"
namespace = "com.github.kyuubiran"

defaultConfig {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
@file:Suppress("MemberVisibilityCanBePrivate", "unused")

package com.github.kyuubiran.ezxhelper

import android.widget.Toast
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,12 @@ class ClassHelper private constructor(private val clz: Class<*>) {
*/
fun toPrimitiveType() =
ClassUtils.toPrimitiveType(clz)

@Throws(NoSuchMethodException::class)
fun newInstanceBestMatch(vararg params: Any?) =
ClassUtils.newInstanceBestMatch(clz, *params)

@Throws(NoSuchMethodException::class)
fun newInstance(paramTypes: ParamTypes = paramTypes(), params: Params = params()) =
ClassUtils.newInstance(clz, paramTypes, params)
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
package com.github.kyuubiran.ezxhelper

import com.github.kyuubiran.ezxhelper.MemberExtensions.isStatic
import com.github.kyuubiran.ezxhelper.finders.ConstructorFinder.`-Static`.constructorFinder
import com.github.kyuubiran.ezxhelper.finders.MethodFinder.`-Static`.methodFinder
import java.lang.IllegalArgumentException

Expand Down Expand Up @@ -216,7 +217,7 @@ object ClassUtils {
.apply { if (returnType != null) filterByAssignableReturnType(returnType) }
.filterByAssignableParamTypes(*paramTypes)
.firstOrNull()
?: throw NoSuchMethodException("No best match method $methodName in ${clz.name} and its superclasses.")
?: throw NoSuchMethodException("No such best match method $methodName in ${clz.name} and its superclasses.")

return m.invoke(null, *params)
}
Expand Down Expand Up @@ -282,4 +283,36 @@ object ClassUtils {
else -> clz
}
}

/**
* Create a new instance of the class
* @param clz class
* @param paramTypes constructor param types
* @param params constructor params
* @return new instance
* @throws NoSuchMethodException if the constructor is not found
*/
@Throws(NoSuchMethodException::class)
fun newInstance(clz: Class<*>, paramTypes: ParamTypes = paramTypes(), params: Params = params()): Any {
val cf = clz.constructorFinder().filterByParamTypes(*paramTypes.types)

val c = cf.firstOrNull() ?: throw NoSuchMethodException("No such constructor found in ${clz.name}.")
return c.newInstance(*params.params)
}

/**
* Create a new instance of the class
* @param clz class
* @param params constructor params
* @return new instance
* @throws NoSuchMethodException if the constructor is not found
*/
@Throws(NoSuchMethodException::class)
fun newInstanceBestMatch(clz: Class<*>, vararg params: Any?): Any {
val paramTypes = params.map { it?.let { it::class.java } }.toTypedArray()
val cf = clz.constructorFinder().filterByAssignableParamTypes(*paramTypes)

val c = cf.firstOrNull() ?: throw NoSuchMethodException("No such best match constructor found in ${clz.name}.")
return c.newInstance(*params)
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@file:Suppress("unused")
@file:Suppress("unused", "MemberVisibilityCanBePrivate")

package com.github.kyuubiran.ezxhelper

Expand Down Expand Up @@ -52,7 +52,7 @@ class HookFactory {
}

/**
* Interrupt the method, make method return null, just a wrapper of [before].
* Interrupt the method, make method return null, just a wrapper of [before] and same as [returnConstant]`(null)`
*
* **WARNING: MAY CAUSE EXCEPTION IF METHOD RETURNS NON-NULL TYPE**
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,22 @@ import java.lang.reflect.Constructor
* Helper for finding constructor(s) in the class or collection.
*/
class ConstructorFinder private constructor(seq: Sequence<Constructor<*>>) : ExecutableFinder<Constructor<*>, ConstructorFinder>(seq) {
override val name: String
get() = "ConstructorFinder"

@Suppress("ClassName")
companion object `-Static` {
@JvmStatic
fun fromClass(clazz: Class<*>): ConstructorFinder {
return ConstructorFinder(clazz.declaredConstructors.asSequence()).apply {
exceptMessageScope { ctor<ConstructorFinder>("No such constructor found in class: ${clazz.name}") }
exceptMessageScope { ctor(this@apply, "No such constructor found in class: ${clazz.name}") }
}
}

@JvmStatic
fun fromSequence(seq: Sequence<Constructor<*>>): ConstructorFinder {
return ConstructorFinder(seq).apply {
exceptMessageScope { ctor<ConstructorFinder>("No such constructor found in sequence(size=${seq.count()})") }
exceptMessageScope { ctor(this@apply,"No such constructor found in sequence(size=${seq.count()})") }
}
}

Expand All @@ -35,21 +38,21 @@ class ConstructorFinder private constructor(seq: Sequence<Constructor<*>>) : Exe
@JvmStatic
fun fromArray(array: Array<Constructor<*>>): ConstructorFinder {
return ConstructorFinder(array.asSequence()).apply {
exceptMessageScope { ctor<ConstructorFinder>("No such constructor found in array(size=${array.count()})") }
exceptMessageScope { ctor(this@apply,"No such constructor found in array(size=${array.count()})") }
}
}

@JvmStatic
fun fromVararg(vararg array: Constructor<*>): ConstructorFinder {
return ConstructorFinder(array.asSequence()).apply {
exceptMessageScope { ctor<ConstructorFinder>("No such constructor found in array(size=${array.count()})") }
exceptMessageScope { ctor(this@apply,"No such constructor found in array(size=${array.count()})") }
}
}

@JvmStatic
fun fromIterable(iterable: Iterable<Constructor<*>>): ConstructorFinder {
return ConstructorFinder(iterable.asSequence()).apply {
exceptMessageScope { ctor<ConstructorFinder>("No such constructor found in iterable)") }
exceptMessageScope { ctor(this@apply,"No such constructor found in iterable)") }
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@ import java.lang.reflect.Modifier
*/
class FieldFinder private constructor(seq: Sequence<Field>) : BaseMemberFinder<Field, FieldFinder>(seq), IFindSuper<FieldFinder> {
private var clazz: Class<*>? = null
override val name: String
get() = "FieldFinder"

@Suppress("ClassName")
companion object `-Static` {
@JvmStatic
fun fromClass(clazz: Class<*>): FieldFinder {
return FieldFinder(clazz.declaredFields.asSequence()).also { it.clazz = clazz }.apply {
exceptMessageScope { ctor<FieldFinder>("No such field found in class: ${clazz.name}") }
exceptMessageScope { ctor(this@apply, "No such field found in class: ${clazz.name}") }
}
}

Expand All @@ -31,28 +33,28 @@ class FieldFinder private constructor(seq: Sequence<Field>) : BaseMemberFinder<F
@JvmStatic
fun fromSequence(seq: Sequence<Field>): FieldFinder {
return FieldFinder(seq).apply {
exceptMessageScope { ctor<FieldFinder>("No such field found in sequence(size=${seq.count()})") }
exceptMessageScope { ctor(this@apply, "No such field found in sequence(size=${seq.count()})") }
}
}

@JvmStatic
fun fromArray(array: Array<Field>): FieldFinder {
return FieldFinder(array.asSequence()).apply {
exceptMessageScope { ctor<FieldFinder>("No such field found in array(size=${array.count()})") }
exceptMessageScope { ctor(this@apply, "No such field found in array(size=${array.count()})") }
}
}

@JvmStatic
fun fromVararg(vararg array: Field): FieldFinder {
return FieldFinder(array.asSequence()).apply {
exceptMessageScope { ctor<FieldFinder>("No such field found in vararg(size=${array.count()})") }
exceptMessageScope { ctor(this@apply, "No such field found in vararg(size=${array.count()})") }
}
}

@JvmStatic
fun fromIterable(iterable: Iterable<Field>): FieldFinder {
return FieldFinder(iterable.asSequence()).apply {
exceptMessageScope { ctor<FieldFinder>("No such field found in iterable(size=${iterable.count()})") }
exceptMessageScope { ctor(this@apply, "No such field found in iterable(size=${iterable.count()})") }
}
}

Expand Down Expand Up @@ -156,7 +158,7 @@ class FieldFinder private constructor(seq: Sequence<Field>) : BaseMemberFinder<F
}

if (ml != null) {
exceptMessageScope { condition("findSuper($ml)") }
exceptMessageScope { condition("findSuper(CustomCondition)") }
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ import java.lang.reflect.Modifier
class MethodFinder private constructor(seq: Sequence<Method>) : ExecutableFinder<Method, MethodFinder>(seq), IFindSuper<MethodFinder> {
private var clazz: Class<*>? = null

override val name: String
get() = "MethodFinder"

@Suppress("ClassName")
companion object `-Static` {
@JvmStatic
Expand All @@ -24,7 +27,7 @@ class MethodFinder private constructor(seq: Sequence<Method>) : ExecutableFinder
seq += clazz.interfaces.flatMap { c -> c.declaredMethods.asSequence() }
return MethodFinder(seq).apply {
this.clazz = clazz
exceptMessageScope { ctor<MethodFinder>("No such method found in class: ${clazz.name}") }
exceptMessageScope { ctor(this@apply, "No such method found in class: ${clazz.name}") }
}
}

Expand All @@ -35,28 +38,28 @@ class MethodFinder private constructor(seq: Sequence<Method>) : ExecutableFinder
@JvmStatic
fun fromSequence(seq: Sequence<Method>): MethodFinder {
return MethodFinder(seq).apply {
exceptMessageScope { ctor<MethodFinder>("No such method found in sequence(size=${seq.count()})") }
exceptMessageScope { ctor(this@apply, "No such method found in sequence(size=${seq.count()})") }
}
}

@JvmStatic
fun fromArray(array: Array<Method>): MethodFinder {
return MethodFinder(array.asSequence()).apply {
exceptMessageScope { ctor<MethodFinder>("No such method found in array(size=${array.count()})") }
exceptMessageScope { ctor(this@apply, "No such method found in array(size=${array.count()})") }
}
}

@JvmStatic
fun fromVararg(vararg array: Method): MethodFinder {
return MethodFinder(array.asSequence()).apply {
exceptMessageScope { ctor<MethodFinder>("No such method found in vararg(size=${array.count()})") }
exceptMessageScope { ctor(this@apply, "No such method found in vararg(size=${array.count()})") }
}
}

@JvmStatic
fun fromIterable(iterable: Iterable<Method>): MethodFinder {
return MethodFinder(iterable.asSequence()).apply {
exceptMessageScope { ctor<MethodFinder>("No such method found in iterable(size=${iterable.count()})") }
exceptMessageScope { ctor(this@apply, "No such method found in iterable(size=${iterable.count()})") }
}
}

Expand Down Expand Up @@ -96,7 +99,7 @@ class MethodFinder private constructor(seq: Sequence<Method>) : ExecutableFinder
*/
fun filterByReturnType(returnType: Class<*>) = applyThis {
sequence = sequence.filter { it.returnType == returnType }
exceptMessageScope { condition("filterByReturnType($returnType)") }
exceptMessageScope { condition("filterByReturnType(${returnType.name})") }
}

/**
Expand All @@ -106,7 +109,7 @@ class MethodFinder private constructor(seq: Sequence<Method>) : ExecutableFinder
*/
fun filterByAssignableReturnType(returnType: Class<*>) = applyThis {
sequence = sequence.filter { it.returnType.isAssignableFrom(returnType) || returnType.isAssignableFrom(it.returnType) }
exceptMessageScope { condition("filterByAssignableReturnType($returnType)") }
exceptMessageScope { condition("filterByAssignableReturnType(${returnType.name})") }
}

// endregion
Expand Down Expand Up @@ -175,7 +178,7 @@ class MethodFinder private constructor(seq: Sequence<Method>) : ExecutableFinder
}

if (ml != null) {
exceptMessageScope { condition("findSuper($ml)") }
exceptMessageScope { condition("findSuper(CustomCondition)") }
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
package com.github.kyuubiran.ezxhelper.finders.base

import com.github.kyuubiran.ezxhelper.Config
import com.github.kyuubiran.ezxhelper.interfaces.INamed
import com.github.kyuubiran.ezxhelper.misc.FinderExceptionMessage

abstract class BaseFinder<T, Self> constructor(protected var sequence: Sequence<T>) {
abstract class BaseFinder<T, Self> constructor(protected var sequence: Sequence<T>) : INamed {
// region exception message

protected val exceptMsg: FinderExceptionMessage? =
Expand Down
Loading

0 comments on commit e5f143e

Please sign in to comment.