Skip to content

Commit f6faba4

Browse files
committed
initial "implementation" of the reflection tools. Only a mapping explorer for now.
1 parent 7f1e4fe commit f6faba4

File tree

12 files changed

+22383
-0
lines changed

12 files changed

+22383
-0
lines changed
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
package com.falsepattern.lib.internal;
2+
import lombok.Getter;
3+
4+
import java.io.IOException;
5+
import java.io.OutputStream;
6+
import java.nio.charset.StandardCharsets;
7+
import java.nio.file.Files;
8+
import java.nio.file.Path;
9+
import java.nio.file.Paths;
10+
import java.util.HashMap;
11+
import java.util.List;
12+
import java.util.Map;
13+
import java.util.Objects;
14+
15+
@Getter
16+
class SRGGen {
17+
private static class StringPair {
18+
public final String name;
19+
public final String desc;
20+
21+
private StringPair(String name, String desc) {
22+
this.name = name;
23+
this.desc = desc;
24+
}
25+
26+
@Override
27+
public boolean equals(Object o) {
28+
if (this == o) {
29+
return true;
30+
}
31+
if (o == null || getClass() != o.getClass()) {
32+
return false;
33+
}
34+
StringPair that = (StringPair) o;
35+
return name.equals(that.name) && desc.equals(that.desc);
36+
}
37+
38+
@Override
39+
public int hashCode() {
40+
return Objects.hash(name, desc);
41+
}
42+
43+
@Override
44+
public String toString() {
45+
return name + "," + desc;
46+
}
47+
}
48+
private static Map<String, String> class_notch_srg = new HashMap<>();
49+
private static Map<String, String> class_notch_mcp = new HashMap<>();
50+
private static Map<String, String> class_srg_mcp = new HashMap<>();
51+
private static Map<String, String> class_mcp_srg = new HashMap<>();
52+
private static Map<String, String> class_mcp_notch = new HashMap<>();
53+
private static Map<String, String> field_notch_srg = new HashMap<>();
54+
private static Map<String, String> field_notch_mcp = new HashMap<>();
55+
private static Map<String, String> field_srg_mcp = new HashMap<>();
56+
private static Map<String, String> field_mcp_srg = new HashMap<>();
57+
private static Map<String, String> field_mcp_notch = new HashMap<>();
58+
private static Map<StringPair, StringPair> method_notch_srg = new HashMap<>();
59+
private static Map<StringPair, StringPair> method_notch_mcp = new HashMap<>();
60+
private static Map<StringPair, StringPair> method_srg_mcp = new HashMap<>();
61+
private static Map<StringPair, StringPair> method_mcp_srg = new HashMap<>();
62+
private static Map<StringPair, StringPair> method_mcp_notch = new HashMap<>();
63+
public static void main(String[] args) throws IOException {
64+
Path dir = Paths.get(args[0]);
65+
parseLines(Files.readAllLines(dir.resolve("notch-srg.srg")), class_notch_srg, field_notch_srg, method_notch_srg);
66+
parseLines(Files.readAllLines(dir.resolve("notch-mcp.srg")), class_notch_mcp, field_notch_mcp, method_notch_mcp);
67+
parseLines(Files.readAllLines(dir.resolve("srg-mcp.srg")), class_srg_mcp, field_srg_mcp, method_srg_mcp);
68+
parseLines(Files.readAllLines(dir.resolve("mcp-srg.srg")), class_mcp_srg, field_mcp_srg, method_mcp_srg);
69+
parseLines(Files.readAllLines(dir.resolve("mcp-notch.srg")), class_mcp_notch, field_mcp_notch, method_mcp_notch);
70+
try (OutputStream output = Files.newOutputStream(dir.resolve("classes.csv"))) {
71+
output.write("notch,srg,mcp\n".getBytes(StandardCharsets.UTF_8));
72+
crossValidate(class_notch_srg, class_notch_mcp, class_srg_mcp, class_mcp_srg, class_mcp_notch, output);
73+
}
74+
try (OutputStream output = Files.newOutputStream(dir.resolve("fields.csv"))) {
75+
output.write("notch,srg,mcp\n".getBytes(StandardCharsets.UTF_8));
76+
crossValidate(field_notch_srg, field_notch_mcp, field_srg_mcp, field_mcp_srg, field_mcp_notch, output);
77+
}
78+
79+
try (OutputStream output = Files.newOutputStream(dir.resolve("methods.csv"))) {
80+
output.write("notch,notchdesc,srg,srgdesc,mcp,mcpdesc\n".getBytes(StandardCharsets.UTF_8));
81+
crossValidate(method_notch_srg, method_notch_mcp, method_srg_mcp, method_mcp_srg, method_mcp_notch, output);
82+
}
83+
}
84+
85+
private static boolean crossValidate(Map<?, ?> notch_srg, Map<?, ?> notch_mcp, Map<?, ?> srg_mcp, Map<?, ?> mcp_srg, Map<?, ?> mcp_notch, OutputStream output)
86+
throws IOException {
87+
for (Map.Entry<?, ?> notch_srg_entry: notch_srg.entrySet()) {
88+
Object notch = notch_srg_entry.getKey();
89+
Object srg = notch_srg_entry.getValue();
90+
Object mcp = notch_mcp.get(notch);
91+
if (!srg_mcp.get(srg).equals(mcp) ||
92+
!mcp_srg.get(mcp).equals(srg) ||
93+
!mcp_notch.get(mcp).equals(notch)) {
94+
throw new RuntimeException(notch + " - " + srg + " - " + mcp);
95+
}
96+
output.write((notch + "," + srg + "," + mcp + "\n").getBytes(StandardCharsets.UTF_8));
97+
}
98+
return true;
99+
}
100+
101+
private static void parseLines(List<String> lines, Map<String, String> classes, Map<String, String> fields, Map<StringPair, StringPair> methods) {
102+
for (String line: lines) {
103+
String[] parts = line.split(" ");
104+
switch (parts[0]) {
105+
case "CL:":
106+
classes.put(parts[1], parts[2]);
107+
break;
108+
case "FD:":
109+
fields.put(parts[1], parts[2]);
110+
break;
111+
case "MD:":
112+
methods.put(new StringPair(parts[1], parts[2]), new StringPair(parts[3], parts[4]));
113+
break;
114+
}
115+
}
116+
}
117+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package com.falsepattern.lib.reflection;
2+
3+
import com.falsepattern.lib.reflection.types.MappingType;
4+
import lombok.EqualsAndHashCode;
5+
import lombok.Getter;
6+
import lombok.NonNull;
7+
import lombok.ToString;
8+
import lombok.experimental.Accessors;
9+
10+
import java.util.Map;
11+
import java.util.function.Function;
12+
13+
@Accessors(fluent = true)
14+
@ToString
15+
@EqualsAndHashCode
16+
@Getter
17+
public class MappedString {
18+
public final String notch;
19+
public final String srg;
20+
public final String mcp;
21+
public MappedString(String[] source, int offset, int stride, Function<String, String> remapper, Map<String, String> stringPool) {
22+
notch = stringPool.computeIfAbsent(remapper.apply(source[offset ]), (str) -> str);
23+
srg = stringPool.computeIfAbsent(remapper.apply(source[offset + stride ]), (str) -> str);
24+
mcp = stringPool.computeIfAbsent(remapper.apply(source[offset + stride * 2]), (str) -> str);
25+
}
26+
27+
public String get(@NonNull MappingType type) {
28+
switch (type) {
29+
case Notch:
30+
return notch;
31+
case SRG:
32+
return srg;
33+
case MCP:
34+
return mcp;
35+
default:
36+
throw new IllegalArgumentException("Invalid enum value " + type);
37+
}
38+
}
39+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package com.falsepattern.lib.reflection;
2+
3+
import com.falsepattern.lib.internal.FalsePatternLib;
4+
import com.falsepattern.lib.reflection.storage.Lookup;
5+
import com.falsepattern.lib.reflection.types.MappingType;
6+
import com.falsepattern.lib.reflection.types.NameType;
7+
import com.falsepattern.lib.util.ResourceUtil;
8+
import lombok.NonNull;
9+
import lombok.SneakyThrows;
10+
import lombok.val;
11+
12+
import java.io.IOException;
13+
import java.util.HashMap;
14+
15+
public class MappingManager {
16+
private static boolean initialized = false;
17+
18+
private static final Lookup<UniversalClass> internalLookup = new Lookup<>();
19+
private static final Lookup<UniversalClass> regularLookup = new Lookup<>();
20+
21+
22+
@SneakyThrows
23+
private static synchronized void initialize() {
24+
if (initialized) return;
25+
initialized = true;
26+
val stringPool = new HashMap<String, String>();
27+
{
28+
val classMappings = ResourceUtil.getResourceStringFromJar("/classes.csv", FalsePatternLib.class).split("\n");
29+
for (int i = 1; i < classMappings.length; i++) {
30+
val line = classMappings[i].split(",");
31+
val clazz = new UniversalClass(line, stringPool);
32+
internalLookup.unwrap(clazz.internalName, clazz);
33+
regularLookup.unwrap(clazz.regularName, clazz);
34+
}
35+
}
36+
{
37+
val fieldMappings = ResourceUtil.getResourceStringFromJar("/fields.csv", FalsePatternLib.class).split("\n");
38+
for (int i = 1; i < fieldMappings.length; i++) {
39+
val line = fieldMappings[i].split(",");
40+
val field = new UniversalField(line, stringPool);
41+
val clazz = internalLookup.get(MappingType.Notch, line[0].substring(0, line[0].lastIndexOf('/')));
42+
clazz.addField(field);
43+
}
44+
}
45+
{
46+
val methodMappings = ResourceUtil.getResourceStringFromJar("/methods.csv", FalsePatternLib.class).split("\n");
47+
for (int i = 1; i < methodMappings.length; i++) {
48+
val line = methodMappings[i].split(",");
49+
val field = new UniversalMethod(line, stringPool);
50+
val clazz = internalLookup.get(MappingType.Notch, line[0].substring(0, line[0].lastIndexOf('/')));
51+
clazz.addMethod(field);
52+
}
53+
}
54+
}
55+
56+
public static UniversalClass classForName(@NonNull NameType nameType, @NonNull MappingType mappingType, String className) {
57+
initialize();
58+
switch (nameType) {
59+
case Internal:
60+
return internalLookup.get(mappingType, className);
61+
case Regular:
62+
return regularLookup.get(mappingType, className);
63+
default:
64+
throw new IllegalArgumentException("Invalid enum value " + nameType);
65+
}
66+
}
67+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package com.falsepattern.lib.reflection;
2+
3+
import com.falsepattern.lib.reflection.storage.Lookup;
4+
import com.falsepattern.lib.reflection.types.MappingType;
5+
import com.falsepattern.lib.reflection.types.NameType;
6+
import lombok.EqualsAndHashCode;
7+
import lombok.Getter;
8+
import lombok.NonNull;
9+
import lombok.ToString;
10+
import lombok.experimental.Accessors;
11+
12+
import java.util.Map;
13+
14+
@Accessors(fluent = true)
15+
@ToString
16+
@EqualsAndHashCode
17+
public class UniversalClass {
18+
@Getter
19+
public final MappedString internalName;
20+
@Getter
21+
public final MappedString regularName;
22+
23+
private final Lookup<UniversalField> fields = new Lookup<>();
24+
private final Lookup<UniversalMethod> methods = new Lookup<>();
25+
26+
public UniversalClass(String[] names, Map<String, String> stringPool) {
27+
internalName = new MappedString(names, 0, 1, (str) -> str, stringPool);
28+
regularName = new MappedString(names, 0, 1, (str) -> str.replace('/', '.'), stringPool);
29+
}
30+
31+
public void addField(UniversalField field) {
32+
fields.unwrap(field.name, field);
33+
}
34+
35+
public void addMethod(UniversalMethod method) {
36+
methods.unwrap(method.name, method);
37+
}
38+
39+
public String getName(@NonNull NameType nameType, @NonNull MappingType mappingType) {
40+
switch (nameType) {
41+
case Internal:
42+
return internalName.get(mappingType);
43+
case Regular:
44+
return regularName.get(mappingType);
45+
default:
46+
throw new IllegalArgumentException("Invalid enum value " + nameType);
47+
}
48+
}
49+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.falsepattern.lib.reflection;
2+
3+
import com.falsepattern.lib.reflection.types.MappingType;
4+
import lombok.EqualsAndHashCode;
5+
import lombok.Getter;
6+
import lombok.NonNull;
7+
import lombok.ToString;
8+
import lombok.experimental.Accessors;
9+
10+
import java.util.Map;
11+
12+
@Accessors(fluent = true)
13+
@ToString
14+
@EqualsAndHashCode
15+
public class UniversalField {
16+
@Getter
17+
public final MappedString name;
18+
19+
public UniversalField(String[] names, Map<String, String> stringPool) {
20+
name = new MappedString(names, 0, 1, (str) -> str.substring(str.lastIndexOf('/') + 1), stringPool);
21+
}
22+
23+
public String getName(@NonNull MappingType mappingType) {
24+
return name.get(mappingType);
25+
}
26+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package com.falsepattern.lib.reflection;
2+
3+
import com.falsepattern.lib.reflection.types.MappingType;
4+
import lombok.EqualsAndHashCode;
5+
import lombok.Getter;
6+
import lombok.NonNull;
7+
import lombok.ToString;
8+
import lombok.experimental.Accessors;
9+
10+
import java.util.Map;
11+
12+
@Accessors(fluent = true)
13+
@ToString
14+
@EqualsAndHashCode
15+
public class UniversalMethod {
16+
@Getter
17+
public final MappedString name;
18+
@Getter
19+
public final MappedString descriptor;
20+
21+
public UniversalMethod(String[] names, Map<String, String> stringPool) {
22+
name = new MappedString(names, 0, 2, (str) -> str.substring(str.lastIndexOf('/') + 1), stringPool);
23+
descriptor = new MappedString(names, 1, 2, (str) -> str, stringPool);
24+
}
25+
26+
public String getName(@NonNull MappingType mappingType) {
27+
return name.get(mappingType);
28+
}
29+
30+
public String getDescriptor(@NonNull MappingType mappingType) {
31+
return descriptor.get(mappingType);
32+
}
33+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package com.falsepattern.lib.reflection.storage;
2+
3+
import com.falsepattern.lib.reflection.MappedString;
4+
import com.falsepattern.lib.reflection.types.MappingType;
5+
import lombok.EqualsAndHashCode;
6+
import lombok.NonNull;
7+
import lombok.experimental.Accessors;
8+
9+
import java.util.HashMap;
10+
import java.util.Map;
11+
12+
@Accessors(fluent = true)
13+
@EqualsAndHashCode
14+
public class Lookup<T> {
15+
private final Map<String, T> notch = new HashMap<>();
16+
private final Map<String, T> srg = new HashMap<>();
17+
private final Map<String, T> mcp = new HashMap<>();
18+
19+
public void unwrap(MappedString mappedString, T value) {
20+
notch.put(mappedString.notch, value);
21+
srg.put(mappedString.srg, value);
22+
mcp.put(mappedString.mcp, value);
23+
}
24+
25+
public T get(@NonNull MappingType mappingType, @NonNull String key) {
26+
switch (mappingType) {
27+
case Notch:
28+
return notch.get(key);
29+
case SRG:
30+
return srg.get(key);
31+
case MCP:
32+
return mcp.get(key);
33+
default:
34+
throw new IllegalArgumentException("Invalid enum value " + mappingType);
35+
}
36+
}
37+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.falsepattern.lib.reflection.types;
2+
3+
public enum MappingType {
4+
Notch,
5+
SRG,
6+
MCP
7+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package com.falsepattern.lib.reflection.types;
2+
3+
public enum NameType {
4+
Internal,
5+
Regular
6+
}

0 commit comments

Comments
 (0)