Skip to content

Commit a933e82

Browse files
committed
Handle ModifyExpressionValue in UTP
1 parent 8310fbd commit a933e82

7 files changed

Lines changed: 95 additions & 0 deletions

File tree

definition/src/main/java/org/sinytra/adapter/patch/api/MixinConstants.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ public class MixinConstants {
1818
public static final String INVOKER = "Lorg/spongepowered/asm/mixin/gen/Invoker;";
1919
// Mixinextras annotations
2020
public static final String MODIFY_EXPR_VAL = "Lcom/llamalad7/mixinextras/injector/ModifyExpressionValue;";
21+
public static final String MODIFY_EXPR_VAL_INTERNAL_NAME = "com/llamalad7/mixinextras/injector/ModifyExpressionValue";
2122
public static final String MODIFY_RETURN_VAL = "Lcom/llamalad7/mixinextras/injector/ModifyReturnValue;";
2223
public static final String WRAP_OPERATION = "Lcom/llamalad7/mixinextras/injector/wrapoperation/WrapOperation;";
2324
public static final String WRAP_OPERATION_INTERNAL_NAME = "com/llamalad7/mixinextras/injector/wrapoperation/WrapOperation";
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package org.sinytra.adapter.next.env.ann;
2+
3+
import org.sinytra.adapter.patch.util.MethodQualifier;
4+
5+
public class ModifyExpressionValueMixinData extends MixinData {
6+
public ModifyExpressionValueMixinData(ClassTarget targetClass, MethodQualifier targetMethod, AtData atData) {
7+
super(targetClass, targetMethod, atData);
8+
}
9+
}

definition/src/next/java/org/sinytra/adapter/next/env/param/MethodParameters.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import java.util.*;
88
import java.util.function.Predicate;
99

10+
// TODO Support for @Local
1011
public class MethodParameters {
1112
public sealed interface ParamGroup {
1213
ParamGroup METHOD_PARAMS = new Variable("method_params");

definition/src/next/java/org/sinytra/adapter/next/type/MixinTypes.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ public class MixinTypes {
1919
registerMixinType(ModifyArg.class, new ModifyArgMixin());
2020
registerMixinType(Redirect.class, new RedirectMixin());
2121
registerMixinType(MixinConstants.WRAP_OPERATION_INTERNAL_NAME, new WrapOperationMixin());
22+
registerMixinType(MixinConstants.MODIFY_EXPR_VAL_INTERNAL_NAME, new ModifyExpressionValueMixin());
2223
}
2324

2425
@Nullable
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package org.sinytra.adapter.next.type;
2+
3+
import org.objectweb.asm.Type;
4+
import org.sinytra.adapter.next.env.MixinContext;
5+
import org.sinytra.adapter.next.env.ann.AtData;
6+
import org.sinytra.adapter.next.env.ann.ClassTarget;
7+
import org.sinytra.adapter.next.env.ann.ModifyExpressionValueMixinData;
8+
import org.sinytra.adapter.next.env.param.MethodParameters;
9+
import org.sinytra.adapter.next.pipeline.Recipe;
10+
import org.sinytra.adapter.next.pipeline.config.Configuration;
11+
import org.sinytra.adapter.next.pipeline.config.MutableConfiguration;
12+
import org.sinytra.adapter.patch.analysis.selector.AnnotationHandle;
13+
import org.sinytra.adapter.patch.util.MethodQualifier;
14+
15+
import java.util.List;
16+
17+
import static org.sinytra.adapter.next.env.param.MethodParameters.ParamGroup.*;
18+
19+
public class ModifyExpressionValueMixin implements MixinType<ModifyExpressionValueMixinData> {
20+
@Override
21+
public ModifyExpressionValueMixinData parse(MixinContext context, ClassTarget targetClass, MethodQualifier targetMethod, AtData atData, AnnotationHandle handle) {
22+
return new ModifyExpressionValueMixinData(targetClass, targetMethod, atData);
23+
}
24+
25+
@Override
26+
public void preProcess(ModifyExpressionValueMixinData mixin, MixinContext context, MutableConfiguration clean, Recipe recipe) {
27+
clean.setParameters(MethodParameters.create(context.methodNode().desc, List.of(SINGLE_ANY, CAPTURED_PARAMS)));
28+
}
29+
30+
// TODO Find universal way of handling captured method params
31+
@Override
32+
public void postProcess(ModifyExpressionValueMixinData mixin, MixinContext context, Configuration clean, MutableConfiguration dirty, Recipe recipe) {
33+
if (dirty.getTargetMethod() == null) return;
34+
35+
MethodQualifier targetDesc = dirty.getAtData().getTarget().flatMap(MethodQualifier::create).orElse(null);
36+
if (targetDesc == null) return;
37+
38+
List<Type> dirtyCaptured = context.methods().resolveCapturedMethodParams(recipe.clean(), recipe.dirty());
39+
Type modifyingType = Type.getReturnType(targetDesc.desc());
40+
41+
MethodParameters params = MethodParameters.builder()
42+
.put(SINGLE_ANY, modifyingType)
43+
.put(CAPTURED_PARAMS, dirtyCaptured)
44+
.build();
45+
46+
dirty.setParameters(params);
47+
dirty.setReturnType(modifyingType);
48+
}
49+
}

test/src/test/java/org/sinytra/adapter/patch/test/mixin/DynamicMixinPatchTest.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,15 @@ void testChangedTargetMethodWrapOperation() throws Exception {
6565
);
6666
}
6767

68+
@Test
69+
void testChangedTargetMethodModifyExpressionValue() throws Exception {
70+
assertSameCode(
71+
"org/sinytra/adapter/test/mixin/pipeline/CropBlockMixin",
72+
"getAvailableMoisture",
73+
assertTargetMethod()
74+
);
75+
}
76+
6877
@Test
6978
void testChangeMethodParamsInPipeline() throws Exception {
7079
assertSameCode(

test/src/testClasses/java/org/sinytra/adapter/test/mixin/pipeline/CropBlockMixin.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.sinytra.adapter.test.mixin.pipeline;
22

3+
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
34
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
45
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
56
import net.minecraft.world.level.block.Block;
@@ -32,4 +33,28 @@ private static boolean isOnFarmland(BlockState instance, Block block, Operation<
3233
private static boolean isOnFarmlandExpected(BlockState instance, Block block, Operation<Boolean> original) {
3334
return Blocks.FARMLAND.equals(block) || original.call(instance, block);
3435
}
36+
37+
@ModifyExpressionValue(
38+
method = "getGrowthSpeed(Lnet/minecraft/world/level/block/Block;Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;)F",
39+
at = @At(
40+
value = "INVOKE",
41+
ordinal = 0,
42+
target = "Lnet/minecraft/world/level/BlockGetter;getBlockState(Lnet/minecraft/core/BlockPos;)Lnet/minecraft/world/level/block/state/BlockState;"
43+
)
44+
)
45+
private static BlockState getAvailableMoisture(BlockState original) {
46+
return original;
47+
}
48+
49+
@ModifyExpressionValue(
50+
method = "getGrowthSpeed(Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;)F",
51+
at = @At(
52+
value = "INVOKE",
53+
ordinal = 0,
54+
target = "Lnet/minecraft/world/level/BlockGetter;getBlockState(Lnet/minecraft/core/BlockPos;)Lnet/minecraft/world/level/block/state/BlockState;"
55+
)
56+
)
57+
private static BlockState getAvailableMoistureExpected(BlockState original) {
58+
return original;
59+
}
3560
}

0 commit comments

Comments
 (0)