Skip to content

Commit 200c8bf

Browse files
committed
Add preliminary package mapping support
1 parent d6b7a22 commit 200c8bf

26 files changed

+717
-100
lines changed

src/main/java/net/fabricmc/mappingio/FlatMappingVisitor.java

+19
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,14 @@ default boolean visitContent() throws IOException {
6262
return true;
6363
}
6464

65+
// TODO: Un-"default" in the next breaking release
66+
default boolean visitPackage(String srcName, @Nullable String[] dstNames) throws IOException {
67+
return false;
68+
}
69+
70+
// TODO: Un-"default" in the next breaking release
71+
default void visitPackageComment(String srcName, @Nullable String[] dstNames, String comment) throws IOException { }
72+
6573
boolean visitClass(String srcName, @Nullable String[] dstNames) throws IOException;
6674
void visitClassComment(String srcName, @Nullable String[] dstNames, String comment) throws IOException;
6775

@@ -149,6 +157,17 @@ default boolean visitMethodVar(String srcClsName, String srcMethodName, @Nullabl
149157
}
150158

151159
// convenience / potentially higher efficiency visit methods for only one dst name
160+
default boolean visitPackage(String srcName, String dstName) throws IOException {
161+
return visitPackage(srcName, toArray(dstName));
162+
}
163+
164+
default void visitPackageComment(String srcName, String comment) throws IOException {
165+
visitPackageComment(srcName, (String) null, comment);
166+
}
167+
168+
default void visitPackageComment(String srcName, @Nullable String dstName, String comment) throws IOException {
169+
visitPackageComment(srcName, toArray(dstName), comment);
170+
}
152171

