Skip to content

Commit f15781a

Browse files
committed
Add useResolvedOwners option to swap the owner in member accesses with the resolved class.
Original fix by @KabanFriends and reported by @kennytv in #87
1 parent ffae101 commit f15781a

File tree

3 files changed

+63
-17
lines changed

3 files changed

+63
-17
lines changed

src/main/java/net/fabricmc/tinyremapper/AsmClassRemapper.java

+38-7
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,10 @@ private static class AsmMethodRemapper extends MethodRemapper {
198198
this.inferNameFromSameLvIndex = inferNameFromSameLvIndex;
199199
}
200200

201+
private AsmRemapper getRemapper() {
202+
return (AsmRemapper) remapper;
203+
}
204+
201205
@Override
202206
public AnnotationVisitor createAnnotationRemapper(String descriptor, AnnotationVisitor annotationVisitor) {
203207
return new AsmAnnotationRemapper(descriptor, annotationVisitor, (AsmRemapper) remapper);
@@ -240,21 +244,48 @@ public void visitMultiANewArrayInsn(String descriptor, int numDimensions) {
240244
}
241245

242246
@Override
243-
public void visitFieldInsn(int opcode, String owner, String name, String descriptor) {
247+
public void visitFieldInsn(int opcode, String owner, String name, String desc) {
244248
if (checkPackageAccess) {
245-
PackageAccessChecker.checkMember(this.owner, owner, name, descriptor, TrMember.MemberType.FIELD, "field instruction", (AsmRemapper) remapper);
249+
PackageAccessChecker.checkMember(this.owner, owner, name, desc, TrMember.MemberType.FIELD, "field instruction", (AsmRemapper) remapper);
250+
}
251+
252+
AsmRemapper remapper = getRemapper();
253+
ClassInstance cls = remapper.getClass(owner);
254+
MemberInstance member = cls != null ? cls.resolveField(name, desc) : null;
255+
256+
name = remapper.mapFieldName(cls, member, name, desc);
257+
258+
if (remapper.tr.useResolvedOwners && member != null && member.getOwner() != cls) {
259+
owner = member.getOwner().getName();
246260
}
247261

248-
super.visitFieldInsn(opcode, owner, name, descriptor);
262+
mv.visitFieldInsn(opcode,
263+
remapper.mapType(owner),
264+
name,
265+
remapper.mapDesc(desc));
249266
}
250267

251268
@Override
252-
public void visitMethodInsn(int opcode, String owner, String name, String descriptor, boolean isInterface) {
269+
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean isInterface) {
253270
if (checkPackageAccess) {
254-
PackageAccessChecker.checkMember(this.owner, owner, name, descriptor, TrMember.MemberType.METHOD, "method instruction", (AsmRemapper) remapper);
271+
PackageAccessChecker.checkMember(this.owner, owner, name, desc, TrMember.MemberType.METHOD, "method instruction", (AsmRemapper) remapper);
272+
}
273+
274+
AsmRemapper remapper = getRemapper();
275+
ClassInstance cls = remapper.getClass(owner);
276+
MemberInstance member = cls != null ? cls.resolveMethod(name, desc) : null;
277+
278+
name = remapper.mapMethodName(cls, member, name, desc);
279+
280+
if (remapper.tr.useResolvedOwners && member != null && member.getOwner() != cls) {
281+
owner = member.getOwner().getName();
255282
}
256283

257-
super.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
284+
mv.visitMethodInsn(opcode,
285+
remapper.mapType(owner),
286+
name,
287+
remapper.mapMethodDesc(desc),
288+
isInterface);
258289
}
259290

260291
@Override
@@ -271,7 +302,7 @@ public void visitInvokeDynamicInsn(String name, String descriptor, Handle bootst
271302
bootstrapMethodArguments[i] = remapper.mapValue(bootstrapMethodArguments[i]);
272303
}
273304

274-
// bypass remapper
305+
// bypass remapper, TODO: implement useResolvedOwners
275306
mv.visitInvokeDynamicInsn(name,
276307
remapper.mapMethodDesc(descriptor), (Handle) remapper.mapValue(bootstrapMethodHandle),
277308
bootstrapMethodArguments);

src/main/java/net/fabricmc/tinyremapper/AsmRemapper.java

+10-7
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,12 @@ public String mapFieldName(String owner, String name, String desc) {
4848
ClassInstance cls = getClass(owner);
4949
if (cls == null) return name;
5050

51-
return mapFieldName(cls, name, desc);
51+
MemberInstance member = cls.resolveField(name, desc);
52+
53+
return mapFieldName(cls, member, name, desc);
5254
}
5355

54-
final String mapFieldName(ClassInstance cls, String name, String desc) {
55-
MemberInstance member = cls.resolve(TrMember.MemberType.FIELD, MemberInstance.getFieldId(name, desc, tr.ignoreFieldDesc));
56+
final String mapFieldName(ClassInstance cls, MemberInstance member, String name, String desc) {
5657
String newName;
5758

5859
if (member != null && (newName = member.getNewName()) != null) {
@@ -78,11 +79,12 @@ public String mapMethodName(String owner, String name, String desc) {
7879
ClassInstance cls = getClass(owner);
7980
if (cls == null) return name; // TODO: try to map these from just the mappings?, warn if actual class is missing
8081

81-
return mapMethodName(cls, name, desc);
82+
MemberInstance member = cls.resolveMethod(name, desc);
83+
84+
return mapMethodName(cls, member, name, desc);
8285
}
8386

84-
final String mapMethodName(ClassInstance cls, String name, String desc) {
85-
MemberInstance member = cls.resolve(TrMember.MemberType.METHOD, MemberInstance.getMethodId(name, desc));
87+
final String mapMethodName(ClassInstance cls, MemberInstance member, String name, String desc) {
8688
String newName;
8789

8890
if (member != null && (newName = member.getNewName()) != null) {
@@ -134,6 +136,7 @@ public String mapMethodArg(String methodOwner, String methodName, String methodD
134136
return originatingNewName != null ? originatingNewName : name;
135137
}
136138

139+
@Override
137140
public String mapMethodVar(String methodOwner, String methodName, String methodDesc, int lvIndex, int startOpIdx, int asmIndex, String name) {
138141
return name; // TODO: implement
139142
}
@@ -148,7 +151,7 @@ public String mapAnnotationAttributeName(final String annotationDesc, final Stri
148151
String annotationClass = Type.getType(annotationDesc).getInternalName();
149152

150153
if (attributeDesc == null) {
151-
return this.mapMethodNamePrefixDesc(annotationClass, name, "()");
154+
return mapMethodNamePrefixDesc(annotationClass, name, "()");
152155
} else {
153156
return this.mapMethodName(annotationClass, name, "()" + attributeDesc);
154157
}

src/main/java/net/fabricmc/tinyremapper/TinyRemapper.java

+15-3
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,14 @@ public Builder resolveMissing(boolean value) {
132132
return this;
133133
}
134134

135+
/**
136+
* Whether to use the resolved owner class instead of the current class for member accesses.
137+
*/
138+
public Builder useResolvedOwners(boolean value) {
139+
useResolvedOwners = value;
140+
return this;
141+
}
142+
135143
public Builder checkPackageAccess(boolean value) {
136144
checkPackageAccess = value;
137145
return this;
@@ -217,7 +225,7 @@ public TinyRemapper build() {
217225
keepInputData,
218226
forcePropagation, propagatePrivate,
219227
propagateBridges, propagateRecordComponents,
220-
removeFrames, ignoreConflicts, resolveMissing, checkPackageAccess || fixPackageAccess, fixPackageAccess,
228+
removeFrames, ignoreConflicts, resolveMissing, useResolvedOwners, checkPackageAccess || fixPackageAccess, fixPackageAccess,
221229
rebuildSourceFilenames, skipLocalMapping, renameInvalidLocals, invalidLvNamePattern, inferNameFromSameLvIndex,
222230
analyzeVisitors, stateProcessors, preApplyVisitors, postApplyVisitors,
223231
extraRemapper);
@@ -236,6 +244,7 @@ public TinyRemapper build() {
236244
private boolean removeFrames = false;
237245
private boolean ignoreConflicts = false;
238246
private boolean resolveMissing = false;
247+
private boolean useResolvedOwners = false;
239248
private boolean checkPackageAccess = false;
240249
private boolean fixPackageAccess = false;
241250
private boolean rebuildSourceFilenames = false;
@@ -274,6 +283,7 @@ private TinyRemapper(Collection<IMappingProvider> mappingProviders, boolean igno
274283
boolean removeFrames,
275284
boolean ignoreConflicts,
276285
boolean resolveMissing,
286+
boolean useResolvedOwners,
277287
boolean checkPackageAccess,
278288
boolean fixPackageAccess,
279289
boolean rebuildSourceFilenames,
@@ -294,6 +304,7 @@ private TinyRemapper(Collection<IMappingProvider> mappingProviders, boolean igno
294304
this.removeFrames = removeFrames;
295305
this.ignoreConflicts = ignoreConflicts;
296306
this.resolveMissing = resolveMissing;
307+
this.useResolvedOwners = useResolvedOwners;
297308
this.checkPackageAccess = checkPackageAccess;
298309
this.fixPackageAccess = fixPackageAccess;
299310
this.rebuildSourceFilenames = rebuildSourceFilenames;
@@ -1089,10 +1100,10 @@ private byte[] fixClass(ClassInstance cls, byte[] data) {
10891100
String mappedName, mappedDesc;
10901101

10911102
if (member.type == TrMember.MemberType.FIELD) {
1092-
mappedName = remapper.mapFieldName(cls, member.name, member.desc);
1103+
mappedName = remapper.mapFieldName(cls, member, member.name, member.desc);
10931104
mappedDesc = remapper.mapDesc(member.desc);
10941105
} else {
1095-
mappedName = remapper.mapMethodName(cls, member.name, member.desc);
1106+
mappedName = remapper.mapMethodName(cls, member, member.name, member.desc);
10961107
mappedDesc = remapper.mapMethodDesc(member.desc);
10971108
}
10981109

@@ -1311,6 +1322,7 @@ public void propagate(TrMember m, String newName) {
13111322
private final boolean removeFrames;
13121323
private final boolean ignoreConflicts;
13131324
private final boolean resolveMissing;
1325+
final boolean useResolvedOwners;
13141326
private final boolean checkPackageAccess;
13151327
private final boolean fixPackageAccess;
13161328
private final boolean rebuildSourceFilenames;

0 commit comments

Comments
 (0)