Skip to content

Commit 159ba64

Browse files
committed
work on enum renames
1 parent 4dd1120 commit 159ba64

39 files changed

+845
-197
lines changed

src/main/java/io/papermc/asm/rules/RewriteRule.java

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import io.papermc.asm.ClassProcessingContext;
44
import io.papermc.asm.rules.builder.RuleFactory;
5+
import io.papermc.asm.util.DescriptorUtils;
56
import java.lang.constant.ClassDesc;
67
import java.util.ArrayList;
78
import java.util.Arrays;
@@ -26,7 +27,7 @@ static RewriteRule forOwnerClass(final Class<?> owner, final Consumer<? super Ru
2627

2728
@SafeVarargs
2829
static RewriteRule forOwnerClasses(final Set<Class<?>> owners, final Consumer<? super RuleFactory> firstFactoryConsumer, final Consumer<? super RuleFactory>... factoryConsumers) {
29-
return forOwners(owners.stream().map(c -> c.describeConstable().orElseThrow()).collect(Collectors.toUnmodifiableSet()), firstFactoryConsumer, factoryConsumers);
30+
return forOwners(owners.stream().map(DescriptorUtils::desc).collect(Collectors.toUnmodifiableSet()), firstFactoryConsumer, factoryConsumers);
3031
}
3132

3233
@SafeVarargs
@@ -49,7 +50,13 @@ static RewriteRule chain(final RewriteRule... rules) {
4950
}
5051

5152
static RewriteRule chain(final Collection<? extends RewriteRule> rules) {
52-
return new Chain(List.copyOf(rules));
53+
final List<? extends RewriteRule> filteredRules = rules.stream().filter(r -> r != EMPTY).toList();
54+
if (filteredRules.isEmpty()) {
55+
return EMPTY;
56+
} else if (filteredRules.size() == 1) {
57+
return filteredRules.iterator().next();
58+
}
59+
return new Chain(filteredRules);
5360
}
5461

5562
static ChainBuilder chain() {
@@ -73,16 +80,17 @@ default ClassVisitor createVisitor(final int api, final ClassVisitor parent, fin
7380
}
7481
}
7582

76-
record Chain(List<RewriteRule> rules) implements RewriteRule {
77-
public Chain(final List<RewriteRule> rules) {
78-
this.rules = List.copyOf(rules);
83+
record Chain(List<? extends RewriteRule> rules) implements RewriteRule {
84+
public Chain {
85+
rules = List.copyOf(rules);
7986
}
8087

8188
@Override
8289
public ClassVisitor createVisitor(final int api, final ClassVisitor parent, final ClassProcessingContext context) {
8390
ClassVisitor visitor = parent;
84-
for (final RewriteRule rule : this.rules) {
85-
visitor = rule.createVisitor(api, visitor, context);
91+
// iterate over this.rules backwards to ensure the first rule is the outermost visitor
92+
for (int i = this.rules.size() - 1; i >= 0; i--) {
93+
visitor = this.rules.get(i).createVisitor(api, visitor, context);
8694
}
8795
return visitor;
8896
}
@@ -109,7 +117,7 @@ public ChainBuilder then(final RewriteRule... rules) {
109117
}
110118

111119
public RewriteRule build() {
112-
return new Chain(this.rules);
120+
return RewriteRule.chain(this.rules);
113121
}
114122
}
115123
}

src/main/java/io/papermc/asm/rules/builder/RuleFactoryImpl.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,6 @@ private static Method isStatic(final Method staticHandler) {
101101

102102
@Override
103103
public RewriteRule build() {
104-
if (this.rules.size() == 1) {
105-
return this.rules.get(0);
106-
}
107104
return RewriteRule.chain(this.rules);
108105
}
109106
}

src/main/java/io/papermc/asm/rules/method/MethodRewriteRule.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55
import io.papermc.asm.rules.method.rewrite.MethodRewrite;
66
import java.lang.constant.ClassDesc;
77
import java.lang.constant.MethodTypeDesc;
8-
import java.util.LinkedHashMap;
8+
import java.util.Comparator;
99
import java.util.Map;
10+
import java.util.TreeMap;
1011
import org.checkerframework.checker.nullness.qual.Nullable;
1112
import org.objectweb.asm.ClassVisitor;
1213
import org.objectweb.asm.Handle;
@@ -56,9 +57,16 @@ default boolean shouldProcess(final ClassProcessingContext context, final int op
5657

5758
@Override
5859
default ClassVisitor createVisitor(final int api, final ClassVisitor parent, final ClassProcessingContext context) {
59-
record MethodKey(String owner, String name, MethodTypeDesc descriptor) {
60+
record MethodKey(String owner, String name, MethodTypeDesc descriptor) implements Comparable<MethodKey> {
61+
private static final Comparator<MethodKey> COMPARATOR = Comparator.comparing(MethodKey::owner)
62+
.thenComparing(MethodKey::name)
63+
.thenComparing(key -> key.descriptor().descriptorString());
64+
@Override
65+
public int compareTo(final MethodKey o) {
66+
return COMPARATOR.compare(this, o);
67+
}
6068
}
61-
final Map<MethodKey, MethodRewrite.MethodGenerator> methodsToGenerate = new LinkedHashMap<>();
69+
final Map<MethodKey, MethodRewrite.MethodGenerator> methodsToGenerate = new TreeMap<>();
6270
return new ClassVisitor(api, parent) {
6371

6472
@Override
Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,14 @@
11
package io.papermc.asm.rules.method.params;
22

3-
import io.papermc.asm.versioned.ApiVersion;
4-
import io.papermc.asm.versioned.VersionedRuleFactory;
53
import io.papermc.asm.rules.RewriteRule;
64
import io.papermc.asm.rules.builder.matcher.method.targeted.TargetedMethodMatcher;
75
import io.papermc.asm.rules.method.generated.TargetedTypeGeneratedStaticRewrite;
6+
import io.papermc.asm.versioned.ApiVersion;
7+
import io.papermc.asm.versioned.VersionedRuleFactory;
8+
import io.papermc.asm.versioned.matcher.targeted.VersionedTargetedMethodMatcher;
89
import java.lang.constant.ClassDesc;
910
import java.lang.reflect.Method;
10-
import java.util.Collections;
11-
import java.util.Map;
12-
import java.util.NavigableMap;
1311
import java.util.Set;
14-
import java.util.TreeMap;
15-
import org.checkerframework.checker.nullness.qual.Nullable;
1612

1713
/**
1814
* Rewrites matching bytecode to a generated method which will invoke the static handler on all parameters that need to be converted. That
@@ -25,20 +21,11 @@
2521
*/
2622
public record DirectParameterRewrite(Set<ClassDesc> owners, ClassDesc existingType, TargetedMethodMatcher methodMatcher, Method staticHandler) implements TargetedTypeGeneratedStaticRewrite.Parameter {
2723

28-
public record Versioned(Set<ClassDesc> owners, ClassDesc existingType, NavigableMap<ApiVersion, Map.Entry<TargetedMethodMatcher, Method>> versions) implements VersionedRuleFactory {
29-
30-
public Versioned {
31-
versions = Collections.unmodifiableNavigableMap(versions);
32-
}
24+
public record Versioned(Set<ClassDesc> owners, ClassDesc existingType, VersionedTargetedMethodMatcher versions) implements VersionedRuleFactory {
3325

3426
@Override
35-
public @Nullable RewriteRule createRule(final ApiVersion apiVersion) {
36-
final Map.@Nullable Entry<ApiVersion, Map.Entry<TargetedMethodMatcher, Method>> apiVersionEntryEntry = this.versions.ceilingEntry(apiVersion);
37-
if (apiVersionEntryEntry == null) {
38-
return null;
39-
}
40-
final Map.Entry<TargetedMethodMatcher, Method> entry = apiVersionEntryEntry.getValue();
41-
return new DirectParameterRewrite(this.owners, this.existingType, entry.getKey(), entry.getValue());
27+
public RewriteRule createRule(final ApiVersion apiVersion) {
28+
return this.versions.ruleForVersion(apiVersion, pair -> new DirectParameterRewrite(this.owners, this.existingType, pair.matcher(), pair.staticHandler()));
4229
}
4330
}
4431
}

src/main/java/io/papermc/asm/rules/method/params/FuzzyParameterRewrite.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
package io.papermc.asm.rules.method.params;
22

33
import io.papermc.asm.ClassProcessingContext;
4+
import io.papermc.asm.rules.RewriteRule;
45
import io.papermc.asm.rules.builder.matcher.method.targeted.TargetedMethodMatcher;
56
import io.papermc.asm.rules.method.generated.TargetedTypeGeneratedStaticRewrite;
67
import io.papermc.asm.rules.method.rewrite.MethodRewrite;
8+
import io.papermc.asm.versioned.ApiVersion;
9+
import io.papermc.asm.versioned.VersionedRuleFactory;
10+
import io.papermc.asm.versioned.matcher.targeted.VersionedTargetedMethodMatcher;
711
import java.lang.constant.ClassDesc;
812
import java.lang.constant.ConstantDescs;
913
import java.lang.constant.MethodTypeDesc;
@@ -53,4 +57,12 @@ public MethodRewrite<MethodCallData> createRewrite(final ClassProcessingContext
5357
arguments[MethodRewrite.DYNAMIC_TYPE_IDX] = Type.getMethodType(newDynamicMethodType.descriptorString());
5458
});
5559
}
60+
61+
public record Versioned(Set<ClassDesc> owners, ClassDesc existingType, VersionedTargetedMethodMatcher versions) implements VersionedRuleFactory {
62+
63+
@Override
64+
public RewriteRule createRule(final ApiVersion apiVersion) {
65+
return this.versions.ruleForVersion(apiVersion, pair -> new FuzzyParameterRewrite(this.owners, this.existingType, pair.matcher(), pair.staticHandler()));
66+
}
67+
}
5668
}

src/main/java/io/papermc/asm/rules/method/params/SuperTypeParamRewrite.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
package io.papermc.asm.rules.method.params;
22

33
import io.papermc.asm.ClassProcessingContext;
4+
import io.papermc.asm.rules.RewriteRule;
45
import io.papermc.asm.rules.builder.matcher.method.MethodMatcher;
56
import io.papermc.asm.rules.method.OwnableMethodRewriteRule;
67
import io.papermc.asm.rules.method.rewrite.MethodRewrite;
78
import io.papermc.asm.rules.method.rewrite.SimpleRewrite;
9+
import io.papermc.asm.versioned.ApiVersion;
10+
import io.papermc.asm.versioned.VersionedRuleFactory;
11+
import io.papermc.asm.versioned.matcher.VersionedMethodMatcher;
812
import java.lang.constant.ClassDesc;
913
import java.lang.constant.MethodTypeDesc;
1014
import java.util.Set;
@@ -31,4 +35,12 @@ public MethodRewrite<?> rewrite(final ClassProcessingContext context, final bool
3135
private MethodTypeDesc modifyMethodDescriptor(final MethodTypeDesc methodDescriptor) {
3236
return replaceParameters(methodDescriptor, isEqual(this.oldParamType()), this.newParamType());
3337
}
38+
39+
public record Versioned(Set<ClassDesc> owners, ClassDesc newParamType, VersionedMethodMatcher versions) implements VersionedRuleFactory {
40+
41+
@Override
42+
public RewriteRule createRule(final ApiVersion apiVersion) {
43+
return this.versions.ruleForVersion(apiVersion, pair -> new SuperTypeParamRewrite(this.owners(), pair.matcher(), pair.legacyType(), this.newParamType()));
44+
}
45+
}
3446
}

src/main/java/io/papermc/asm/rules/method/returns/SubTypeReturnRewrite.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
package io.papermc.asm.rules.method.returns;
22

33
import io.papermc.asm.ClassProcessingContext;
4+
import io.papermc.asm.rules.RewriteRule;
45
import io.papermc.asm.rules.builder.matcher.method.MethodMatcher;
56
import io.papermc.asm.rules.method.OwnableMethodRewriteRule;
67
import io.papermc.asm.rules.method.rewrite.MethodRewrite;
78
import io.papermc.asm.rules.method.rewrite.SimpleRewrite;
9+
import io.papermc.asm.versioned.ApiVersion;
10+
import io.papermc.asm.versioned.VersionedRuleFactory;
11+
import io.papermc.asm.versioned.matcher.VersionedMethodMatcher;
812
import java.lang.constant.ClassDesc;
913
import java.lang.constant.MethodTypeDesc;
1014
import java.util.Set;
@@ -32,4 +36,12 @@ public record SubTypeReturnRewrite(Set<ClassDesc> owners, MethodMatcher methodMa
3236
private MethodTypeDesc modifyMethodDescriptor(final MethodTypeDesc methodDescriptor) {
3337
return methodDescriptor.changeReturnType(this.newReturnType());
3438
}
39+
40+
public record Versioned(Set<ClassDesc> owners, ClassDesc newReturnType, VersionedMethodMatcher versions) implements VersionedRuleFactory {
41+
42+
@Override
43+
public RewriteRule createRule(final ApiVersion apiVersion) {
44+
return this.versions.ruleForVersion(apiVersion, pair -> new SubTypeReturnRewrite(this.owners(), pair.matcher(), pair.legacyType(), this.newReturnType()));
45+
}
46+
}
3547
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package io.papermc.asm.rules.rename;
2+
3+
import java.lang.constant.ClassDesc;
4+
import java.util.HashMap;
5+
import java.util.Map;
6+
import org.checkerframework.checker.nullness.qual.Nullable;
7+
8+
import static io.papermc.asm.util.DescriptorUtils.desc;
9+
10+
public final class EnumRenameBuilder {
11+
12+
private final ClassDesc enumTypeDesc;
13+
private @Nullable ClassDesc optionalEnumReplacementImpl;
14+
private final Map<String, String> enumFieldRenames = new HashMap<>();
15+
16+
EnumRenameBuilder(final ClassDesc enumTypeDesc) {
17+
this.enumTypeDesc = enumTypeDesc;
18+
}
19+
20+
public EnumRenameBuilder enumReplacementImpl(final Class<?> type) {
21+
return this.enumReplacementImpl(desc(type));
22+
}
23+
24+
public EnumRenameBuilder enumReplacementImpl(final ClassDesc type) {
25+
if (this.enumTypeDesc.equals(type)) {
26+
throw new IllegalArgumentException("Cannot replace an enum with itself");
27+
}
28+
this.optionalEnumReplacementImpl = type;
29+
return this;
30+
}
31+
32+
public EnumRenameBuilder rename(final String legacyName, final String newName) {
33+
this.enumFieldRenames.put(legacyName, newName);
34+
return this;
35+
}
36+
37+
void apply(final RenameRuleBuilder renameRuleBuilder) {
38+
this.enumFieldRenames.forEach((legacyName, newName) -> {
39+
renameRuleBuilder.fieldByDesc(this.enumTypeDesc, legacyName, newName);
40+
});
41+
final Map<String, String> copy = Map.copyOf(this.enumFieldRenames);
42+
renameRuleBuilder.enumValueOfFieldRenames.put(this.enumTypeDesc, new EnumRenamer(this.enumTypeDesc, this.optionalEnumReplacementImpl, copy));
43+
}
44+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package io.papermc.asm.rules.rename;
2+
3+
import java.lang.constant.ClassDesc;
4+
import java.util.Map;
5+
import org.checkerframework.checker.nullness.qual.Nullable;
6+
7+
public record EnumRenamer(ClassDesc typeDesc, @Nullable ClassDesc optionalReplacementImpl, Map<String, String> fieldRenames) {
8+
}

0 commit comments

Comments
 (0)