Skip to content
Merged
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
56 changes: 56 additions & 0 deletions src/main/java/net/fabricmc/tinyremapper/LocalInstance.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright (c) 2016, 2018, Player, asie
* Copyright (c) 2026, 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package net.fabricmc.tinyremapper;

import net.fabricmc.tinyremapper.api.TrLocal;
import net.fabricmc.tinyremapper.api.TrMethod;

public class LocalInstance implements TrLocal {
public LocalInstance(TrMethod owner, String name, String desc, int index) {
this.owner = owner;
this.name = name;
this.desc = desc;
this.index = index;
}

@Override
public String getName() {
return this.name;
}

@Override
public String getDesc() {
return this.desc;
}

@Override
public int getIndex() {
return this.index;
}

@Override
public TrMethod getOwner() {
return this.owner;
}

final TrMethod owner;
final String name;
final String desc;
final int index;
}
5 changes: 5 additions & 0 deletions src/main/java/net/fabricmc/tinyremapper/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ public static void main(String[] rawArgs) {
boolean renameInvalidLocals = false;
Pattern invalidLvNamePattern = null;
boolean inferNameFromSameLvIndex = false;
boolean disableLocalVariableTracking = false;
NonClassCopyMode ncCopyMode = NonClassCopyMode.FIX_META_INF;
int threads = -1;

Expand Down Expand Up @@ -132,6 +133,9 @@ public static void main(String[] rawArgs) {
case "infernamefromsamelvindex":
inferNameFromSameLvIndex = true;
break;
case "disablelocalvariabletracking":
disableLocalVariableTracking = true;
break;
case "nonclasscopymode":
switch (arg.substring(valueSepPos + 1).toLowerCase(Locale.ENGLISH)) {
case "unchanged": ncCopyMode = NonClassCopyMode.UNCHANGED; break;
Expand Down Expand Up @@ -270,6 +274,7 @@ public static void main(String[] rawArgs) {
.renameInvalidLocals(renameInvalidLocals)
.invalidLvNamePattern(invalidLvNamePattern)
.inferNameFromSameLvIndex(inferNameFromSameLvIndex)
.disableLocalVariableTracking(disableLocalVariableTracking)
.threads(threads);

for (TinyRemapper.Extension ext : providedExtensions) {
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/net/fabricmc/tinyremapper/MemberInstance.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import net.fabricmc.tinyremapper.TinyRemapper.MrjState;
import net.fabricmc.tinyremapper.api.TrClass;
import net.fabricmc.tinyremapper.api.TrField;
import net.fabricmc.tinyremapper.api.TrLocal;
import net.fabricmc.tinyremapper.api.TrMember;
import net.fabricmc.tinyremapper.api.TrMethod;

Expand Down Expand Up @@ -68,6 +69,11 @@ public int getIndex() {
return index;
}

@Override
public TrLocal[] getLocals() {
return this.locals.clone();
}

public MrjState getContext() {
return cls.getContext();
}
Expand Down Expand Up @@ -113,6 +119,10 @@ public void forceSetNewName(String name) {
newName = name;
}

public void setLocals(TrLocal[] locals) {
this.locals = locals.clone();
}

@Override
public String toString() {
return String.format("%s/%s%s", cls.getName(), name, desc);
Expand Down Expand Up @@ -151,6 +161,7 @@ public static String getNameFromId(TrMember.MemberType type, String id, boolean
final String desc;
final int access;
final int index;
TrLocal[] locals;
private volatile String newName;
private volatile String newBridgedName;
String newNameOriginatingCls;
Expand Down
46 changes: 42 additions & 4 deletions src/main/java/net/fabricmc/tinyremapper/TinyRemapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.RecordComponentVisitor;
Expand All @@ -67,9 +68,11 @@
import net.fabricmc.tinyremapper.IMappingProvider.Member;
import net.fabricmc.tinyremapper.api.TrClass;
import net.fabricmc.tinyremapper.api.TrEnvironment;
import net.fabricmc.tinyremapper.api.TrLocal;
import net.fabricmc.tinyremapper.api.TrLogger;
import net.fabricmc.tinyremapper.api.TrMember;
import net.fabricmc.tinyremapper.api.TrMember.MemberType;
import net.fabricmc.tinyremapper.extension.mixin.common.data.Constant;

public class TinyRemapper {
public static class Builder {
Expand Down Expand Up @@ -183,6 +186,14 @@ public Builder inferNameFromSameLvIndex(boolean value) {
return this;
}

/**
* Whether to disable the tracking of local variable names, used in ModifyVariable local name remapping.
*/
public Builder disableLocalVariableTracking(boolean value) {
this.disableLocalVariableTracking = value;
return this;
}

@Deprecated
public Builder extraAnalyzeVisitor(ClassVisitor visitor) {
return extraAnalyzeVisitor((mrjVersion, className, next) -> {
Expand Down Expand Up @@ -233,7 +244,7 @@ public TinyRemapper build() {
propagateBridges, propagateRecordComponents,
removeFrames, ignoreConflicts, resolveMissing, checkPackageAccess || fixPackageAccess, fixPackageAccess,
rebuildSourceFilenames, skipLocalMapping, renameInvalidLocals, invalidLvNamePattern, inferNameFromSameLvIndex,
analyzeVisitors, stateProcessors, preApplyVisitors, postApplyVisitors,
disableLocalVariableTracking || skipLocalMapping, analyzeVisitors, stateProcessors, preApplyVisitors, postApplyVisitors,
extraRemapper, logger);

return remapper;
Expand All @@ -258,6 +269,7 @@ public TinyRemapper build() {
private boolean renameInvalidLocals = false;
private Pattern invalidLvNamePattern;
private boolean inferNameFromSameLvIndex;
private boolean disableLocalVariableTracking = false;
private final List<AnalyzeVisitorProvider> analyzeVisitors = new ArrayList<>();
private final List<StateProcessor> stateProcessors = new ArrayList<>();
private final List<ApplyVisitorProvider> preApplyVisitors = new ArrayList<>();
Expand Down Expand Up @@ -321,6 +333,7 @@ private TinyRemapper(Collection<IMappingProvider> mappingProviders, boolean igno
boolean rebuildSourceFilenames,
boolean skipLocalMapping,
boolean renameInvalidLocals, Pattern invalidLvNamePattern, boolean inferNameFromSameLvIndex,
boolean disableLocalVariableTracking,
List<AnalyzeVisitorProvider> analyzeVisitors, List<StateProcessor> stateProcessors,
List<ApplyVisitorProvider> preApplyVisitors, List<ApplyVisitorProvider> postApplyVisitors,
Remapper extraRemapper, TrLogger logger) {
Expand All @@ -345,6 +358,7 @@ private TinyRemapper(Collection<IMappingProvider> mappingProviders, boolean igno
this.renameInvalidLocals = renameInvalidLocals;
this.invalidLvNamePattern = invalidLvNamePattern;
this.inferNameFromSameLvIndex = inferNameFromSameLvIndex;
this.disableLocalVariableTracking = disableLocalVariableTracking;
this.analyzeVisitors = analyzeVisitors;
this.stateProcessors = stateProcessors;
this.preApplyVisitors = preApplyVisitors;
Expand Down Expand Up @@ -643,10 +657,29 @@ public void visit(int version, int access, String name, String signature, String

@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
MemberInstance prev = ret.addMember(new MemberInstance(TrMember.MemberType.METHOD, ret, name, desc, access, ret.getMembers().size()));
MemberInstance member = new MemberInstance(MemberType.METHOD, ret, name, desc, access, ret.getMembers().size());
MemberInstance prev = ret.addMember(member);
if (prev != null) throw new RuntimeException(String.format("duplicate method %s/%s%s in inputs", ret.getName(), name, desc));

return super.visitMethod(access, name, desc, signature, exceptions);
if (TinyRemapper.this.disableLocalVariableTracking) {
return super.visitMethod(access, name, desc, signature, exceptions);
} else {
return new MethodVisitor(Constant.ASM_VERSION, super.visitMethod(access, name, desc, signature, exceptions)) {
final List<TrLocal> locals = new ArrayList<>();

@Override
public void visitLocalVariable(String name, String descriptor, String signature, Label start, Label end, int index) {
this.locals.add(new LocalInstance(member, name, descriptor, index));
super.visitLocalVariable(name, descriptor, signature, start, end, index);
}

@Override
public void visitEnd() {
member.setLocals(locals.toArray(new TrLocal[0]));
super.visitEnd();
}
};
}
}

@Override
Expand All @@ -662,7 +695,11 @@ public FieldVisitor visitField(int access, String name, String desc, String sign
cv = analyzeVisitors.get(i).insertAnalyzeVisitor(isInput, mrjVersion, name, cv, tags);
}

reader.accept(cv, ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES | ClassReader.SKIP_CODE);
if (this.disableLocalVariableTracking) {
reader.accept(cv, ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES | ClassReader.SKIP_CODE);
} else {
reader.accept(cv, ClassReader.SKIP_FRAMES);
}

return ret;
}
Expand Down Expand Up @@ -1454,6 +1491,7 @@ public void propagate(TrMember m, String newName) {
private final boolean renameInvalidLocals;
private final Pattern invalidLvNamePattern;
private final boolean inferNameFromSameLvIndex;
private final boolean disableLocalVariableTracking;
private final List<AnalyzeVisitorProvider> analyzeVisitors;
private final List<StateProcessor> stateProcessors;
private final List<ApplyVisitorProvider> preApplyVisitors;
Expand Down
26 changes: 26 additions & 0 deletions src/main/java/net/fabricmc/tinyremapper/api/TrLocal.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright (c) 2016, 2018, Player, asie
* Copyright (c) 2026, 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package net.fabricmc.tinyremapper.api;

public interface TrLocal {
String getName();
String getDesc();
int getIndex();
TrMethod getOwner();
}
2 changes: 2 additions & 0 deletions src/main/java/net/fabricmc/tinyremapper/api/TrMethod.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,6 @@ default boolean isAbstract() {
default boolean isVirtual() {
return getType().equals(MemberType.METHOD) && (getAccess() & (Opcodes.ACC_STATIC | Opcodes.ACC_PRIVATE)) == 0;
}

TrLocal[] getLocals();
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public final class AnnotationElement {
public static final String TO = "to";
public static final String SLICE = "slice";
public static final String METHOD = "method";
public static final String NAME = "name";
public static final String DEFINITION_METHOD = "method";
public static final String DEFINITION_FIELD = "field";
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@
* method with the first occurrence in ASM will be remapped.
*/
class CommonInjectionAnnotationVisitor extends AnnotationVisitor {
private final CommonData data;
private final List<String> targets;
protected final CommonData data;
protected final List<String> targets;

CommonInjectionAnnotationVisitor(CommonData data, AnnotationVisitor delegate, List<String> targets) {
super(Constant.ASM_VERSION, Objects.requireNonNull(delegate));
Expand Down
Loading