Skip to content

Commit

Permalink
slightly refactor how matcher builders work for clarity
Browse files Browse the repository at this point in the history
  • Loading branch information
Machine-Maker committed Aug 28, 2024
1 parent f4815f8 commit 0acc5a8
Show file tree
Hide file tree
Showing 35 changed files with 546 additions and 327 deletions.
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package io.papermc.reflectionrewriter;

import io.papermc.asm.rules.RewriteRule;
import io.papermc.asm.rules.builder.matcher.method.MethodMatcher;
import java.lang.constant.ClassDesc;
import java.lang.invoke.ConstantBootstraps;
import java.lang.invoke.LambdaMetafactory;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.util.List;
import java.util.Set;

public final class BaseReflectionRules {
private final ClassDesc proxy;
Expand Down Expand Up @@ -55,55 +57,65 @@ public List<RewriteRule> rules() {
);
}

private static final MethodMatcher CLASS_RULE = MethodMatcher.builder()
.match("forName", b -> b.desc("(Ljava/lang/String;)Ljava/lang/Class;"))
.match(Set.of("getField", "getDeclaredField"), b -> b.desc("(Ljava/lang/String;)Ljava/lang/reflect/Field;"))
.match(Set.of("getMethod", "getDeclaredMethod"), b -> b.desc("(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;"))
.build();

private RewriteRule createClassRule() {
return RewriteRule.forOwnerClass(Class.class, rf -> {
rf.plainStaticRewrite(this.proxy, b -> b
.match("forName").desc("(Ljava/lang/String;)Ljava/lang/Class;")
.match("getField", "getDeclaredField").desc("(Ljava/lang/String;)Ljava/lang/reflect/Field;")
.match("getMethod", "getDeclaredMethod").desc("(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;")
);
rf.plainStaticRewrite(this.proxy, CLASS_RULE);
});
}

private static final MethodMatcher METHOD_HANDLE_LOOKUP_RULE = MethodMatcher.builder()
.match(Set.of("findStatic", "findVirtual"), b -> b.desc("(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/MethodHandle;"))
.match("findClass", b -> b.desc("(Ljava/lang/String;)Ljava/lang/Class;"))
.match("findSpecial", b -> b.desc("(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/Class;)Ljava/lang/invoke/MethodHandle;"))
.match(Set.of("findGetter", "findSetter", "findStaticGetter", "findStaticSetter"), b -> b.desc("(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/invoke/MethodHandle;"))
.match(Set.of("findVarHandle", "findStaticVarHandle"), b -> b.desc("(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/invoke/VarHandle;"))
.match("bind", b -> b.desc("(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/MethodHandle;"))
.build();

private RewriteRule createMethodHandlesLookupRule() {
return RewriteRule.forOwnerClass(MethodHandles.Lookup.class, rf -> {
rf.plainStaticRewrite(this.proxy, b -> b
.match("findStatic", "findVirtual").desc("(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/MethodHandle;")
.match("findClass").desc("(Ljava/lang/String;)Ljava/lang/Class;")
.match("findSpecial").desc("(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/Class;)Ljava/lang/invoke/MethodHandle;")
.match("findGetter", "findSetter", "findStaticGetter", "findStaticSetter").desc("(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/invoke/MethodHandle;")
.match("findVarHandle", "findStaticVarHandle").desc("(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/invoke/VarHandle;")
.match("bind").desc("(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/MethodHandle;")
);
rf.plainStaticRewrite(this.proxy, METHOD_HANDLE_LOOKUP_RULE);
});
}

private static final MethodMatcher LAMBDA_METAFACTORY_RULE = MethodMatcher.builder()
.match("metafactory", b -> b.desc("(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;"))
.match("altMetafactory", b -> b.desc("(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;"))
.build();

