Skip to content

Commit a8a57ea

Browse files
authored
Catch conflicts when multiple parameters in the same scope get renamed to the same name (#48)
1 parent 81d66a5 commit a8a57ea

File tree

5 files changed

+65
-4
lines changed

5 files changed

+65
-4
lines changed

parchment/src/main/java/net/neoforged/jst/parchment/GatherReplacementsVisitor.java

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ class GatherReplacementsVisitor extends PsiRecursiveElementVisitor {
3939
* this may contain the parameters of multiple scopes simultaneously.
4040
*/
4141
private final Map<PsiParameter, String> activeParameters = new IdentityHashMap<>();
42+
/**
43+
* The parameter names that have already been used by a method in the outer scope and
44+
* therefore cannot be used in nested methods.
45+
*/
46+
private final Set<String> activeNames = new HashSet<>();
4247

4348
public GatherReplacementsVisitor(NamesAndDocsDatabase namesAndDocs,
4449
boolean enableJavadoc,
@@ -134,8 +139,23 @@ else if (PsiHelper.isNonStaticInnerClass(psiMethod.getContainingClass())) {
134139
if (paramData != null && paramData.getName() != null && !PsiHelper.isRecordConstructor(psiMethod)) {
135140
var paramName = namer.apply(paramData.getName());
136141

142+
// We cannot rename a parameter to name that was already taken in this scope
143+
if (activeNames.contains(paramName)) {
144+
// If we have no conflict resolver then we simply don't try to rename this parameter
145+
if (conflictResolver == null) {
146+
parameterOrder.add(psiParameter.getName());
147+
continue;
148+
}
149+
150+
// Keep applying the conflict resolver until the name is no longer used
151+
while (activeNames.contains(paramName)) {
152+
paramName = conflictResolver.apply(paramName);
153+
}
154+
}
155+
137156
// Replace parameters within the method body
138157
activeParameters.put(psiParameter, paramName);
158+
activeNames.add(paramName);
139159

140160
// Find and replace the parameter identifier
141161
replacements.replace(psiParameter.getNameIdentifier(), paramName);
@@ -171,14 +191,17 @@ else if (PsiHelper.isNonStaticInnerClass(psiMethod.getContainingClass())) {
171191
);
172192
}
173193

174-
// When replacements were made and activeParamets were added, we visit the method children here ourselves
194+
// When replacements were made and activeParameters were added, we visit the method children here ourselves
175195
// and clean up active parameters afterward
176196
if (hadReplacements) {
177197
try {
178198
element.acceptChildren(this);
179199
} finally {
180200
for (var parameter : parameters) {
181-
activeParameters.remove(parameter);
201+
var nm = activeParameters.remove(parameter);
202+
if (nm != null) {
203+
activeNames.remove(nm);
204+
}
182205
}
183206
}
184207
return;
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.example;
2+
3+
public class Example {
4+
public void m(String in, String p_in) {
5+
class Nested {
6+
public void m(String p_p_in, String out) {
7+
8+
}
9+
}
10+
}
11+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
tsrg2 left right
2+
obfuscated_c com/example/Example
3+
obfuscated_m (Ljava/lang/String;)V m
4+
0 o in
5+
1 o in
6+
obfuscated_c$nested com/example/Example$1Nested
7+
obfuscated_m (Ljava/lang/String;)V m
8+
0 o in
9+
1 o out
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.example;
2+
3+
public class Example {
4+
public void m(String a1, String ac2) {
5+
class Nested {
6+
public void m(String ac3, String a4) {
7+
8+
}
9+
}
10+
}
11+
}

tests/src/test/java/net/neoforged/jst/tests/EmbeddedTest.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,11 @@ void testTsrgMappings() throws Exception {
224224
void testAnonymousClasses() throws Exception {
225225
runParchmentTest("anonymous_classes", "mappings.tsrg");
226226
}
227+
228+
@Test
229+
void testConflicts() throws Exception {
230+
runParchmentTest("conflicts", "mappings.tsrg", "--parchment-conflict-prefix=p_");
231+
}
227232
}
228233

229234
@Nested
@@ -367,9 +372,11 @@ protected final void runATTest(String testDirName, final String... extraArgs) th
367372
));
368373
}
369374

370-
protected final void runParchmentTest(String testDirName, String mappingsFilename) throws Exception {
375+
protected final void runParchmentTest(String testDirName, String mappingsFilename, String... extraArgs) throws Exception {
371376
testDirName = "parchment/" + testDirName;
372-
runTest(testDirName, UnaryOperator.identity(), "--enable-parchment", "--parchment-mappings", testDataRoot.resolve(testDirName).resolve(mappingsFilename).toString());
377+
var args = new ArrayList<>(Arrays.asList("--enable-parchment", "--parchment-mappings", testDataRoot.resolve(testDirName).resolve(mappingsFilename).toString()));
378+
args.addAll(Arrays.asList(extraArgs));
379+
runTest(testDirName, UnaryOperator.identity(), args.toArray(String[]::new));
373380
}
374381

375382
protected final void runTest(String testDirName, UnaryOperator<String> consoleMapper, String... args) throws Exception {

0 commit comments

Comments
 (0)