Skip to content

Commit

Permalink
finished versioning all the various rules
Browse files Browse the repository at this point in the history
  • Loading branch information
Machine-Maker committed Dec 31, 2024
1 parent 4f7f48e commit fa6503d
Show file tree
Hide file tree
Showing 35 changed files with 476 additions and 302 deletions.
4 changes: 4 additions & 0 deletions src/main/java/io/papermc/asm/rules/RewriteRule.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ static RewriteRule chain(final RewriteRule... rules) {
return chain(Arrays.asList(rules));
}

static RewriteRule chain(final RewriteRule rule1, final RewriteRule rule2) {
return chain(List.of(rule1, rule2));
}

static RewriteRule chain(final Collection<? extends RewriteRule> rules) {
final List<? extends RewriteRule> filteredRules = rules.stream().filter(r -> r != EMPTY).toList();
if (filteredRules.isEmpty()) {
Expand Down
18 changes: 6 additions & 12 deletions src/main/java/io/papermc/asm/rules/builder/RuleFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,11 @@ static RuleFactory.Factory combine(final RuleFactory.Factory... factories) {

void plainStaticRewrite(ClassDesc newOwner, MethodMatcher methodMatcher, String staticMethodName);

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), methodMatcher);
default void changeParamToSuper(final Class<?> newParamType, final TargetedMethodMatcher methodMatcher) {
this.changeParamToSuper( desc(newParamType), methodMatcher);
}

void changeParamToSuper(ClassDesc legacyParamType, ClassDesc newParamType, MethodMatcher methodMatcher);
void changeParamToSuper(ClassDesc newParamType, TargetedMethodMatcher methodMatcher);

default void changeParamFuzzy(final Class<?> newParamType, final Method staticHandler, final TargetedMethodMatcher targetedMethodMatcher) {
this.changeParamFuzzy(desc(newParamType), staticHandler, targetedMethodMatcher);
Expand All @@ -51,14 +48,11 @@ default void changeParamDirect(final Class<?> newParamType, final Method staticH

void changeParamDirect(ClassDesc newParamType, Method staticHandler, TargetedMethodMatcher targetedMethodMatcher);

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), methodMatcher);
default void changeReturnTypeToSub(final Class<?> newReturnType, final TargetedMethodMatcher methodMatcher) {
this.changeReturnTypeToSub(desc(newReturnType), methodMatcher);
}

void changeReturnTypeToSub(ClassDesc oldReturnType, ClassDesc newReturnType, MethodMatcher methodMatcher);
void changeReturnTypeToSub(ClassDesc newReturnType, TargetedMethodMatcher methodMatcher);

default void changeReturnTypeDirect(final Class<?> newReturnType, final Method staticHandler, final TargetedMethodMatcher targetedMethodMatcher) {
this.changeReturnTypeDirect(desc(newReturnType), staticHandler, targetedMethodMatcher);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ public void plainStaticRewrite(final ClassDesc newOwner, final MethodMatcher met
}

@Override
public void changeParamToSuper(final ClassDesc legacyParamType, final ClassDesc newParamType, final MethodMatcher methodMatcher) {
this.addRule(new SuperTypeParamRewrite(this.owners, methodMatcher, legacyParamType, newParamType));
public void changeParamToSuper(final ClassDesc newParamType, final TargetedMethodMatcher methodMatcher) {
this.addRule(new SuperTypeParamRewrite(this.owners, methodMatcher, newParamType));
}

@Override
Expand All @@ -65,8 +65,8 @@ public void changeParamDirect(final ClassDesc newParamType, final Method staticH
}

@Override
public void changeReturnTypeToSub(final ClassDesc oldReturnType, final ClassDesc newReturnType, final MethodMatcher methodMatcher) {
this.addRule(new SubTypeReturnRewrite(this.owners, methodMatcher, oldReturnType, newReturnType));
public void changeReturnTypeToSub(final ClassDesc newReturnType, final TargetedMethodMatcher methodMatcher) {
this.addRule(new SubTypeReturnRewrite(this.owners, methodMatcher, newReturnType));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@
import io.papermc.asm.rules.method.StaticRewrite;
import io.papermc.asm.rules.method.rewrite.MethodRewrite;
import io.papermc.asm.rules.method.rewrite.SimpleRewrite;
import io.papermc.asm.versioned.ApiVersion;
import io.papermc.asm.versioned.VersionedRuleFactory;
import java.lang.constant.ClassDesc;
import java.lang.constant.MethodTypeDesc;
import java.util.NavigableMap;
import java.util.Set;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.objectweb.asm.ClassVisitor;
Expand Down Expand Up @@ -94,4 +97,12 @@ public void visit(final int version, final int access, final String name, final
};
}
}

public record Versioned(NavigableMap<ApiVersion, ClassToInterfaceRule> versions) implements VersionedRuleFactory {

@Override
public RewriteRule createRule(final ApiVersion apiVersion) {
return null;
}
}
}
18 changes: 18 additions & 0 deletions src/main/java/io/papermc/asm/rules/field/FieldToMethodRewrite.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package io.papermc.asm.rules.field;

import io.papermc.asm.ClassProcessingContext;
import io.papermc.asm.rules.RewriteRule;
import io.papermc.asm.rules.builder.matcher.field.FieldMatcher;
import io.papermc.asm.versioned.ApiVersion;
import io.papermc.asm.versioned.VersionedRuleFactory;
import io.papermc.asm.versioned.matcher.VersionedMatcher;
import java.lang.constant.ClassDesc;
import java.lang.constant.ConstantDescs;
import java.lang.constant.MethodTypeDesc;
Expand Down Expand Up @@ -91,4 +95,18 @@ MethodTypeDesc desc(final ClassDesc fieldTypeDesc) {
delegate.visitMethodInsn(type.opcode(opcode), owner, methodName, type.desc(fieldTypeDesc).descriptorString(), this.isInterfaceMethod);
};
}

public record Versioned(Set<ClassDesc> owners, @Nullable String getterName, @Nullable String setterName, boolean isInterfaceMethod, VersionedMatcher<FieldMatcher> versions) implements VersionedRuleFactory {

public Versioned {
if (getterName == null && setterName == null) {
throw new IllegalArgumentException("At least one of getterName or setterName must be non-null");
}
}

@Override
public RewriteRule createRule(final ApiVersion apiVersion) {
return this.versions.ruleForVersion(apiVersion, matcher -> new FieldToMethodRewrite(this.owners(), matcher, this.getterName(), this.setterName(), this.isInterfaceMethod()));
}
}
}
12 changes: 12 additions & 0 deletions src/main/java/io/papermc/asm/rules/method/DirectStaticRewrite.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
package io.papermc.asm.rules.method;