private RewriteRule createLamdaMetafactoryRule() {
return RewriteRule.forOwnerClass(LambdaMetafactory.class, rf -> {
rf.plainStaticRewrite(this.proxy, b -> b
.match("metafactory").desc("(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;")
.match("altMetafactory").desc("(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;")
);
rf.plainStaticRewrite(this.proxy, LAMBDA_METAFACTORY_RULE);
});
}

private static final MethodMatcher CONSTANT_BOOTSTRAPS_RULE = MethodMatcher.builder()
.match("getStaticFinal", b -> b.desc(
"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;Ljava/lang/Class;)Ljava/lang/Object;",
"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;"
))
.match(Set.of("fieldVarHandle", "staticFieldVarHandle"), b -> b.desc("(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/Class;)Ljava/lang/invoke/VarHandle;"))
.build();

private RewriteRule createConstantBootstrapsRule() {
return RewriteRule.forOwnerClass(ConstantBootstraps.class, rf -> {
rf.plainStaticRewrite(this.proxy, b -> b
.match("getStaticFinal").desc(
"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;Ljava/lang/Class;)Ljava/lang/Object;",
"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;"
)
.match("fieldVarHandle", "staticFieldVarHandle").desc("(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/Class;)Ljava/lang/invoke/VarHandle;")
);
rf.plainStaticRewrite(this.proxy, CONSTANT_BOOTSTRAPS_RULE);
});
}

private static final MethodMatcher METHOD_TYPE_RULE = MethodMatcher.builder()
.match("fromMethodDescriptorString", b -> b.desc("(Ljava/lang/String;Ljava/lang/ClassLoader;)Ljava/lang/invoke/MethodType;"))
.build();

