diff --git a/src/common/java/net/minecraftforge/gradle/common/util/McpNames.java b/src/common/java/net/minecraftforge/gradle/common/util/McpNames.java index 823d8078b..4f032dc9c 100644 --- a/src/common/java/net/minecraftforge/gradle/common/util/McpNames.java +++ b/src/common/java/net/minecraftforge/gradle/common/util/McpNames.java @@ -44,6 +44,7 @@ import de.siegmar.fastcsv.reader.CsvReader; import de.siegmar.fastcsv.reader.CsvRow; import org.apache.commons.lang3.tuple.Pair; +import org.gradle.api.logging.Logger; public class McpNames { private static final String NEWLINE = System.getProperty("line.separator"); @@ -53,8 +54,9 @@ public class McpNames { private static final Pattern CLASS_JAVADOC_PATTERN = Pattern.compile("^(?(?: )*|\\t*)([\\w|@]*\\s)*(class|interface|@interface|enum) (?[\\w]+)"); private static final Pattern CLOSING_CURLY_BRACE = Pattern.compile("^(?(?: )*|\\t*)}"); private static final Pattern PACKAGE_DECL = Pattern.compile("^[\\s]*package(\\s)*(?[\\w|.]+);$"); + private int currentMethodIndent = -1; - public static McpNames load(File data) throws IOException { + public static McpNames load(File data, Logger logger) throws IOException { Map names = new HashMap<>(); Map docs = new HashMap<>(); try (ZipFile zip = new ZipFile(data)) { @@ -75,17 +77,19 @@ public static McpNames load(File data) throws IOException { } } - return new McpNames(HashFunction.SHA1.hash(data), names, docs); + return new McpNames(HashFunction.SHA1.hash(data), names, docs, logger); } private Map names; private Map docs; public final String hash; + private final Logger logger; - private McpNames(String hash, Map names, Map docs) { + private McpNames(String hash, Map names, Map docs, Logger logger) { this.hash = hash; this.names = names; this.docs = docs; + this.logger = logger; } public String rename(InputStream stream, boolean javadocs) throws IOException { @@ -123,7 +127,7 @@ private void injectJavadoc(List lines, String line, String _package, Deq String javadoc = docs.get(matcher.group("name")); if (!Strings.isNullOrEmpty(javadoc)) insertAboveAnnotations(lines, JavadocAdder.buildJavadoc(matcher.group("indent"), javadoc, true)); - + currentMethodIndent = matcher.group("indent").length(); // worked, so return and don't try the fields. return; } @@ -143,9 +147,23 @@ private void injectJavadoc(List lines, String line, String _package, Deq if(matcher.find()) { //we maintain a stack of the current (inner) class in com.example.ClassName$Inner format (along with indentation) //if the stack is not empty we are entering a new inner class + int parentBlockIndentation = innerClasses.isEmpty() ? 0 : innerClasses.peek().getRight(); + int currentIndentation = matcher.group("indent").length(); + if (parentBlockIndentation >= currentIndentation) { + //We haven't closed a previous class correctly, so we backtrack now. + innerClasses.removeIf(p -> p.getRight() >= currentIndentation); + } String currentClass = (innerClasses.isEmpty() ? _package : innerClasses.peek().getLeft() + "$") + matcher.group("name"); - innerClasses.push(Pair.of(currentClass, matcher.group("indent").length())); + if (parentBlockIndentation >= currentIndentation) { + logger.warn("Trying to recover inner class tracking, assuming " + currentClass + " is defined in line " + (lines.size() + 1)); + } + + innerClasses.push(Pair.of(currentClass, currentIndentation)); String javadoc = docs.get(currentClass); + if (currentMethodIndent != 0) { + logger.warn("In " + currentClass + ":" + (lines.size() + 1) + " there likely is a method inner class, which we can't handle properly"); + } + currentMethodIndent = -1; if (!Strings.isNullOrEmpty(javadoc)) { insertAboveAnnotations(lines, JavadocAdder.buildJavadoc(matcher.group("indent"), javadoc, true)); } @@ -156,12 +174,15 @@ private void injectJavadoc(List lines, String line, String _package, Deq //detect curly braces for inner class stacking/end identification matcher = CLOSING_CURLY_BRACE.matcher(line); if(matcher.find()){ + if (matcher.group("indent").length() == currentMethodIndent) { + currentMethodIndent = -1; + } if(!innerClasses.isEmpty()) { int len = matcher.group("indent").length(); if (len == innerClasses.peek().getRight()) { innerClasses.pop(); } else if (len < innerClasses.peek().getRight()) { - throw new IllegalArgumentException("Failed to properly track class blocks around class " + innerClasses.peek().getLeft() + ":" + (lines.size() + 1)); + logger.warn("Tracking inner classes failed around " + innerClasses.peek().getLeft() + ":" + (lines.size() + 1) +", classes may be annotated incorrectly. Is your indentation off?g"); } } } diff --git a/src/mcp/java/net/minecraftforge/gradle/mcp/MCPRepo.java b/src/mcp/java/net/minecraftforge/gradle/mcp/MCPRepo.java index 93d6f9f89..eedfcb2ee 100644 --- a/src/mcp/java/net/minecraftforge/gradle/mcp/MCPRepo.java +++ b/src/mcp/java/net/minecraftforge/gradle/mcp/MCPRepo.java @@ -381,7 +381,7 @@ private McpNames loadMCPNames(String name, File data) throws IOException { McpNames map = mapCache.get(name); String hash = HashFunction.SHA1.hash(data); if (map == null || !hash.equals(map.hash)) { - map = McpNames.load(data); + map = McpNames.load(data, project.getLogger()); mapCache.put(name, map); } return map; diff --git a/src/userdev/java/net/minecraftforge/gradle/userdev/MinecraftUserRepo.java b/src/userdev/java/net/minecraftforge/gradle/userdev/MinecraftUserRepo.java index d2154501f..b7896139d 100644 --- a/src/userdev/java/net/minecraftforge/gradle/userdev/MinecraftUserRepo.java +++ b/src/userdev/java/net/minecraftforge/gradle/userdev/MinecraftUserRepo.java @@ -819,7 +819,7 @@ private McpNames loadMCPNames(String name, File data) throws IOException { McpNames map = mapCache.get(name); String hash = HashFunction.SHA1.hash(data); if (map == null || !hash.equals(map.hash)) { - map = McpNames.load(data); + map = McpNames.load(data, project.getLogger()); mapCache.put(name, map); } return map; @@ -1010,7 +1010,7 @@ private File findSource(String mapping, boolean generate) throws IOException { if (cache.isSame() && sources.exists()) { debug(" Cache hit"); } else if (sources.exists() || generate) { - McpNames map = McpNames.load(names); + McpNames map = McpNames.load(names, project.getLogger()); if (!sources.getParentFile().exists()) sources.getParentFile().mkdirs(); diff --git a/src/userdev/java/net/minecraftforge/gradle/userdev/tasks/GenerateSRG.java b/src/userdev/java/net/minecraftforge/gradle/userdev/tasks/GenerateSRG.java index 8925d1525..272a5beea 100644 --- a/src/userdev/java/net/minecraftforge/gradle/userdev/tasks/GenerateSRG.java +++ b/src/userdev/java/net/minecraftforge/gradle/userdev/tasks/GenerateSRG.java @@ -48,7 +48,7 @@ public void apply() throws IOException { MappingFile obf_to_srg = MappingFile.load(srg); MappingFile ret = new MappingFile(); - McpNames map = McpNames.load(names); + McpNames map = McpNames.load(names, getLogger()); obf_to_srg.getPackages().forEach(e -> ret.addPackage(e.getMapped(), e.getMapped())); obf_to_srg.getClasses().forEach(cls -> { ret.addClass(cls.getMapped(), cls.getMapped()); diff --git a/src/userdev/java/net/minecraftforge/gradle/userdev/util/Deobfuscator.java b/src/userdev/java/net/minecraftforge/gradle/userdev/util/Deobfuscator.java index 461c350c8..632440fb4 100644 --- a/src/userdev/java/net/minecraftforge/gradle/userdev/util/Deobfuscator.java +++ b/src/userdev/java/net/minecraftforge/gradle/userdev/util/Deobfuscator.java @@ -154,7 +154,7 @@ public File deobfSources(File original, String mappings, String... cachePath) th .add("orig", original); if (!cache.isSame() || !output.exists()) { - McpNames map = McpNames.load(names); + McpNames map = McpNames.load(names, project.getLogger()); try (ZipInputStream zin = new ZipInputStream(new FileInputStream(input)); ZipOutputStream zout = new ZipOutputStream(new FileOutputStream(output))) {