import io.papermc.asm.ClassProcessingContext;
import io.papermc.asm.rules.RewriteRule;
import io.papermc.asm.rules.builder.matcher.method.MethodMatcher;
import io.papermc.asm.rules.generate.GeneratedMethodHolder;
import io.papermc.asm.rules.method.rewrite.ConstructorRewrite;
import io.papermc.asm.rules.method.rewrite.MethodRewrite;
import io.papermc.asm.rules.method.rewrite.SimpleRewrite;
import io.papermc.asm.versioned.ApiVersion;
import io.papermc.asm.versioned.VersionedRuleFactory;
import io.papermc.asm.versioned.matcher.VersionedMatcher;
import java.lang.constant.ClassDesc;
import java.lang.constant.MethodTypeDesc;
import java.util.Set;
Expand Down Expand Up @@ -49,4 +53,12 @@ public MethodRewrite<GeneratedMethodHolder.ConstructorCallData> createConstructo
public ClassDesc staticRedirectOwner(final ClassProcessingContext context) {
return this.staticRedirectOwner;
}

public record Versioned(Set<ClassDesc> owners, ClassDesc staticRedirectOwner, @Nullable String staticMethodName, VersionedMatcher<MethodMatcher> versions) implements VersionedRuleFactory {

@Override
public RewriteRule createRule(final ApiVersion apiVersion) {
return this.versions.ruleForVersion(apiVersion, match -> new DirectStaticRewrite(this.owners(), this.staticMethodName(), match, this.staticRedirectOwner()));
}
}
}
12 changes: 12 additions & 0 deletions src/main/java/io/papermc/asm/rules/method/MoveInstanceMethod.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package io.papermc.asm.rules.method;