153172
default boolean visitClass(String srcName, String dstName) throws IOException {
154173
return visitClass(srcName, toArray(dstName));

src/main/java/net/fabricmc/mappingio/MappedElementKind.java

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
* A kind of element that can be mapped.
2121
*/
2222
public enum MappedElementKind {
23+
PACKAGE(0),
2324
CLASS(0),
2425
FIELD(1),
2526
METHOD(1),

src/main/java/net/fabricmc/mappingio/MappingVisitor.java

+14-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@
2828
* <p>The visitation order is as follows (omitting visit prefixes for brevity, lowercase for cross references):
2929
* <ul><li>overall: header -> content -> End -> overall
3030
* <li>header: Header -> Namespaces [-> Metadata]*
31-
* <li>content: Content [-> class|Metadata]*
31+
* <li>content: Content [-> package|class|Metadata]*
32+
* <li>package: Package [-> DstName]* -> ElementContent*
3233
* <li>class: Class [-> DstName]* -> ElementContent [-> field|method|Comment]*
3334
* <li>field: Field [-> DstName|DstDesc]* -> ElementContent [-> Comment]
3435
* <li>method: Method [-> DstName|DstDesc]* -> ElementContent [-> arg|var|Comment]*
@@ -85,6 +86,18 @@ default boolean visitContent() throws IOException {
8586
return true;
8687
}
8788

89+
/**
90+
* Visit a package.
91+
*
92+
* @param srcName The package path, with slashes instead of dots, and no trailing slash.
93+
* An empty string represents the default package.
94+
* @return Whether or not the package's content should be visited too.
95+
*/
96+
// TODO: Un-"default" in the next breaking release
97+
default boolean visitPackage(String srcName) throws IOException {
98+
return false;
99+
}
100+
88101
/**
89102
* Visit a class.
90103
*

src/main/java/net/fabricmc/mappingio/adapter/FlatAsRegularMappingVisitor.java

+21-1
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,11 @@ public void visitNamespaces(String srcNamespace, List<String> dstNamespaces) thr
6464
Set<MappingFlag> flags = next.getFlags();
6565

6666
if (flags.contains(MappingFlag.NEEDS_ELEMENT_UNIQUENESS)) {
67+
dstPackageNames = new String[count];
6768
dstClassNames = new String[count];
6869
dstMemberNames = new String[count];
6970
} else {
70-
dstClassNames = dstMemberNames = null;
71+
dstPackageNames = dstClassNames = dstMemberNames = null;
7172
}
7273

7374
dstMemberDescs = flags.contains(MappingFlag.NEEDS_DST_FIELD_DESC) || flags.contains(MappingFlag.NEEDS_DST_METHOD_DESC) ? new String[count] : null;
@@ -83,6 +84,16 @@ public boolean visitContent() throws IOException {
8384
return next.visitContent();
8485
}
8586

87+
@Override
88+
public boolean visitPackage(String srcName) throws IOException {
89+
this.srcPkgName = srcName;
90+
91+
Arrays.fill(dstNames, null);
92+
if (dstPackageNames != null) Arrays.fill(dstPackageNames, null);
93+
94+
return true;
95+
}
96+
8697
@Override
8798
public boolean visitClass(String srcName) {
8899
this.srcClsName = srcName;
@@ -161,6 +172,10 @@ public boolean visitElementContent(MappedElementKind targetKind) throws IOExcept
161172
boolean relay;
162173

163174
switch (targetKind) {
175+
case PACKAGE:
176+
relay = next.visitPackage(srcPkgName, dstNames);
177+
if (relay && dstPackageNames != null) System.arraycopy(dstNames, 0, dstPackageNames, 0, dstNames.length);
178+
break;
164179
case CLASS:
165180
relay = next.visitClass(srcClsName, dstNames);
166181
if (relay && dstClassNames != null) System.arraycopy(dstNames, 0, dstClassNames, 0, dstNames.length);
@@ -193,6 +208,9 @@ public boolean visitElementContent(MappedElementKind targetKind) throws IOExcept
193208
@Override
194209
public void visitComment(MappedElementKind targetKind, String comment) throws IOException {
195210
switch (targetKind) {
211+
case PACKAGE:
212+
next.visitPackageComment(srcPkgName, dstNames, comment);
213+
break;
196214
case CLASS:
197215
next.visitClassComment(srcClsName, dstClassNames, comment);
198216
break;
@@ -217,12 +235,14 @@ public void visitComment(MappedElementKind targetKind, String comment) throws IO
217235

218236
private final FlatMappingVisitor next;
219237

238+
private String srcPkgName;
220239
private String srcClsName;
221240
private String srcMemberName;
222241
private String srcMemberDesc;
223242
private String srcMemberSubName;
224243
private int argIdx, lvIndex, startOpIdx, endOpIdx;
225244
private String[] dstNames;
245+
private String[] dstPackageNames;
226246
private String[] dstClassNames;
227247
private String[] dstMemberNames;
228248
private String[] dstMemberDescs;

src/main/java/net/fabricmc/mappingio/adapter/ForwardingMappingVisitor.java

+5
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,11 @@ public boolean visitContent() throws IOException {
6969
return next.visitContent();
7070
}
7171

72+
@Override
73+
public boolean visitPackage(String srcName) throws IOException {
74+
return next.visitPackage(srcName);
75+
}
76+
7277
@Override
7378
public boolean visitClass(String srcName) throws IOException {
7479
return next.visitClass(srcName);

src/main/java/net/fabricmc/mappingio/adapter/MappingNsCompleter.java

+7
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,13 @@ public boolean visitContent() throws IOException {
115115
return next.visitContent();
116116
}
117117

118+
@Override
119+
public boolean visitPackage(String srcName) throws IOException {
120+
this.srcName = srcName;
121+
122+
return next.visitPackage(srcName);
123+
}
124+
118125
@Override
119126
public boolean visitClass(String srcName) throws IOException {
120127
this.srcName = srcName;

src/main/java/net/fabricmc/mappingio/adapter/MappingSourceNsSwitch.java

+12
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,15 @@ public boolean visitContent() throws IOException {
142142
return next.visitContent();
143143
}
144144

145+
@Override
146+
public boolean visitPackage(String srcName) throws IOException {
147+
if (passThrough) return next.visitPackage(srcName);
148+
149+
this.srcName = srcName;
150+
151+
return true;
152+
}
153+
145154
@Override
146155
public boolean visitClass(String srcName) throws IOException {
147156
if (passThrough) return next.visitClass(srcName);
@@ -256,6 +265,9 @@ public boolean visitElementContent(MappedElementKind targetKind) throws IOExcept
256265
boolean relay;
257266

258267
switch (targetKind) {
268+
case PACKAGE:
269+
relay = next.visitPackage(dstName);
270+
break;
259271
case CLASS:
260272
relay = next.visitClass(dstName);
261273
break;

src/main/java/net/fabricmc/mappingio/adapter/RegularAsFlatMappingVisitor.java

+34-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,38 @@ public boolean visitContent() throws IOException {
7474
}
7575

7676
@Override
77-
public boolean visitClass(String srcName, String[] dstNames) throws IOException {
77+
public boolean visitPackage(String srcName, @Nullable String[] dstNames) throws IOException {
78+
return visitPackage(srcName, dstNames, null);
79+
}
80+
81+
@Override
82+
public boolean visitPackage(String srcName, String dstName) throws IOException {
83+
return visitPackage(srcName, null, dstName);
84+
}
85+
86+
private boolean visitPackage(String srcName, @Nullable String[] dstNames, @Nullable String dstName) throws IOException {
87+
if (!srcName.equals(lastPackage)) {
88+
lastPackage = srcName;
89+
relayLastPackage = next.visitPackage(srcName) && visitDstNames(MappedElementKind.PACKAGE, dstNames, dstName);
90+
}
91+
92+
return relayLastPackage;
93+
}
94+
95+
@Override
96+
public void visitPackageComment(String srcName, @Nullable String[] dstNames, String comment) throws IOException {
97+
if (!visitPackage(srcName, dstNames, null)) return;
98+
next.visitComment(MappedElementKind.PACKAGE, comment);
99+
}
100+
101+
@Override
102+
public void visitPackageComment(String srcName, @Nullable String dstName, String comment) throws IOException {
103+
if (!visitPackage(srcName, null, dstName)) return;
104+
next.visitComment(MappedElementKind.PACKAGE, comment);
105+
}
106+
107+
@Override
108+
public boolean visitClass(String srcName, @Nullable String[] dstNames) throws IOException {
78109
return visitClass(srcName, dstNames, null);
79110
}
80111

@@ -367,6 +398,8 @@ private boolean visitDstNamesDescs(MappedElementKind targetKind, @Nullable Strin
367398
private boolean relayDstFieldDescs;
368399
private boolean relayDstMethodDescs;
369400

401+
private String lastPackage;
402+
private boolean relayLastPackage;
370403
private String lastClass;
371404
private boolean relayLastClass;
372405
private String lastMemberName, lastMemberDesc;

src/main/java/net/fabricmc/mappingio/format/FeatureSet.java

+2-4
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,11 @@ public interface FeatureSet {
3030
boolean hasFileComments();
3131

3232
default boolean supportsPackages() {
33-
return packages().srcNames() != FeaturePresence.ABSENT
34-
|| packages().dstNames() != FeaturePresence.ABSENT;
33+
return packages().srcNames() != FeaturePresence.ABSENT;
3534
}
3635

3736
default boolean supportsClasses() {
38-
return classes().srcNames() != FeaturePresence.ABSENT
39-
|| classes().dstNames() != FeaturePresence.ABSENT;
37+
return classes().srcNames() != FeaturePresence.ABSENT;
4038
}
4139

4240
default boolean supportsFields() {

src/main/java/net/fabricmc/mappingio/format/MappingFormat.java

-18
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,6 @@ public enum MappingFormat {
116116

117117
/**
118118
* The {@code SRG} ("Searge RetroGuard") mapping format, as specified <a href="https://github.com/MinecraftForge/SrgUtils/blob/67f30647ece29f18256ca89a23cda6216d6bd21e/src/main/java/net/minecraftforge/srgutils/InternalUtils.java#L69-L81">here</a>.
119-
*
120-
* <h2>Implementation notes</h2>
121-
* Package mappings are currently not supported.
122119
*/
123120
SRG_FILE("SRG file", "srg", true, FeatureSetBuilder.create()
124121
.withPackages(p -> p
@@ -141,9 +138,6 @@ public enum MappingFormat {
141138
* The {@code XSRG} ("Extended SRG") mapping format, as specified <a href="https://github.com/MinecraftForge/SrgUtils/blob/67f30647ece29f18256ca89a23cda6216d6bd21e/src/main/java/net/minecraftforge/srgutils/InternalUtils.java#L69-L84">here</a>.
142139
*
143140
* <p>Same as SRG, but with field descriptors.
144-
*
145-
* <h2>Implementation notes</h2>
146-
* Package mappings are currently not supported.
147141
*/
148142
XSRG_FILE("XSRG file", "xsrg", true, FeatureSetBuilder.createFrom(SRG_FILE.features)
149143
.withFields(f -> f
@@ -168,9 +162,6 @@ public enum MappingFormat {
168162

169163
/**
170164
* The {@code CSRG} ("Compact SRG", since it saves disk space over SRG) mapping format, as specified <a href="https://github.com/MinecraftForge/SrgUtils/blob/67f30647ece29f18256ca89a23cda6216d6bd21e/src/main/java/net/minecraftforge/srgutils/InternalUtils.java#L196-L207">here</a>.
171-
*
172-
* <h2>Implementation notes</h2>
173-
* Package mappings are currently not supported.
174165
*/
175166
CSRG_FILE("CSRG file", "csrg", true, FeatureSetBuilder.createFrom(SRG_FILE.features)
176167
.withMethods(m -> m
@@ -180,17 +171,11 @@ public enum MappingFormat {
180171
* The {@code TSRG} ("Tiny SRG", since it saves disk space over SRG) mapping format, as specified <a href="https://github.com/MinecraftForge/SrgUtils/blob/67f30647ece29f18256ca89a23cda6216d6bd21e/src/main/java/net/minecraftforge/srgutils/InternalUtils.java#L196-L213">here</a>.
181172
*
182173
* <p>Same as CSRG, but hierarchical instead of flat.
183-
*
184-
* <h2>Implementation notes</h2>
185-
* Package mappings are currently not supported.
186174
*/
187175
TSRG_FILE("TSRG file", "tsrg", true, FeatureSetBuilder.createFrom(CSRG_FILE.features)),
188176

189177
/**
190178
* The {@code TSRG v2} mapping format, as specified <a href="https://github.com/MinecraftForge/SrgUtils/blob/67f30647ece29f18256ca89a23cda6216d6bd21e/src/main/java/net/minecraftforge/srgutils/InternalUtils.java#L262-L285">here</a>.
191-
*
192-
* <h2>Implementation notes</h2>
193-
* Package mappings and static markers for methods are currently not supported.
194179
*/
195180
TSRG_2_FILE("TSRG v2 file", "tsrg", true, FeatureSetBuilder.createFrom(TSRG_FILE.features)
196181
.withNamespaces(true)
@@ -255,9 +240,6 @@ public enum MappingFormat {
255240

256241
/**
257242
* The {@code JOBF} mapping format, as specified <a href="https://github.com/skylot/jadx/blob/2d5c0fda4a0c5d16207a5f48edb72e6efa7d5bbd/jadx-core/src/main/java/jadx/core/deobf/DeobfPresets.java">here</a>.
258-
*
259-
* <h2>Implementation notes</h2>
260-
* Package mappings are currently not supported.
261243
*/
262244
JOBF_FILE("JOBF file", "jobf", true, FeatureSetBuilder.create()
263245
.withPackages(c -> c

src/main/java/net/fabricmc/mappingio/format/intellij/MigrationMapFileReader.java

+11-4
Original file line numberDiff line numberDiff line change
@@ -122,22 +122,29 @@ private static void read0(BufferedReader reader, String sourceNs, String targetN
122122
break;
123123
case "entry":
124124
String type = xmlReader.getAttributeValue(null, "type");
125+
boolean isPackage;
125126

126127
if (type == null || type.isEmpty()) throw new IOException("missing/empty type attribute at line "+xmlReader.getLocation().getLineNumber());
127-
if (type.equals("package")) continue; // TODO: support packages
128-
if (!type.equals("class")) throw new IOException("unexpected entry type "+type+" at line "+xmlReader.getLocation().getLineNumber());
128+
129+
if (!(isPackage = type.equals("package")) && !type.equals("class")) {
130+
throw new IOException("unexpected entry type "+type+" at line "+xmlReader.getLocation().getLineNumber());
131+
}
129132

130133
String srcName = xmlReader.getAttributeValue(null, "oldName");
131134
String dstName = xmlReader.getAttributeValue(null, "newName");
132-
// String recursive = xmlReader.getAttributeValue(null, "recursive"); // only used for packages
135+
// String recursive = xmlReader.getAttributeValue(null, "recursive"); // only used for packages, indicates if subpackages should also be renamed
133136

134137
if (srcName == null || srcName.isEmpty()) throw new IOException("missing/empty oldName attribute at line "+xmlReader.getLocation().getLineNumber());
135138
if (dstName == null || dstName.isEmpty()) throw new IOException("missing/empty newName attribute at line "+xmlReader.getLocation().getLineNumber());
136139

137140
srcName = srcName.replace('.', '/');
138141
dstName = dstName.replace('.', '/');
139142

140-
if (visitor.visitClass(srcName)) {
143+
if (isPackage && visitor.visitPackage(srcName)) {
144+
visitor.visitDstName(MappedElementKind.PACKAGE, 0, dstName);
145+
visitor.visitElementContent(MappedElementKind.PACKAGE);
146+
// TODO: visit "recursive" attribute as element metadata once https://github.com/FabricMC/mapping-io/pull/41 is merged
147+
} else if (!isPackage && visitor.visitClass(srcName)) {
141148
visitor.visitDstName(MappedElementKind.CLASS, 0, dstName);
142149
visitor.visitElementContent(MappedElementKind.CLASS);
143150
}

src/main/java/net/fabricmc/mappingio/format/intellij/MigrationMapFileWriter.java

+16-1
Original file line numberDiff line numberDiff line change
@@ -117,10 +117,20 @@ public void visitMetadata(String key, @Nullable String value) throws IOException
117117
}
118118
}
119119

120+
@Override
121+
public boolean visitPackage(String srcName) throws IOException {
122+
this.srcName = srcName;
123+
this.dstName = null;
124+
this.isPackage = true;
125+
126+
return true;
127+
}
128+
120129
@Override
121130
public boolean visitClass(String srcName) throws IOException {
122131
this.srcName = srcName;
123132
this.dstName = null;
133+
this.isPackage = false;
124134

125135
return true;
126136
}
@@ -161,7 +171,11 @@ public boolean visitElementContent(MappedElementKind targetKind) throws IOExcept
161171
xmlWriter.writeEmptyElement("entry");
162172
xmlWriter.writeAttribute("oldName", srcName.replace('/', '.'));
163173
xmlWriter.writeAttribute("newName", dstName.replace('/', '.'));
164-
xmlWriter.writeAttribute("type", "class");
174+
xmlWriter.writeAttribute("type", isPackage ? "package" : "class");
175+
176+
if (isPackage) {
177+
xmlWriter.writeAttribute("recursive", "false"); // TODO: true or false?
178+
}
165179
} catch (XMLStreamException e) {
166180
throw new IOException(e);
167181
}
@@ -180,6 +194,7 @@ public void visitComment(MappedElementKind targetKind, String comment) throws IO
180194
private XMLStreamWriter xmlWriter;
181195
private boolean wroteName;
182196
private boolean wroteOrder;
197+
private boolean isPackage;
183198
private String srcName;
184199
private String dstName;
185200
}

0 commit comments

Comments
 (0)