Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add useResolvedOwners option to swap the owner in member accesses with the resolved class #90

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 44 additions & 7 deletions src/main/java/net/fabricmc/tinyremapper/AsmClassRemapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,10 @@ private static class AsmMethodRemapper extends MethodRemapper {
this.inferNameFromSameLvIndex = inferNameFromSameLvIndex;
}

private AsmRemapper getRemapper() {
return (AsmRemapper) remapper;
}

@Override
public AnnotationVisitor createAnnotationRemapper(String descriptor, AnnotationVisitor annotationVisitor) {
return new AsmAnnotationRemapper(descriptor, annotationVisitor, (AsmRemapper) remapper);
Expand Down Expand Up @@ -240,21 +244,54 @@ public void visitMultiANewArrayInsn(String descriptor, int numDimensions) {
}

@Override
public void visitFieldInsn(int opcode, String owner, String name, String descriptor) {
public void visitFieldInsn(int opcode, String owner, String name, String desc) {
if (checkPackageAccess) {
PackageAccessChecker.checkMember(this.owner, owner, name, descriptor, TrMember.MemberType.FIELD, "field instruction", (AsmRemapper) remapper);
PackageAccessChecker.checkMember(this.owner, owner, name, desc, TrMember.MemberType.FIELD, "field instruction", (AsmRemapper) remapper);
}

AsmRemapper remapper = getRemapper();
ClassInstance cls = remapper.getClass(owner);

if (cls != null) {
MemberInstance member = cls.resolveField(name, desc);

name = remapper.mapFieldName(cls, member, name, desc);

if (remapper.tr.useResolvedOwners && member != null && member.getOwner() != cls) {
owner = member.getOwner().getName();
}
}

super.visitFieldInsn(opcode, owner, name, descriptor);
mv.visitFieldInsn(opcode,
remapper.mapType(owner),
name,
remapper.mapDesc(desc));
}

@Override
public void visitMethodInsn(int opcode, String owner, String name, String descriptor, boolean isInterface) {
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean isInterface) {
if (checkPackageAccess) {
PackageAccessChecker.checkMember(this.owner, owner, name, descriptor, TrMember.MemberType.METHOD, "method instruction", (AsmRemapper) remapper);
PackageAccessChecker.checkMember(this.owner, owner, name, desc, TrMember.MemberType.METHOD, "method instruction", (AsmRemapper) remapper);
}

AsmRemapper remapper = getRemapper();
ClassInstance cls = remapper.getClass(owner);

if (cls != null) {
MemberInstance member = cls.resolveMethod(name, desc);

name = remapper.mapMethodName(cls, member, name, desc);

if (remapper.tr.useResolvedOwners && member != null && member.getOwner() != cls) {
owner = member.getOwner().getName();
}
}

super.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
mv.visitMethodInsn(opcode,
remapper.mapType(owner),
name,
remapper.mapMethodDesc(desc),
isInterface);
}

@Override
Expand All @@ -271,7 +308,7 @@ public void visitInvokeDynamicInsn(String name, String descriptor, Handle bootst
bootstrapMethodArguments[i] = remapper.mapValue(bootstrapMethodArguments[i]);
}

// bypass remapper
// bypass remapper, TODO: implement useResolvedOwners
mv.visitInvokeDynamicInsn(name,
remapper.mapMethodDesc(descriptor), (Handle) remapper.mapValue(bootstrapMethodHandle),
bootstrapMethodArguments);
Expand Down
19 changes: 11 additions & 8 deletions src/main/java/net/fabricmc/tinyremapper/AsmRemapper.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2016, 2018, Player, asie
* Copyright (c) 2018, 2021, FabricMC
* Copyright (c) 2018, 2022, FabricMC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
Expand Down Expand Up @@ -48,11 +48,12 @@ public String mapFieldName(String owner, String name, String desc) {
ClassInstance cls = getClass(owner);
if (cls == null) return name;

return mapFieldName(cls, name, desc);
MemberInstance member = cls.resolveField(name, desc);

return mapFieldName(cls, member, name, desc);
}

final String mapFieldName(ClassInstance cls, String name, String desc) {
MemberInstance member = cls.resolve(TrMember.MemberType.FIELD, MemberInstance.getFieldId(name, desc, tr.ignoreFieldDesc));
final String mapFieldName(ClassInstance cls, MemberInstance member, String name, String desc) {
String newName;

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

return mapMethodName(cls, name, desc);
MemberInstance member = cls.resolveMethod(name, desc);

return mapMethodName(cls, member, name, desc);
}

final String mapMethodName(ClassInstance cls, String name, String desc) {
MemberInstance member = cls.resolve(TrMember.MemberType.METHOD, MemberInstance.getMethodId(name, desc));
final String mapMethodName(ClassInstance cls, MemberInstance member, String name, String desc) {
String newName;

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

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

if (attributeDesc == null) {
return this.mapMethodNamePrefixDesc(annotationClass, name, "()");
return mapMethodNamePrefixDesc(annotationClass, name, "()");
} else {
return this.mapMethodName(annotationClass, name, "()" + attributeDesc);
}
Expand Down
27 changes: 25 additions & 2 deletions src/main/java/net/fabricmc/tinyremapper/Main.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2016, 2018, Player, asie
* Copyright (c) 2016, 2021, FabricMC
* Copyright (c) 2016, 2022, FabricMC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
Expand Down Expand Up @@ -46,6 +46,7 @@ public static void main(String[] rawArgs) {
Set<String> forcePropagation = Collections.emptySet();
File forcePropagationFile = null;
boolean ignoreConflicts = false;
boolean useResolvedOwners = false;
boolean checkPackageAccess = false;
boolean fixPackageAccess = false;
boolean resolveMissing = false;
Expand Down Expand Up @@ -91,6 +92,9 @@ public static void main(String[] rawArgs) {
case "ignoreconflicts":
ignoreConflicts = true;
break;
case "useresolvedowners":
useResolvedOwners = true;
break;
case "checkpackageaccess":
checkPackageAccess = true;
break;
Expand Down Expand Up @@ -145,7 +149,25 @@ public static void main(String[] rawArgs) {
}

if (args.size() < 5) {
System.out.println("usage: <input> <output> <mappings> <from> <to> [<classpath>]... [--reverse] [--forcePropagation=<file>] [--propagatePrivate] [--ignoreConflicts]");
System.out.printf("usage: <input> <output> <mappings> <from> <to> [<classpath>]... [OPTIONS]%n"
+ "options:%n"
+ " --ignoreFieldDesc%n"
+ " --forcePropagation=<file>%n"
+ " --propagatePrivate%n"
+ " --propagateBridges=(disabled|enabled|compatible)%n"
+ " --removeFrames%n"
+ " --ignoreConflicts%n"
+ " --useResolvedOwners%n"
+ " --checkPackagAaccess%n"
+ " --fixPackageAccess%n"
+ " --resolveMissing%n"
+ " --rebuildSourceFilenames%n"
+ " --skipLocalVariableMapping%n"
+ " --renameInvalidLocals%n"
+ " --invalidLvNamePattern=<pattern>%n"
+ " --nonClassCopyMode=(unchanged|fixmeta|skipmeta)%n"
+ " --threads=<n>%n"
+ " --mixin%n");
System.exit(1);
}

Expand Down Expand Up @@ -212,6 +234,7 @@ public static void main(String[] rawArgs) {
.propagateBridges(propagateBridges)
.removeFrames(removeFrames)
.ignoreConflicts(ignoreConflicts)
.useResolvedOwners(useResolvedOwners)
.checkPackageAccess(checkPackageAccess)
.fixPackageAccess(fixPackageAccess)
.resolveMissing(resolveMissing)
Expand Down
20 changes: 16 additions & 4 deletions src/main/java/net/fabricmc/tinyremapper/TinyRemapper.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2016, 2018, Player, asie
* Copyright (c) 2016, 2021, FabricMC
* Copyright (c) 2016, 2022, FabricMC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
Expand Down Expand Up @@ -132,6 +132,14 @@ public Builder resolveMissing(boolean value) {
return this;
}

/**
* Whether to use the resolved owner class instead of the current class for member accesses.
*/
public Builder useResolvedOwners(boolean value) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since we only use the CLI, could you add a new CLI option for this, please? Thanks!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure, on it

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done :)

useResolvedOwners = value;
return this;
}

public Builder checkPackageAccess(boolean value) {
checkPackageAccess = value;
return this;
Expand Down Expand Up @@ -217,7 +225,7 @@ public TinyRemapper build() {
keepInputData,
forcePropagation, propagatePrivate,
propagateBridges, propagateRecordComponents,
removeFrames, ignoreConflicts, resolveMissing, checkPackageAccess || fixPackageAccess, fixPackageAccess,
removeFrames, ignoreConflicts, resolveMissing, useResolvedOwners, checkPackageAccess || fixPackageAccess, fixPackageAccess,
rebuildSourceFilenames, skipLocalMapping, renameInvalidLocals, invalidLvNamePattern, inferNameFromSameLvIndex,
analyzeVisitors, stateProcessors, preApplyVisitors, postApplyVisitors,
extraRemapper);
Expand All @@ -236,6 +244,7 @@ public TinyRemapper build() {
private boolean removeFrames = false;
private boolean ignoreConflicts = false;
private boolean resolveMissing = false;
private boolean useResolvedOwners = false;
private boolean checkPackageAccess = false;
private boolean fixPackageAccess = false;
private boolean rebuildSourceFilenames = false;
Expand Down Expand Up @@ -274,6 +283,7 @@ private TinyRemapper(Collection<IMappingProvider> mappingProviders, boolean igno
boolean removeFrames,
boolean ignoreConflicts,
boolean resolveMissing,
boolean useResolvedOwners,
boolean checkPackageAccess,
boolean fixPackageAccess,
boolean rebuildSourceFilenames,
Expand All @@ -294,6 +304,7 @@ private TinyRemapper(Collection<IMappingProvider> mappingProviders, boolean igno
this.removeFrames = removeFrames;
this.ignoreConflicts = ignoreConflicts;
this.resolveMissing = resolveMissing;
this.useResolvedOwners = useResolvedOwners;
this.checkPackageAccess = checkPackageAccess;
this.fixPackageAccess = fixPackageAccess;
this.rebuildSourceFilenames = rebuildSourceFilenames;
Expand Down Expand Up @@ -1089,10 +1100,10 @@ private byte[] fixClass(ClassInstance cls, byte[] data) {
String mappedName, mappedDesc;

if (member.type == TrMember.MemberType.FIELD) {
mappedName = remapper.mapFieldName(cls, member.name, member.desc);
mappedName = remapper.mapFieldName(cls, member, member.name, member.desc);
mappedDesc = remapper.mapDesc(member.desc);
} else {
mappedName = remapper.mapMethodName(cls, member.name, member.desc);
mappedName = remapper.mapMethodName(cls, member, member.name, member.desc);
mappedDesc = remapper.mapMethodDesc(member.desc);
}

Expand Down Expand Up @@ -1311,6 +1322,7 @@ public void propagate(TrMember m, String newName) {
private final boolean removeFrames;
private final boolean ignoreConflicts;
private final boolean resolveMissing;
final boolean useResolvedOwners;
private final boolean checkPackageAccess;
private final boolean fixPackageAccess;
private final boolean rebuildSourceFilenames;
Expand Down