import io.papermc.asm.ClassProcessingContext;
import io.papermc.asm.rules.RewriteRule;
import io.papermc.asm.rules.builder.matcher.method.MethodMatcher;
import io.papermc.asm.rules.method.generated.GeneratedStaticRewrite;
import io.papermc.asm.rules.method.rewrite.MethodRewrite;
import io.papermc.asm.versioned.ApiVersion;
import io.papermc.asm.versioned.VersionedRuleFactory;
import io.papermc.asm.versioned.matcher.VersionedMatcher;
import java.lang.constant.ClassDesc;
import java.lang.constant.MethodTypeDesc;
import java.util.Set;
Expand Down Expand Up @@ -56,4 +60,12 @@ public void generateMethod(final GeneratorAdapterFactory factory, final MethodCa
public void generateConstructor(final GeneratorAdapterFactory factory, final MethodCallData modified, final ConstructorCallData original) {
throw new UnsupportedOperationException("Doesn't work with constructors");
}

public record Versioned(Set<ClassDesc> owners, ClassDesc newOwner, String newMethodName, VersionedMatcher<MethodMatcher> versions) implements VersionedRuleFactory {

@Override
public RewriteRule createRule(final ApiVersion apiVersion) {
return this.versions.ruleForVersion(apiVersion, match -> new MoveInstanceMethod(this.owners(), match, this.newOwner(), this.newMethodName()));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
import io.papermc.asm.rules.method.generated.TargetedTypeGeneratedStaticRewrite;
import io.papermc.asm.versioned.ApiVersion;
import io.papermc.asm.versioned.VersionedRuleFactory;
import io.papermc.asm.versioned.matcher.targeted.VersionedTargetedMethodMatcher;
import io.papermc.asm.versioned.matcher.TargetedMethodMatcherWithHandler;
import io.papermc.asm.versioned.matcher.VersionedMatcher;
import java.lang.constant.ClassDesc;
import java.lang.reflect.Method;
import java.util.Set;
Expand All @@ -22,7 +23,7 @@
*/
public record DirectParameterRewrite(Set<ClassDesc> owners, ClassDesc existingType, TargetedMethodMatcher methodMatcher, Method staticHandler) implements TargetedTypeGeneratedStaticRewrite.Parameter, OwnableMethodRewriteRule.Filtered {

public record Versioned(Set<ClassDesc> owners, ClassDesc existingType, VersionedTargetedMethodMatcher versions) implements VersionedRuleFactory {
public record Versioned(Set<ClassDesc> owners, ClassDesc existingType, VersionedMatcher<TargetedMethodMatcherWithHandler> versions) implements VersionedRuleFactory {

@Override
public RewriteRule createRule(final ApiVersion apiVersion) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
import io.papermc.asm.rules.method.rewrite.MethodRewrite;
import io.papermc.asm.versioned.ApiVersion;
import io.papermc.asm.versioned.VersionedRuleFactory;
import io.papermc.asm.versioned.matcher.targeted.VersionedTargetedMethodMatcher;
import io.papermc.asm.versioned.matcher.TargetedMethodMatcherWithHandler;
import io.papermc.asm.versioned.matcher.VersionedMatcher;
import java.lang.constant.ClassDesc;
import java.lang.constant.ConstantDescs;
import java.lang.constant.MethodTypeDesc;
Expand Down Expand Up @@ -59,7 +60,7 @@ public MethodRewrite<MethodCallData> createRewrite(final ClassProcessingContext
});
}

public record Versioned(Set<ClassDesc> owners, ClassDesc existingType, VersionedTargetedMethodMatcher versions) implements VersionedRuleFactory {
public record Versioned(Set<ClassDesc> owners, ClassDesc existingType, VersionedMatcher<TargetedMethodMatcherWithHandler> versions) implements VersionedRuleFactory {

@Override
public RewriteRule createRule(final ApiVersion apiVersion) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

import io.papermc.asm.ClassProcessingContext;
import io.papermc.asm.rules.RewriteRule;
import io.papermc.asm.rules.builder.matcher.method.MethodMatcher;
import io.papermc.asm.rules.builder.matcher.method.targeted.TargetedMethodMatcher;
import io.papermc.asm.rules.method.OwnableMethodRewriteRule;
import io.papermc.asm.rules.method.rewrite.MethodRewrite;
import io.papermc.asm.rules.method.rewrite.SimpleRewrite;
import io.papermc.asm.versioned.ApiVersion;
import io.papermc.asm.versioned.VersionedRuleFactory;
import io.papermc.asm.versioned.matcher.VersionedMethodMatcher;
import io.papermc.asm.versioned.matcher.VersionedMatcher;
import java.lang.constant.ClassDesc;
import java.lang.constant.MethodTypeDesc;
import java.util.Set;
Expand All @@ -21,26 +21,29 @@
* offending parameter in the descriptor and move on.
*
* @param owners owners of the methods to change
* @param methodMatcher method matcher to find methods with
* @param oldParamType the parameter type that will be found in bytecode that needs to be transformed
* @param methodMatcher method matcher to find methods with (target is the type to be found in bytecode that needs to be transformed)
* @param newParamType the parameter type that is valid for existing method
*/
public record SuperTypeParamRewrite(Set<ClassDesc> owners, MethodMatcher methodMatcher, ClassDesc oldParamType, ClassDesc newParamType) implements OwnableMethodRewriteRule.Filtered {
public record SuperTypeParamRewrite(Set<ClassDesc> owners, TargetedMethodMatcher methodMatcher, ClassDesc newParamType) implements OwnableMethodRewriteRule.Filtered {

public ClassDesc oldParamType() {
return this.methodMatcher.targetType();
}

@Override
public MethodRewrite<?> rewrite(final ClassProcessingContext context, final boolean isInvokeDynamic, final int opcode, final ClassDesc owner, final String name, final MethodTypeDesc descriptor, final boolean isInterface) {
return new SimpleRewrite(opcode, owner, name, this.modifyMethodDescriptor(descriptor), isInterface, isInvokeDynamic);
}

private MethodTypeDesc modifyMethodDescriptor(final MethodTypeDesc methodDescriptor) {
return replaceParameters(methodDescriptor, isEqual(this.oldParamType()), this.newParamType());
return replaceParameters(methodDescriptor, isEqual(this.methodMatcher().targetType()), this.newParamType());
}

public record Versioned(Set<ClassDesc> owners, ClassDesc newParamType, VersionedMethodMatcher versions) implements VersionedRuleFactory {
public record Versioned(Set<ClassDesc> owners, ClassDesc newParamType, VersionedMatcher<TargetedMethodMatcher> versions) implements VersionedRuleFactory {

@Override
public RewriteRule createRule(final ApiVersion apiVersion) {
return this.versions.ruleForVersion(apiVersion, pair -> new SuperTypeParamRewrite(this.owners(), pair.matcher(), pair.legacyType(), this.newParamType()));
return this.versions.ruleForVersion(apiVersion, matcher -> new SuperTypeParamRewrite(this.owners(), matcher, this.newParamType()));
}
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
package io.papermc.asm.rules.method.returns;

import io.papermc.asm.rules.RewriteRule;
import io.papermc.asm.rules.builder.matcher.method.targeted.TargetedMethodMatcher;
import io.papermc.asm.rules.method.OwnableMethodRewriteRule;
import io.papermc.asm.rules.method.generated.TargetedTypeGeneratedStaticRewrite;
import io.papermc.asm.versioned.ApiVersion;
import io.papermc.asm.versioned.VersionedRuleFactory;
import io.papermc.asm.versioned.matcher.TargetedMethodMatcherWithHandler;
import io.papermc.asm.versioned.matcher.VersionedMatcher;
import java.lang.constant.ClassDesc;
import java.lang.reflect.Method;
import java.util.Set;
Expand Down Expand Up @@ -30,4 +35,12 @@ public record DirectReturnRewrite(Set<ClassDesc> owners, ClassDesc existingType,
throw new IllegalArgumentException("staticHandler param type isn't " + existingType);
}
}

public record Versioned(Set<ClassDesc> owners, ClassDesc existingType, VersionedMatcher<TargetedMethodMatcherWithHandler> versions, boolean includeOwnerContext) implements VersionedRuleFactory {

@Override
public RewriteRule createRule(final ApiVersion apiVersion) {
return this.versions.ruleForVersion(apiVersion, pair -> new DirectReturnRewrite(this.owners(), this.existingType(), pair.matcher(), pair.staticHandler(), this.includeOwnerContext()));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

import io.papermc.asm.ClassProcessingContext;
import io.papermc.asm.rules.RewriteRule;
import io.papermc.asm.rules.builder.matcher.method.MethodMatcher;
import io.papermc.asm.rules.builder.matcher.method.targeted.TargetedMethodMatcher;
import io.papermc.asm.rules.method.OwnableMethodRewriteRule;
import io.papermc.asm.rules.method.rewrite.MethodRewrite;
import io.papermc.asm.rules.method.rewrite.SimpleRewrite;
import io.papermc.asm.versioned.ApiVersion;
import io.papermc.asm.versioned.VersionedRuleFactory;
import io.papermc.asm.versioned.matcher.VersionedMethodMatcher;
import io.papermc.asm.versioned.matcher.VersionedMatcher;
import java.lang.constant.ClassDesc;
import java.lang.constant.MethodTypeDesc;
import java.util.Set;
Expand All @@ -19,15 +19,18 @@
* We just change the return type in the descriptor and move on.
*
* @param owners owners of the methods to change
* @param methodMatcher method matcher to find methods with
* @param oldReturnType the return type that will be found in bytecode that needs to be transformed
* @param methodMatcher method matcher to find methods with (target is the type to be found in bytecode that needs to be transformed)
* @param newReturnType the return type that is valid for existing method
*/
public record SubTypeReturnRewrite(Set<ClassDesc> owners, MethodMatcher methodMatcher, ClassDesc oldReturnType, ClassDesc newReturnType) implements OwnableMethodRewriteRule.Filtered {
public record SubTypeReturnRewrite(Set<ClassDesc> owners, TargetedMethodMatcher methodMatcher, ClassDesc newReturnType) implements OwnableMethodRewriteRule.Filtered {

public ClassDesc oldReturnType() {
return this.methodMatcher.targetType();
}

@Override
public @Nullable MethodRewrite<?> rewrite(final ClassProcessingContext context, final boolean isInvokeDynamic, final int opcode, final ClassDesc owner, final String name, final MethodTypeDesc descriptor, final boolean isInterface) {
if (!descriptor.returnType().equals(this.newReturnType())) {
if (descriptor.returnType().equals(this.methodMatcher().targetType())) {
return new SimpleRewrite(opcode, owner, name, this.modifyMethodDescriptor(descriptor), isInterface, isInvokeDynamic);
}
return null;
Expand All @@ -37,11 +40,11 @@ private MethodTypeDesc modifyMethodDescriptor(final MethodTypeDesc methodDescrip
return methodDescriptor.changeReturnType(this.newReturnType());
}

public record Versioned(Set<ClassDesc> owners, ClassDesc newReturnType, VersionedMethodMatcher versions) implements VersionedRuleFactory {
public record Versioned(Set<ClassDesc> owners, ClassDesc newReturnType, VersionedMatcher<TargetedMethodMatcher> versions) implements VersionedRuleFactory {

@Override
public RewriteRule createRule(final ApiVersion apiVersion) {
return this.versions.ruleForVersion(apiVersion, pair -> new SubTypeReturnRewrite(this.owners(), pair.matcher(), pair.legacyType(), this.newReturnType()));
return this.versions.ruleForVersion(apiVersion, matcher -> new SubTypeReturnRewrite(this.owners(), matcher, this.newReturnType()));
}
}
}
Loading

0 comments on commit fa6503d

Please sign in to comment.