private RewriteRule createMethodTypeRule() {
return RewriteRule.forOwnerClass(MethodType.class, rf -> {
rf.plainStaticRewrite(this.proxy, b -> b
.match("fromMethodDescriptorString").desc("(Ljava/lang/String;Ljava/lang/ClassLoader;)Ljava/lang/invoke/MethodType;")
);
rf.plainStaticRewrite(this.proxy, METHOD_TYPE_RULE);
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import io.papermc.asm.ClassInfoProvider;
import io.papermc.asm.ClassProcessingContext;
import io.papermc.asm.rules.RewriteRule;
import io.papermc.asm.rules.builder.matcher.method.MethodMatcher;
import java.lang.constant.ClassDesc;
import java.lang.invoke.ConstantBootstraps;
import java.util.function.Predicate;
Expand Down Expand Up @@ -54,8 +55,9 @@ public static RewriteRule create(
final Predicate<String> ownerPredicate
) {
final RewriteRule rewrite = RewriteRule.forOwnerClass(ConstantBootstraps.class, rf -> {
rf.plainStaticRewrite(ClassDesc.of(proxyClassName), b -> b
.match("enumConstant").desc("(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Enum;")
rf.plainStaticRewrite(ClassDesc.of(proxyClassName), MethodMatcher.builder()
.match("enumConstant", b -> b.desc("(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Enum;"))
.build()
);
});
final RewriteRule enumRule = new RewriteRule() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package io.papermc.asm.rules.builder;

import io.papermc.asm.rules.builder.matcher.MethodMatcher;
import io.papermc.asm.rules.builder.matcher.method.MethodMatcher;
import java.lang.constant.ClassDesc;
import java.util.Set;
import java.util.function.Consumer;
Expand All @@ -19,7 +19,7 @@ static ConfiguredRuleFactory.Factory combine(final ConfiguredRuleFactory.Factory
};
}

void plainStaticRewrite(Consumer<? super MethodMatcher.Builder> builderConsumer);
void plainStaticRewrite(MethodMatcher methodMatcher);

@FunctionalInterface
interface Factory extends Consumer<ConfiguredRuleFactory> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
package io.papermc.asm.rules.builder;

import io.papermc.asm.rules.builder.matcher.MethodMatcher;
import io.papermc.asm.rules.builder.matcher.method.MethodMatcher;
import java.lang.constant.ClassDesc;
import java.util.Set;
import java.util.function.Consumer;

public class ConfiguredRuleFactoryImpl extends RuleFactoryImpl implements ConfiguredRuleFactory {

Expand All @@ -15,7 +14,7 @@ public class ConfiguredRuleFactoryImpl extends RuleFactoryImpl implements Config
}

@Override
public void plainStaticRewrite(final Consumer<? super MethodMatcher.Builder> builderConsumer) {
this.plainStaticRewrite(this.config.delegateOwner(), builderConsumer);
public void plainStaticRewrite(final MethodMatcher methodMatcher) {
this.plainStaticRewrite(this.config.delegateOwner(), methodMatcher);
}
}
50 changes: 25 additions & 25 deletions src/main/java/io/papermc/asm/rules/builder/RuleFactory.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package io.papermc.asm.rules.builder;

import io.papermc.asm.rules.RewriteRule;
import io.papermc.asm.rules.builder.matcher.FieldMatcher;
import io.papermc.asm.rules.builder.matcher.MethodMatcher;
import io.papermc.asm.rules.builder.matcher.TargetedMethodMatcher;
import io.papermc.asm.rules.builder.matcher.field.FieldMatcher;
import io.papermc.asm.rules.builder.matcher.method.MethodMatcher;
import io.papermc.asm.rules.builder.matcher.method.targeted.TargetedMethodMatcher;
import java.lang.constant.ClassDesc;
import java.lang.reflect.Method;
import java.util.Set;
Expand All @@ -26,57 +26,57 @@ static RuleFactory.Factory combine(final RuleFactory.Factory... factories) {
};
}

void plainStaticRewrite(ClassDesc newOwner, Consumer<? super MethodMatcher.Builder> builderConsumer);
void plainStaticRewrite(ClassDesc newOwner, MethodMatcher methodMatcher);

default void changeParamToSuper(final Class<?> oldParamType, final Class<?> newParamType, final Consumer<? super MethodMatcher.Builder> builderConsumer) {
default void changeParamToSuper(final Class<?> oldParamType, final Class<?> newParamType, final MethodMatcher methodMatcher) {
if (!newParamType.isAssignableFrom(oldParamType)) {
throw new IllegalArgumentException(newParamType + " is not a superclass of " + oldParamType);
}
this.changeParamToSuper(desc(oldParamType), desc(newParamType), builderConsumer);
this.changeParamToSuper(desc(oldParamType), desc(newParamType), methodMatcher);
}

void changeParamToSuper(ClassDesc legacyParamType, ClassDesc newParamType, Consumer<? super MethodMatcher.Builder> builderConsumer);
void changeParamToSuper(ClassDesc legacyParamType, ClassDesc newParamType, MethodMatcher methodMatcher);

default void changeParamFuzzy(final Class<?> newParamType, final Method staticHandler, final Consumer<? super TargetedMethodMatcher.Builder> builderConsumer) {
this.changeParamFuzzy(desc(newParamType), staticHandler, builderConsumer);
default void changeParamFuzzy(final Class<?> newParamType, final Method staticHandler, final TargetedMethodMatcher targetedMethodMatcher) {
this.changeParamFuzzy(desc(newParamType), staticHandler, targetedMethodMatcher);
}

void changeParamFuzzy(ClassDesc newParamType, Method staticHandler, Consumer<? super TargetedMethodMatcher.Builder> builderConsumer);
void changeParamFuzzy(ClassDesc newParamType, Method staticHandler, TargetedMethodMatcher targetedMethodMatcher);

default void changeParamDirect(final Class<?> newParamType, final Method staticHandler, final Consumer<? super TargetedMethodMatcher.Builder> builderConsumer) {
this.changeParamDirect(desc(newParamType), staticHandler, builderConsumer);
default void changeParamDirect(final Class<?> newParamType, final Method staticHandler, final TargetedMethodMatcher targetedMethodMatcher) {
this.changeParamDirect(desc(newParamType), staticHandler, targetedMethodMatcher);
}

void changeParamDirect(ClassDesc newParamType, Method staticHandler, Consumer<? super TargetedMethodMatcher.Builder> builderConsumer);
void changeParamDirect(ClassDesc newParamType, Method staticHandler, TargetedMethodMatcher targetedMethodMatcher);

default void changeReturnTypeToSub(final Class<?> oldReturnType, final Class<?> newReturnType, final Consumer<? super MethodMatcher.Builder> builderConsumer) {
default void changeReturnTypeToSub(final Class<?> oldReturnType, final Class<?> newReturnType, final MethodMatcher methodMatcher) {
if (!oldReturnType.isAssignableFrom(newReturnType)) {
throw new IllegalArgumentException(newReturnType + " is not a subclass of " + oldReturnType);
}
this.changeReturnTypeToSub(desc(oldReturnType), desc(newReturnType), builderConsumer);
this.changeReturnTypeToSub(desc(oldReturnType), desc(newReturnType), methodMatcher);
}

void changeReturnTypeToSub(ClassDesc oldReturnType, ClassDesc newReturnType, Consumer<? super MethodMatcher.Builder> builderConsumer);
void changeReturnTypeToSub(ClassDesc oldReturnType, ClassDesc newReturnType, MethodMatcher methodMatcher);

default void changeReturnTypeDirect(final Class<?> newReturnType, final Method staticHandler, final Consumer<? super TargetedMethodMatcher.Builder> builderConsumer) {
this.changeReturnTypeDirect(desc(newReturnType), staticHandler, builderConsumer);
default void changeReturnTypeDirect(final Class<?> newReturnType, final Method staticHandler, final TargetedMethodMatcher targetedMethodMatcher) {
this.changeReturnTypeDirect(desc(newReturnType), staticHandler, targetedMethodMatcher);
}

void changeReturnTypeDirect(ClassDesc newReturnType, Method staticHandler, Consumer<? super TargetedMethodMatcher.Builder> builderConsumer);
void changeReturnTypeDirect(ClassDesc newReturnType, Method staticHandler, TargetedMethodMatcher targetedMethodMatcher);

default void changeReturnTypeDirectWithContext(final Class<?> newReturnType, final Method staticHandler, final Consumer<? super TargetedMethodMatcher.Builder> builderConsumer) {
this.changeReturnTypeDirectWithContext(desc(newReturnType), staticHandler, builderConsumer);
default void changeReturnTypeDirectWithContext(final Class<?> newReturnType, final Method staticHandler, final TargetedMethodMatcher targetedMethodMatcher) {
this.changeReturnTypeDirectWithContext(desc(newReturnType), staticHandler, targetedMethodMatcher);
}

void changeReturnTypeDirectWithContext(ClassDesc newReturnType, Method staticHandler, Consumer<? super TargetedMethodMatcher.Builder> builderConsumer);
void changeReturnTypeDirectWithContext(ClassDesc newReturnType, Method staticHandler, TargetedMethodMatcher targetedMethodMatcher);

void changeFieldToMethod(@Nullable String getterName, @Nullable String setterName, boolean isInterfaceMethod, Consumer<? super FieldMatcher.Builder> builderConsumer);

default void moveInstanceMethod(final Class<?> newOwner, final String newMethodName, final Consumer<? super MethodMatcher.Builder> builderConsumer) {
this.moveInstanceMethod(desc(newOwner), newMethodName, builderConsumer);
default void moveInstanceMethod(final Class<?> newOwner, final String newMethodName, final MethodMatcher methodMatcher) {
this.moveInstanceMethod(desc(newOwner), newMethodName, methodMatcher);
}

void moveInstanceMethod(ClassDesc newOwner, String newMethodName, Consumer<? super MethodMatcher.Builder> builderConsumer);
void moveInstanceMethod(ClassDesc newOwner, String newMethodName, MethodMatcher methodMatcher);

void addRule(RewriteRule rule);

Expand Down
Loading

0 comments on commit 0acc5a8

Please sign in to comment.