Skip to content

Commit 83573b2

Browse files
committed
Custom logger implementation, allow skipping propagation, fix propagation
1 parent dc31879 commit 83573b2

4 files changed

Lines changed: 92 additions & 44 deletions

File tree

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ plugins {
88
sourceCompatibility = JavaVersion.VERSION_1_8
99
targetCompatibility = JavaVersion.VERSION_1_8
1010

11-
version = '0.3.2-architectury.5'
11+
version = '0.3.2-architectury.6'
1212

1313
def ENV = System.getenv()
1414
version = version + (ENV.GITHUB_ACTIONS ? "" : "+local")

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -209,9 +209,9 @@ public void checkPackageAccess(String accessingOwner, String owner, String name,
209209
}
210210
}
211211

212-
System.out.printf("Invalid access from %s to %s after remapping.%n",
212+
remapper.logger.accept(String.format("Invalid access from %s to %s after remapping.",
213213
mappedAccessor,
214-
inaccessible);
214+
inaccessible));
215215

216216
if (!clsAccessible) remapper.classesToMakePublic.add(cls);
217217
if (!memberAccessible) remapper.membersToMakePublic.add(member);

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,7 @@ public String toString() {
455455
final String srcPath;
456456
byte[] data;
457457
private final Map<String, MemberInstance> members = new HashMap<>(); // methods and fields are distinct due to their different desc separators
458-
private final ConcurrentMap<String, MemberInstance> resolvedMembers = new ConcurrentHashMap<>();
458+
ConcurrentMap<String, MemberInstance> resolvedMembers = new ConcurrentHashMap<>();
459459
final Set<ClassInstance> parents = new HashSet<>();
460460
final Set<ClassInstance> children = new HashSet<>();
461461
private String name;

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

Lines changed: 88 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import java.util.concurrent.*;
3434
import java.util.concurrent.atomic.AtomicReference;
3535
import java.util.function.BiConsumer;
36+
import java.util.function.Consumer;
3637
import java.util.stream.Collectors;
3738

3839
public class TinyRemapper {
@@ -127,18 +128,28 @@ public Builder skipConflictsChecking(boolean value) {
127128
return this;
128129
}
129130

131+
public Builder skipPropagate(boolean value) {
132+
skipPropagate = value;
133+
return this;
134+
}
135+
130136
public Builder cacheMappings(boolean value) {
131137
cacheMappings = value;
132138
return this;
133139
}
134140

141+
public Builder logger(Consumer<String> value) {
142+
logger = value;
143+
return this;
144+
}
145+
135146
public TinyRemapper build() {
136147
TinyRemapper remapper = new TinyRemapper(mappingProviders, ignoreFieldDesc, threadCount,
137148
keepInputData,
138149
forcePropagation, propagatePrivate,
139150
removeFrames, ignoreConflicts, resolveMissing, checkPackageAccess || fixPackageAccess, fixPackageAccess,
140151
rebuildSourceFilenames, skipLocalMapping, renameInvalidLocals, skipConflictsChecking,
141-
cacheMappings, extraAnalyzeVisitor, extraRemapper);
152+
cacheMappings, skipPropagate, extraAnalyzeVisitor, extraRemapper, logger);
142153

143154
return remapper;
144155
}
@@ -159,8 +170,10 @@ public TinyRemapper build() {
159170
private boolean renameInvalidLocals = false;
160171
private boolean skipConflictsChecking = false;
161172
private boolean cacheMappings = false;
173+
private boolean skipPropagate = false;
162174
private ClassVisitor extraAnalyzeVisitor;
163175
private Remapper extraRemapper;
176+
private Consumer<String> logger = System.out::println;
164177
}
165178

166179
private TinyRemapper(Set<IMappingProvider> mappingProviders, boolean ignoreFieldDesc,
@@ -177,7 +190,10 @@ private TinyRemapper(Set<IMappingProvider> mappingProviders, boolean ignoreField
177190
boolean renameInvalidLocals,
178191
boolean skipConflictsChecking,
179192
boolean cacheMappings,
180-
ClassVisitor extraAnalyzeVisitor, Remapper extraRemapper) {
193+
boolean skipPropagate,
194+
ClassVisitor extraAnalyzeVisitor,
195+
Remapper extraRemapper,
196+
Consumer<String> logger) {
181197
this.mappingProviders = mappingProviders;
182198
this.ignoreFieldDesc = ignoreFieldDesc;
183199
this.threadCount = threadCount > 0 ? threadCount : Math.max(Runtime.getRuntime().availableProcessors(), 2);
@@ -195,8 +211,10 @@ private TinyRemapper(Set<IMappingProvider> mappingProviders, boolean ignoreField
195211
this.renameInvalidLocals = renameInvalidLocals;
196212
this.skipConflictsChecking = skipConflictsChecking;
197213
this.cacheMappings = cacheMappings;
214+
this.skipPropagate = skipPropagate;
198215
this.extraAnalyzeVisitor = extraAnalyzeVisitor;
199216
this.extraRemapper = extraRemapper;
217+
this.logger = logger;
200218
}
201219

202220
public static Builder newRemapper() {
@@ -348,7 +366,7 @@ private CompletableFuture<List<ClassInstance>> read(Path[] inputs, boolean isInp
348366
});
349367
}
350368

351-
private static void addClass(ClassInstance cls, Map<String, ClassInstance> out) {
369+
private void addClass(ClassInstance cls, Map<String, ClassInstance> out) {
352370
String name = cls.getName();
353371

354372
// add new class or replace non-input class with input class, warn if two input classes clash
@@ -358,7 +376,7 @@ private static void addClass(ClassInstance cls, Map<String, ClassInstance> out)
358376

359377
if (cls.isInput) {
360378
if (prev.isInput) {
361-
System.out.printf("duplicate input class %s, from %s and %s%n", name, prev.srcPath, cls.srcPath);
379+
logger.accept(String.format("duplicate input class %s, from %s and %s", name, prev.srcPath, cls.srcPath));
362380
prev.addInputTags(cls.getInputTags());
363381
return;
364382
} else if (out.replace(name, prev, cls)) { // cas with retry-loop on failure
@@ -368,6 +386,11 @@ private static void addClass(ClassInstance cls, Map<String, ClassInstance> out)
368386
// loop
369387
}
370388
} else {
389+
if (out == readClasses) {
390+
mergedClasspath = false;
391+
mappingsDirty = true;
392+
}
393+
371394
prev.addInputTags(cls.getInputTags());
372395
return;
373396
}
@@ -385,7 +408,7 @@ private CompletableFuture<List<ClassInstance>> read(Path file, boolean isInput,
385408
ClassInstance res = analyze(isInput, tags, srcPath, Files.readAllBytes(file));
386409
if (res != null) return Collections.singletonList(res);
387410
} catch (IOException e) {
388-
System.out.println(file.toAbsolutePath());
411+
logger.accept(file.toAbsolutePath().toString());
389412
e.printStackTrace();
390413
}
391414
return Collections.emptyList();
@@ -414,7 +437,7 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
414437
} catch (URISyntaxException e) {
415438
throw new RuntimeException(e);
416439
} catch (IOException e) {
417-
System.out.println(file.toAbsolutePath());
440+
logger.accept(file.toAbsolutePath().toString());
418441
e.printStackTrace();
419442
}
420443
}
@@ -461,20 +484,16 @@ String mapClass(String className) {
461484
}
462485

463486
private void loadMappings(boolean ignoreCached) {
464-
if (ignoreCached) {
487+
if (mappingsDirty || ignoreCached) {
465488
classMap.clear();
466489
methodMap.clear();
467490
methodArgMap.clear();
468491
fieldMap.clear();
469-
470-
for (ClassInstance node : classes.values()) {
471-
node.parents.clear();
472-
node.children.clear();
473-
}
492+
unmergeClasses();
474493

475494
mappingsDirty = true;
476495
}
477-
496+
478497
if (!mappingsDirty) return;
479498
mappingsDirty = false;
480499
MappingAcceptor acceptor = new MappingAcceptor() {
@@ -537,8 +556,6 @@ public void acceptField(Member field, String dstName) {
537556
}
538557

539558
checkClassMappings();
540-
mergeClasspath();
541-
propagate();
542559
}
543560

544561
public void replaceMappings(Set<IMappingProvider> providers) {
@@ -569,35 +586,47 @@ private void checkClassMappings() {
569586
duplicates.add(name);
570587
}
571588
}
572-
573-
System.out.println("non-unique class target name mappings:");
589+
590+
logger.accept("non-unique class target name mappings:");
574591

575592
for (String target : duplicates) {
576-
System.out.print(" [");
593+
StringBuilder builder = new StringBuilder();
594+
builder.append(" [");
577595
boolean first = true;
578596

579597
for (Map.Entry<String, String> e : classMap.entrySet()) {
580598
if (e.getValue().equals(target)) {
581599
if (first) {
582600
first = false;
583601
} else {
584-
System.out.print(", ");
602+
builder.append(", ");
585603
}
586-
587-
System.out.print(e.getKey());
604+
605+
builder.append(e.getKey());
588606
}
589607
}
590-
591-
System.out.printf("] -> %s%n", target);
608+
609+
builder.append("] -> ").append(target);
610+
logger.accept(builder.toString());
592611
}
593612

594613
throw new RuntimeException("duplicate class target name mappings detected");
595614
}
596615
}
616+
617+
private void unmergeClasses() {
618+
mergedClasspath = false;
619+
for (ClassInstance node : classes.values()) {
620+
node.parents.clear();
621+
node.children.clear();
622+
}
623+
}
597624

598625
private void mergeClasspath() {
626+
if (mergedClasspath) return;
627+
mergedClasspath = true;
599628
for (ClassInstance node : classes.values()) {
600-
if (node.isInput) return;
629+
if (node.isInput) continue;
601630
assert node.getSuperName() != null;
602631

603632
ClassInstance parent = classes.get(node.getSuperName());
@@ -619,8 +648,9 @@ private void mergeClasspath() {
619648
}
620649

621650
private void mergeInput() {
622-
for (ClassInstance node : classes.values()) {
623-
if (!node.isInput) return;
651+
for (ClassInstance node : classes.values().parallelStream()
652+
.filter(node -> node.isInput)
653+
.collect(Collectors.toList())) {
624654
assert node.getSuperName() != null;
625655

626656
ClassInstance parent = classes.get(node.getSuperName());
@@ -650,6 +680,16 @@ private void unmergeInput() {
650680
}
651681

652682
private void propagate() {
683+
if (skipPropagate) return;
684+
conflicts.clear();
685+
classes.values().parallelStream().forEach(value -> {
686+
value.resolvedMembers = new ConcurrentHashMap<>();
687+
for (MemberInstance member : value.getMembers()) {
688+
member.forceSetNewName(null);
689+
member.newNameOriginatingCls = null;
690+
}
691+
});
692+
653693
List<Future<?>> futures = new ArrayList<>();
654694
List<Map.Entry<String, String>> tasks = new ArrayList<>();
655695
int maxTasks = methodMap.size() / threadCount / 4;
@@ -699,7 +739,7 @@ private void handleConflicts() {
699739
if (testSet.size() != cls.getMembers().size()) {
700740
if (!targetNameCheckFailed) {
701741
targetNameCheckFailed = true;
702-
System.out.println("Mapping target name conflicts detected:");
742+
logger.accept("Mapping target name conflicts detected:");
703743
}
704744

705745
Map<String, List<MemberInstance>> duplicates = new HashMap<>();
@@ -717,22 +757,25 @@ private void handleConflicts() {
717757
if (members.size() < 2) continue;
718758

719759
MemberInstance anyMember = members.get(0);
720-
System.out.printf(" %ss %s/[", anyMember.type, cls.getName());
760+
StringBuilder builder = new StringBuilder();
761+
builder.append(" ").append(anyMember.type).append("s ").append(cls.getName()).append("/[");
721762

722763
for (int i = 0; i < members.size(); i++) {
723-
if (i != 0) System.out.print(", ");
764+
if (i != 0) builder.append(", ");
724765

725766
MemberInstance member = members.get(i);
726767

727768
if (member.newNameOriginatingCls != null && !member.newNameOriginatingCls.equals(cls.getName())) {
728-
System.out.print(member.newNameOriginatingCls);
729-
System.out.print('/');
769+
builder.append(member.newNameOriginatingCls);
770+
builder.append('/');
730771
}
731-
732-
System.out.print(member.name);
772+
773+
builder.append(member.name);
733774
}
734-
735-
System.out.printf("]%s -> %s%n", MemberInstance.getId(anyMember.type, "", anyMember.desc, ignoreFieldDesc), MemberInstance.getNameFromId(anyMember.type, nameDesc, ignoreFieldDesc));
775+
776+
builder.append(']').append(MemberInstance.getId(anyMember.type, "", anyMember.desc, ignoreFieldDesc));
777+
builder.append(" -> ").append(MemberInstance.getNameFromId(anyMember.type, nameDesc, ignoreFieldDesc));
778+
logger.accept(builder.toString());
736779
}
737780
}
738781

@@ -742,15 +785,15 @@ private void handleConflicts() {
742785
boolean unfixableConflicts = false;
743786

744787
if (!conflicts.isEmpty()) {
745-
System.out.println("Mapping source name conflicts detected:");
788+
logger.accept("Mapping source name conflicts detected:");
746789

747790
for (Map.Entry<MemberInstance, Set<String>> entry : conflicts.entrySet()) {
748791
MemberInstance member = entry.getKey();
749792
String newName = member.getNewName();
750793
Set<String> names = entry.getValue();
751794
names.add(member.cls.getName()+"/"+newName);
752795

753-
System.out.printf(" %s %s %s (%s) -> %s%n", member.cls.getName(), member.type.name(), member.name, member.desc, names);
796+
logger.accept(String.format(" %s %s %s (%s) -> %s", member.cls.getName(), member.type.name(), member.name, member.desc, names));
754797

755798
if (ignoreConflicts) {
756799
Map<String, String> mappings = member.type == MemberType.METHOD ? methodMap : fieldMap;
@@ -772,14 +815,14 @@ private void handleConflicts() {
772815
unfixableConflicts = true;
773816
} else {
774817
member.forceSetNewName(mappingName);
775-
System.out.println(" fixable: replaced with "+mappingName);
818+
logger.accept(" fixable: replaced with "+mappingName);
776819
}
777820
}
778821
}
779822
}
780823

781824
if (!conflicts.isEmpty() && !ignoreConflicts || unfixableConflicts || targetNameCheckFailed) {
782-
if (ignoreConflicts || targetNameCheckFailed) System.out.println("There were unfixable conflicts.");
825+
if (ignoreConflicts || targetNameCheckFailed) logger.accept("There were unfixable conflicts.");
783826

784827
System.exit(1);
785828
}
@@ -828,7 +871,7 @@ public void apply(final BiConsumer<String, byte[]> outputConsumer, InputTag... i
828871

829872
if (fixPackageAccess) {
830873
if (needsFixes) {
831-
System.out.printf("Fixing access for %d classes and %d members.%n", classesToMakePublic.size(), membersToMakePublic.size());
874+
logger.accept(String.format("Fixing access for %d classes and %d members.", classesToMakePublic.size(), membersToMakePublic.size()));
832875
}
833876

834877
for (Map.Entry<ClassInstance, byte[]> entry : outputBuffer.entrySet()) {
@@ -912,7 +955,9 @@ private void refresh() {
912955

913956
_prepareClasses();
914957
loadMappings(!cacheMappings);
958+
mergeClasspath();
915959
mergeInput();
960+
propagate();
916961

917962
assert dirty;
918963
dirty = false;
@@ -1122,8 +1167,10 @@ public boolean isMappingsDirty() {
11221167
private final boolean renameInvalidLocals;
11231168
private final boolean skipConflictsChecking;
11241169
private final boolean cacheMappings;
1170+
private final boolean skipPropagate;
11251171
private final ClassVisitor extraAnalyzeVisitor;
11261172
final Remapper extraRemapper;
1173+
final Consumer<String> logger;
11271174

11281175
final AtomicReference<Map<InputTag, InputTag[]>> singleInputTags = new AtomicReference<>(Collections.emptyMap()); // cache for tag -> { tag }
11291176

@@ -1144,6 +1191,7 @@ public boolean isMappingsDirty() {
11441191
private final ExecutorService threadPool;
11451192
private final AsmRemapper remapper = new AsmRemapper(this);
11461193

1194+
private boolean mergedClasspath = false;
11471195
private boolean mappingsDirty = true;
11481196
private volatile boolean dirty = true; // volatile to make the state debug asserts more reliable, shouldn't actually see concurrent modifications
11491197
private Map<ClassInstance, byte[]> outputBuffer;

0 commit comments

Comments
 (0)