aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/moe/nea/firmament/init/Intermediary.java
blob: 3513a6b5d738a0ef3e855f71bda3ffe6cdcada3b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package moe.nea.firmament.init;

import net.fabricmc.loader.api.FabricLoader;
import net.fabricmc.loader.api.MappingResolver;
import org.objectweb.asm.Type;

import java.util.List;

public class Intermediary {
	private static final MappingResolver RESOLVER = FabricLoader.getInstance().getMappingResolver();

	static InterMethod intermediaryMethod(Object object, InterClass returnType, InterClass... args) {
		throw new AssertionError("Cannot be called at runtime");
	}

	static <T> InterClass intermediaryClass() {
		throw new AssertionError("Cannot be called at runtime");
	}

	public static InterClass ofIntermediaryClass(String interClass) {
		return new InterClass(Type.getObjectType(interClass.replace('.', '/')));
	}

	public static InterClass ofClass(Class<?> unmappedClass) {
		return new InterClass(Type.getType(unmappedClass));
	}

	public static InterMethod ofMethod(String intermediary, String ownerType, InterClass returnType, InterClass... argTypes) {
		return new InterMethod(intermediary, ofIntermediaryClass(ownerType), returnType, List.of(argTypes));
	}

	public record InterClass(
		Type intermediary
	) {
		public Type mapped() {
			if (intermediary().getSort() != Type.OBJECT)
				return intermediary();
			return Type.getObjectType(RESOLVER.mapClassName("intermediary", intermediary().getClassName())
				.replace('.', '/'));
		}
	}

	public record InterMethod(
		String intermediary,
		InterClass ownerType,
		InterClass returnType,
		List<InterClass> argumentTypes
	) {
		public Type intermediaryDesc() {
			return Type.getMethodType(
				returnType.intermediary(),
				argumentTypes().stream().map(InterClass::intermediary).toArray(Type[]::new)
			);
		}

		public Type mappedDesc() {
			return Type.getMethodType(
				returnType.mapped(),
				argumentTypes().stream().map(InterClass::mapped).toArray(Type[]::new)
			);
		}

		public String mapped() {
			return RESOLVER.mapMethodName(
				"intermediary",
				ownerType.intermediary().getClassName(),
				intermediary(),
				intermediaryDesc().getDescriptor()
			);
		}
	}
}