Skip to content

Commit 007cfcd

Browse files
Fix 348 (#352)
* add (failing) test for #348 * EntryRemapper: use main jar index for resolution and combined jar index for validation
1 parent fef8a9c commit 007cfcd

6 files changed

Lines changed: 152 additions & 15 deletions

File tree

enigma-server/src/main/java/org/quiltmc/enigma/network/DedicatedEnigmaServer.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,10 +124,10 @@ public static void main(String[] args) {
124124

125125
EntryRemapper mappings;
126126
if (!Files.exists(mappingsFile)) {
127-
mappings = EntryRemapper.mapped(enigma, project.getCombinedIndex(), project.getMappingsIndex(), project.getRemapper().getJarProposedMappings(), new HashEntryTree<>(), enigma.getNameProposalServices());
127+
mappings = EntryRemapper.mapped(project, project.getRemapper().getJarProposedMappings(), new HashEntryTree<>());
128128
} else {
129129
Logger.info("Reading mappings...");
130-
mappings = EntryRemapper.mapped(enigma, project.getCombinedIndex(), project.getMappingsIndex(), project.getRemapper().getJarProposedMappings(), readWriteService.get().read(mappingsFile), enigma.getNameProposalServices());
130+
mappings = EntryRemapper.mapped(project, project.getRemapper().getJarProposedMappings(), readWriteService.get().read(mappingsFile));
131131
}
132132

133133
PrintWriter log = new PrintWriter(Files.newBufferedWriter(logFile));

enigma-swing/src/main/java/org/quiltmc/enigma/gui/GuiController.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -686,7 +686,7 @@ public void createClient(String username, String ip, int port, char[] password)
686686
}
687687

688688
public void createServer(String username, int port, char[] password) throws IOException {
689-
this.server = new IntegratedEnigmaServer(this.project.getJarChecksum(), password, EntryRemapper.mapped(this.project.getEnigma(), this.project.getCombinedIndex(), this.project.getMappingsIndex(), new HashEntryTree<>(this.project.getRemapper().getJarProposedMappings()), new HashEntryTree<>(this.project.getRemapper().getDeobfMappings()), this.project.getEnigma().getNameProposalServices()), port);
689+
this.server = new IntegratedEnigmaServer(this.project.getJarChecksum(), password, EntryRemapper.mapped(this.project, new HashEntryTree<>(this.project.getRemapper().getJarProposedMappings()), new HashEntryTree<>(this.project.getRemapper().getDeobfMappings())), port);
690690
this.server.start();
691691
this.client = new IntegratedEnigmaClient(this, "127.0.0.1", port);
692692
this.client.connect();

enigma/src/main/java/org/quiltmc/enigma/api/EnigmaProject.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ public EnigmaProject(Enigma enigma, Path jarPath, ClassProvider classProvider, J
7878
this.jarChecksum = jarChecksum;
7979

8080
this.mappingsIndex = mappingsIndex;
81-
this.remapper = EntryRemapper.mapped(this.enigma, this.combinedIndex, this.mappingsIndex, proposedNames, new HashEntryTree<>(), this.enigma.getNameProposalServices());
81+
this.remapper = EntryRemapper.mapped(this, proposedNames, new HashEntryTree<>());
8282
}
8383

8484
/**
@@ -97,12 +97,12 @@ public void setMappings(@Nullable EntryTree<EntryMapping> mappings, ProgressList
9797
EntryTree<EntryMapping> mergedTree = EntryTreeUtil.merge(jarProposedMappings, mappings);
9898

9999
this.mappingsIndex.indexMappings(mergedTree, progress);
100-
this.remapper = EntryRemapper.mapped(this.enigma, this.combinedIndex, this.mappingsIndex, jarProposedMappings, mappings, this.enigma.getNameProposalServices());
100+
this.remapper = EntryRemapper.mapped(this, jarProposedMappings, mappings);
101101
} else if (!jarProposedMappings.isEmpty()) {
102102
this.mappingsIndex.indexMappings(jarProposedMappings, progress);
103-
this.remapper = EntryRemapper.mapped(this.enigma, this.combinedIndex, this.mappingsIndex, jarProposedMappings, new HashEntryTree<>(), this.enigma.getNameProposalServices());
103+
this.remapper = EntryRemapper.mapped(this, jarProposedMappings, new HashEntryTree<>());
104104
} else {
105-
this.remapper = EntryRemapper.empty(this.enigma, this.combinedIndex, this.enigma.getNameProposalServices());
105+
this.remapper = EntryRemapper.empty(this);
106106
}
107107

108108
// update dynamically proposed names

enigma/src/main/java/org/quiltmc/enigma/api/translation/mapping/EntryRemapper.java

Lines changed: 67 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import org.jspecify.annotations.NonNull;
44
import org.jspecify.annotations.Nullable;
55
import org.quiltmc.enigma.api.Enigma;
6+
import org.quiltmc.enigma.api.EnigmaProject;
67
import org.quiltmc.enigma.api.analysis.index.jar.InheritanceIndex;
78
import org.quiltmc.enigma.api.analysis.index.jar.JarIndex;
89
import org.quiltmc.enigma.api.analysis.index.mapping.MappingsIndex;
@@ -30,7 +31,7 @@
3031
import java.util.Set;
3132
import java.util.stream.Stream;
3233

33-
public class EntryRemapper {
34+
public final class EntryRemapper {
3435
private final EntryTree<EntryMapping> deobfMappings;
3536
private final EntryTree<EntryMapping> jarProposedMappings;
3637
private final EntryTree<EntryMapping> proposedMappings;
@@ -45,7 +46,12 @@ public class EntryRemapper {
4546
private final MappingValidator validator;
4647
private final List<NameProposalService> proposalServices;
4748

48-
private EntryRemapper(Enigma enigma, JarIndex jarIndex, MappingsIndex mappingsIndex, EntryTree<EntryMapping> jarProposedMappings, EntryTree<EntryMapping> deobfMappings, List<NameProposalService> proposalServices) {
49+
private EntryRemapper(
50+
Enigma enigma, JarIndex jarIndex, JarIndex combinedIndex,
51+
MappingsIndex mappingsIndex,
52+
EntryTree<EntryMapping> jarProposedMappings, EntryTree<EntryMapping> deobfMappings,
53+
List<NameProposalService> proposalServices
54+
) {
4955
this.deobfMappings = deobfMappings;
5056
this.jarProposedMappings = jarProposedMappings;
5157
this.proposedMappings = new HashEntryTree<>(jarProposedMappings);
@@ -58,16 +64,67 @@ private EntryRemapper(Enigma enigma, JarIndex jarIndex, MappingsIndex mappingsIn
5864
this.jarIndex = jarIndex;
5965
this.mappingsIndex = mappingsIndex;
6066

61-
this.validator = new MappingValidator(this.obfResolver, this.deobfuscator, jarIndex, mappingsIndex);
67+
// use combined index for validator so it can find conflicts with lib method names
68+
final EntryResolver combinedResolver = combinedIndex.getEntryResolver();
69+
this.validator = new MappingValidator(combinedResolver, new MappingTranslator(this.mappings, combinedResolver), combinedIndex, mappingsIndex);
6270
this.proposalServices = proposalServices;
6371
}
6472

65-
public static EntryRemapper mapped(Enigma enigma, JarIndex jarIndex, MappingsIndex mappingsIndex, EntryTree<EntryMapping> proposedMappings, EntryTree<EntryMapping> deobfMappings, List<NameProposalService> proposalServices) {
66-
return new EntryRemapper(enigma, jarIndex, mappingsIndex, proposedMappings, deobfMappings, proposalServices);
73+
public static EntryRemapper mapped(
74+
Enigma project, JarIndex jarIndex, JarIndex combinedIndex,
75+
MappingsIndex mappingsIndex,
76+
EntryTree<EntryMapping> proposedMappings, EntryTree<EntryMapping> deobfMappings,
77+
List<NameProposalService> proposalServices
78+
) {
79+
return new EntryRemapper(
80+
project, jarIndex, combinedIndex,
81+
mappingsIndex,
82+
proposedMappings, deobfMappings,
83+
proposalServices
84+
);
6785
}
6886

69-
public static EntryRemapper empty(Enigma enigma, JarIndex index, List<NameProposalService> proposalServices) {
70-
return new EntryRemapper(enigma, index, MappingsIndex.empty(), new HashEntryTree<>(), new HashEntryTree<>(), proposalServices);
87+
/**
88+
* Creates a remapper with the passed {@code project}'s {@linkplain EnigmaProject#getEnigma() enigma} instance,
89+
* {@linkplain EnigmaProject#getJarIndex() jar index}, {@linkplain EnigmaProject#getCombinedIndex() combined index},
90+
* {@linkplain EnigmaProject#getMappingsIndex() mappings index},
91+
* and its enigma instance's {@linkplain Enigma#getNameProposalServices() name proposal services}.
92+
*/
93+
public static EntryRemapper mapped(
94+
EnigmaProject project, EntryTree<EntryMapping> proposedMappings, EntryTree<EntryMapping> deobfMappings
95+
) {
96+
return mapped(
97+
project.getEnigma(), project.getJarIndex(), project.getCombinedIndex(),
98+
project.getMappingsIndex(),
99+
proposedMappings, deobfMappings,
100+
project.getEnigma().getNameProposalServices()
101+
);
102+
}
103+
104+
public static EntryRemapper empty(
105+
Enigma enigma,
106+
JarIndex jarIndex, JarIndex combinedIndex,
107+
List<NameProposalService> proposalServices
108+
) {
109+
return new EntryRemapper(
110+
enigma, jarIndex, combinedIndex,
111+
MappingsIndex.empty(), new HashEntryTree<>(), new HashEntryTree<>(),
112+
proposalServices
113+
);
114+
}
115+
116+
/**
117+
* Creates an empty remapper with the passed {@code project}'s
118+
* {@linkplain EnigmaProject#getEnigma() enigma} instance,
119+
* {@linkplain EnigmaProject#getJarIndex() jar index}, {@linkplain EnigmaProject#getCombinedIndex() combined index},
120+
* and its enigma instance's {@linkplain Enigma#getNameProposalServices() name proposal services}.
121+
*/
122+
public static EntryRemapper empty(EnigmaProject project) {
123+
return empty(
124+
project.getEnigma(),
125+
project.getJarIndex(), project.getCombinedIndex(),
126+
project.getEnigma().getNameProposalServices()
127+
);
71128
}
72129

73130
public void validatePutMapping(ValidationContext vc, Entry<?> obfuscatedEntry, @NonNull EntryMapping deobfMapping) {
@@ -82,7 +139,9 @@ private void doPutMapping(ValidationContext vc, Entry<?> obfuscatedEntry, @NonNu
82139
EntryMapping oldMapping = this.getMapping(obfuscatedEntry);
83140
boolean renaming = !Objects.equals(oldMapping.targetName(), deobfMapping.targetName());
84141

85-
Collection<Entry<?>> resolvedEntries = renaming ? this.resolveAllRoots(obfuscatedEntry) : this.obfResolver.resolveEntry(obfuscatedEntry, ResolutionStrategy.RESOLVE_CLOSEST);
142+
Collection<Entry<?>> resolvedEntries = renaming
143+
? this.resolveAllRoots(obfuscatedEntry)
144+
: this.obfResolver.resolveEntry(obfuscatedEntry, ResolutionStrategy.RESOLVE_CLOSEST);
86145

87146
if (renaming && deobfMapping.targetName() != null) {
88147
for (Entry<?> resolvedEntry : resolvedEntries) {
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package org.quiltmc.enigma;
2+
3+
import org.junit.jupiter.api.Test;
4+
import org.quiltmc.enigma.api.Enigma;
5+
import org.quiltmc.enigma.api.EnigmaProject;
6+
import org.quiltmc.enigma.api.ProgressListener;
7+
import org.quiltmc.enigma.api.class_provider.ClasspathClassProvider;
8+
import org.quiltmc.enigma.api.translation.mapping.EntryMapping;
9+
import org.quiltmc.enigma.api.translation.mapping.serde.MappingFileNameFormat;
10+
import org.quiltmc.enigma.api.translation.mapping.serde.MappingSaveParameters;
11+
import org.quiltmc.enigma.api.translation.representation.entry.LocalVariableEntry;
12+
import org.quiltmc.enigma.util.validation.ValidationContext;
13+
14+
import java.io.IOException;
15+
import java.nio.file.Files;
16+
import java.nio.file.Path;
17+
import java.util.LinkedList;
18+
import java.util.List;
19+
import java.util.stream.Stream;
20+
21+
import static org.junit.jupiter.api.Assertions.assertEquals;
22+
23+
public class TestMainJarMapped {
24+
private static final Path JAR = TestUtil.obfJar("main_jar_mapped");
25+
26+
public static final String TEST_CLASS_NAME = "a";
27+
28+
private static EnigmaProject openProject() {
29+
try {
30+
return Enigma.create().openJar(JAR, new ClasspathClassProvider(), ProgressListener.createEmpty());
31+
} catch (IOException e) {
32+
throw new RuntimeException(e);
33+
}
34+
}
35+
36+
/**
37+
* Tests that when a parameter of a main jar method that's inherited from a lib class is mapped,
38+
* the main jar's parameter is mapped; no lib mapping should be created.
39+
*/
40+
@Test
41+
void test() throws IOException {
42+
final EnigmaProject project = openProject();
43+
44+
final LocalVariableEntry equalsParam = TestEntryFactory.newParameter(
45+
TestEntryFactory.newMethod(TEST_CLASS_NAME, "equals", "(Ljava/lang/Object;)Z"),
46+
1
47+
);
48+
49+
project.getRemapper().putMapping(new ValidationContext(null), equalsParam, new EntryMapping("object"));
50+
51+
final Path mappingsDir = Files.createTempDirectory("main_jar_mapped");
52+
project.getEnigma()
53+
.getReadWriteService(mappingsDir)
54+
.orElseThrow()
55+
.write(
56+
project.getRemapper().getMappings(),
57+
mappingsDir,
58+
new MappingSaveParameters(MappingFileNameFormat.BY_DEOBF, false, null, null)
59+
);
60+
61+
final List<Path> savedFiles = new LinkedList<>();
62+
try (Stream<Path> paths = Files.walk(mappingsDir)) {
63+
paths.filter(Files::isRegularFile).forEach(savedFiles::add);
64+
}
65+
66+
assertEquals(1, savedFiles.size());
67+
68+
assertEquals(mappingsDir.resolve(TEST_CLASS_NAME + ".mapping"), savedFiles.get(0));
69+
}
70+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package org.quiltmc.enigma.input.main_jar_mapped;
2+
3+
public class MainJarMapped {
4+
@Override
5+
public boolean equals(Object o) {
6+
return false;
7+
}
8+
}

0 commit comments

Comments
 (0)