Skip to content

Commit d1621bd

Browse files
committed
Fix issues with Type annotations while extracting.
Stabilize batch output by sorting after everything is processed. Properly implement cache copying.
1 parent a521287 commit d1621bd

File tree

8 files changed

+146
-11
lines changed

8 files changed

+146
-11
lines changed

build.gradle

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ plugins {
2020
group = 'net.minecraftforge'
2121
archivesBaseName = 'srg2source'
2222
version = gradleutils.tagOffsetVersion
23+
logger.lifecycle("Version ${version}")
2324

2425
java {
2526
toolchain.languageVersion = JavaLanguageVersion.of(17)
@@ -77,12 +78,12 @@ tasks.register('shadowJarPatched', Jar).configure {
7778
dependsOn patchJDT
7879
archiveClassifier = 'fatjar'
7980
manifest = jar.manifest
80-
81+
8182
from(zipTree(patchJDT.output))
8283
from(sourceSets.main.output) {
8384
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
8485
}
85-
86+
8687
from { configurations.shadow.collect { it.isDirectory() ? it : zipTree(it) } } {
8788
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
8889
}

src/main/java/net/minecraftforge/srg2source/api/RangeExtractorBuilder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ public RangeExtractorBuilder batch() {
124124
}
125125

126126
public RangeExtractorBuilder batch(boolean value) {
127-
this.batch = true;
127+
this.batch = value;
128128
return this;
129129
}
130130

src/main/java/net/minecraftforge/srg2source/apply/RangeApplier.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import net.minecraftforge.srg2source.api.OutputSupplier;
3535
import net.minecraftforge.srg2source.range.RangeMap;
3636
import net.minecraftforge.srg2source.range.entries.ClassLiteral;
37+
import net.minecraftforge.srg2source.range.entries.ClassPackageReference;
3738
import net.minecraftforge.srg2source.range.entries.ClassReference;
3839
import net.minecraftforge.srg2source.range.entries.FieldLiteral;
3940
import net.minecraftforge.srg2source.range.entries.FieldReference;
@@ -265,6 +266,21 @@ private List<String> processJavaSourceFile(String fileName, String data, RangeMa
265266
}
266267
break;
267268
}
269+
case CLASS_PACKAGE: {
270+
// This is much like the Class Reference, except that we only care about the package part.
271+
// We run into this when there are Type annotations on a fully qualified class name.
272+
// EXA: com.example.@Nullable Foo
273+
// This will be emitted as:
274+
// CLASS_PACKAGE: `come.example.`
275+
// CLASS: `Nullable`
276+
// CLASS: `Foo`
277+
ClassPackageReference ref = (ClassPackageReference)info;
278+
String fullname = fixLocalClassName(mapClass(ref.getClassName()));
279+
idx = fullname.lastIndexOf('/');
280+
String packagename = idx == -1 ? null : fullname.substring(0, idx);
281+
newName = packagename.replace('/', '.');
282+
break;
283+
}
268284
case FIELD: {
269285
FieldReference ref = (FieldReference)info;
270286
newName = mapField(ref.getOwner(), ref.getName());

src/main/java/net/minecraftforge/srg2source/extract/RangeExtractor.java

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,15 @@
1616
import java.nio.charset.StandardCharsets;
1717
import java.util.ArrayList;
1818
import java.util.Arrays;
19+
import java.util.Collections;
1920
import java.util.HashMap;
2021
import java.util.Hashtable;
2122
import java.util.LinkedHashSet;
23+
import java.util.List;
2224
import java.util.Locale;
2325
import java.util.Map;
2426
import java.util.Set;
27+
import java.util.concurrent.ConcurrentHashMap;
2528

2629
import net.minecraftforge.srg2source.api.InputSupplier;
2730
import net.minecraftforge.srg2source.api.SourceVersion;
@@ -204,6 +207,7 @@ private boolean batchGenerate(String[] files) {
204207
//TODO: Check org.eclipse.jdt.internal.compiler.batch.FileSystem.getClasspath(String, String, boolean, AccessRuleSet, String, Map<String, String>, String)
205208
// That is where it loads sourceDirs as classpath entries. Try and hijack to include InputSuppliers?
206209
ASTParser parser = createParser(null);
210+
Map<String, RangeMapBuilder> builders = new ConcurrentHashMap<>();
207211

208212
FileASTRequestor requestor = new FileASTRequestor() {
209213
@Override
@@ -219,6 +223,7 @@ public void acceptAST(String path, CompilationUnit cu) {
219223
String md5 = Util.md5(data, encoding);
220224

221225
RangeMapBuilder builder = new RangeMapBuilder(RangeExtractor.this, path, md5);
226+
builders.put(path, builder);
222227

223228
log("startProcessing \"" + path + "\" md5: " + md5);
224229

@@ -233,10 +238,6 @@ public void acceptAST(String path, CompilationUnit cu) {
233238
SymbolReferenceWalker walker = new SymbolReferenceWalker(RangeExtractor.this, builder, enableMixins);
234239
rethrow(walker.safeWalk(cu));
235240
}
236-
237-
RangeMap range = builder.build();
238-
if (output != null)
239-
range.write(output, true);
240241
log("endProcessing \"" + path + "\"");
241242
log("");
242243
} catch (IOException e) {
@@ -249,6 +250,17 @@ public void acceptAST(String path, CompilationUnit cu) {
249250

250251
parser.createASTs(files, null, new String[0], requestor, monitor);
251252

253+
if (output != null) {
254+
List<String> names = new ArrayList<>(builders.keySet());
255+
Collections.sort(names);
256+
257+
for (String path : names) {
258+
RangeMapBuilder builder = builders.get(path);
259+
RangeMap range = builder.build();
260+
range.write(output, true);
261+
}
262+
}
263+
252264
cleanup();
253265

254266
RangeExtractor.INSTANCE = null;

src/main/java/net/minecraftforge/srg2source/extract/SymbolReferenceWalker.java

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ private boolean process(SimpleName node) {
375375
error("Could not resolve method binding: " + builder.getFilename() + " @ " + node.getStartPosition() + " Text: " + node.toString());
376376
else */
377377
error(node, "Null IBinding: " + node.toString());
378-
return false;
378+
return true;
379379
}
380380

381381
switch (bind.getKind()) {
@@ -445,6 +445,52 @@ else if (var.isParameter())
445445
}
446446
}
447447

448+
// This is basically the same as QualifiedName, except it has the potential to have a annotation in the middle.
449+
private boolean process(NameQualifiedType node) {
450+
IBinding bind = node.resolveBinding();
451+
if (bind == null) {
452+
error(node, "Null IBinding: " + node.toString());
453+
return false;
454+
}
455+
switch (bind.getKind()) {
456+
case IBinding.TYPE:
457+
ITypeBinding type = (ITypeBinding)bind;
458+
if (type.isTypeVariable()) {
459+
error(node, "Named Qualified generic type variable?: " + node.toString());
460+
return false;
461+
}
462+
// Qualified type names are make up of two parts, the qualifier, and the name.
463+
// Optionally they can have an array of annotations stuck in the middle.
464+
// The qualifier itself can be a NameQualifiedType, SimpleName, QualifiedName, or some other node.
465+
// We can recursively parse those nodes and export as normal.
466+
// We need to mark the name reference as not requiring a import so that we don't add one during Apply.
467+
// However, is the qualifier is a package, we need to output a special package reference so we can
468+
// know which class the package belongs to.
469+
IBinding qualifier = node.getQualifier().resolveBinding();
470+
if (qualifier.getKind() == IBinding.PACKAGE) {
471+
Name pkg = node.getQualifier();
472+
String clsName = getInternalName(type, node);
473+
builder.addClassPackageReference(pkg.getStartPosition(), pkg.getLength(), pkg.toString(), clsName);
474+
} else {
475+
acceptChild(node.getQualifier());
476+
}
477+
acceptChildren(node.annotations());
478+
479+
SimpleName name = node.getName();
480+
ITypeBinding nameBind = name.resolveTypeBinding();
481+
if (nameBind == null) {
482+
error(node, "Null ITypeBinding: " + name.toString());
483+
} else {
484+
String clsName = getInternalName(nameBind, name);
485+
builder.addClassReference(name.getStartPosition(), name.getLength(), name.toString(), clsName, true);
486+
}
487+
return false;
488+
default:
489+
error(node, "Unknown IBinding Kind: " + bind.getKind() + " Text: " + node.toString());
490+
return false;
491+
}
492+
}
493+
448494
private boolean process(QualifiedName node) {
449495
IBinding bind = node.resolveBinding();
450496

@@ -740,7 +786,7 @@ public ASTVisitor getVisitor() {
740786
@Override public boolean visit(ModuleDeclaration node) { return true; }
741787
@Override public boolean visit(ModuleModifier node) { return true; }
742788
@Override public boolean visit(ModuleQualifiedName node) { return true; }
743-
@Override public boolean visit(NameQualifiedType node) { return true; }
789+
@Override public boolean visit(NameQualifiedType node) { return process(node); }
744790
@Override public boolean visit(NormalAnnotation node) { return process(node); }
745791
@Override public boolean visit(NullLiteral node) { return true; }
746792
@Override public boolean visit(NullPattern node) { return true; }

src/main/java/net/minecraftforge/srg2source/range/RangeMapBuilder.java

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import java.util.List;
1111

1212
import net.minecraftforge.srg2source.range.entries.ClassLiteral;
13+
import net.minecraftforge.srg2source.range.entries.ClassPackageReference;
1314
import net.minecraftforge.srg2source.range.entries.ClassReference;
1415
import net.minecraftforge.srg2source.range.entries.FieldLiteral;
1516
import net.minecraftforge.srg2source.range.entries.FieldReference;
@@ -44,9 +45,18 @@ public String getFilename() {
4445
}
4546

4647
public boolean loadCache(RangeMap cache) {
47-
if (cache == null || !filename.equals(cache.getFilename()) || !hash.equals(cache.getHash()))
48+
if (cache == null)
4849
return false;
49-
return false;
50+
if (!filename.equals(cache.getFilename()))
51+
return false;
52+
if (hash == null || !hash.equals(cache.getHash()))
53+
return false;
54+
55+
this.entries.addAll(cache.getEntries());
56+
this.structures.addAll(cache.getStructures());
57+
this.meta.addAll(meta);
58+
59+
return true;
5060
}
5161

5262
public RangeMap build() {
@@ -116,6 +126,10 @@ public void addClassReference(int start, int length, String text, String interna
116126
addCode(ClassReference.create(start, length, text, internal, qualified));
117127
}
118128

129+
public void addClassPackageReference(int start, int length, String text, String internal) {
130+
addCode(ClassPackageReference.create(start, length, text, internal));
131+
}
132+
119133
public void addClassLiteral(int start, int length, String text, String internal) {
120134
addCode(ClassLiteral.create(start, length, text, internal));
121135
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* Copyright (c) Forge Development LLC
3+
* SPDX-License-Identifier: LGPL-2.1-only
4+
*/
5+
6+
package net.minecraftforge.srg2source.range.entries;
7+
8+
import java.util.List;
9+
import java.util.function.Consumer;
10+
11+
import net.minecraftforge.srg2source.util.Util;
12+
13+
public class ClassPackageReference extends RangeEntry {
14+
public static ClassPackageReference create(int start, int length, String text, String className) {
15+
return new ClassPackageReference(start, length, text, className);
16+
}
17+
18+
static ClassPackageReference read(int spec, int start, int length, String text, String data) {
19+
List<String> pts = Util.unquote(data, 1);
20+
if (pts.size() != 1)
21+
throw new IllegalArgumentException("Invalid Class reference: " + data);
22+
return new ClassPackageReference(start, length, text, pts.get(0));
23+
}
24+
25+
private final String className;
26+
27+
protected ClassPackageReference(int start, int length, String text, String className) {
28+
super(RangeEntry.Type.CLASS_PACKAGE, start, length, text);
29+
this.className = className;
30+
}
31+
32+
public String getClassName() {
33+
return this.className;
34+
}
35+
36+
@Override
37+
protected String getExtraFields() {
38+
return "Internal: " + className;
39+
}
40+
41+
@Override
42+
protected void writeInternal(Consumer<String> out) {
43+
out.accept(Util.quote(className));
44+
}
45+
}

src/main/java/net/minecraftforge/srg2source/range/entries/RangeEntry.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ public abstract class RangeEntry implements IRange {
1616
public enum Type {
1717
PACKAGE(PackageReference::read),
1818
CLASS(ClassReference::read),
19+
CLASS_PACKAGE(ClassPackageReference::read),
1920
CLASS_LITERAL(ClassLiteral::read),
2021
FIELD(FieldReference::read),
2122
FIELD_LITERAL(FieldLiteral::read),

0 commit comments

Comments
 (0)