Skip to content

Commit

Permalink
Use LineNumberReader
Browse files Browse the repository at this point in the history
  • Loading branch information
lukebemish committed Apr 10, 2024
1 parent fbdc67a commit a32109e
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 86 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import org.slf4j.Marker;
import org.slf4j.MarkerFactory;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.net.URISyntaxException;
Expand Down Expand Up @@ -39,8 +38,7 @@ public void loadFromPath(final Path path) throws IOException {

public void loadAT(Reader reader, String originName) throws IOException {
final HashMap<Target<?>, AccessTransformer> localATCopy = new HashMap<>(accessTransformers);
BufferedReader bufferedReader = reader instanceof BufferedReader buffered ? buffered : new BufferedReader(reader);
mergeAccessTransformers(AtParser.parse(bufferedReader, originName), localATCopy, originName);
mergeAccessTransformers(AtParser.parse(reader, originName), localATCopy, originName);
final List<AccessTransformer> invalidTransformers = invalidTransformers(localATCopy);
if (!invalidTransformers.isEmpty()) {
invalidTransformers.forEach(at -> LOGGER.error(AXFORM_MARKER,"Invalid access transform final state for target {}. Referred in resources {}.",at.getTarget(), at.getOrigins()));
Expand Down
151 changes: 76 additions & 75 deletions src/main/java/net/neoforged/accesstransformer/parser/AtParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
import net.neoforged.accesstransformer.*;
import org.objectweb.asm.Type;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.LineNumberReader;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;

Expand All @@ -21,89 +22,89 @@ private static AccessTransformer.Modifier parseModifier(String modifier, int lin
};
}

public static List<AccessTransformer> parse(BufferedReader reader, String originName) throws IOException {
List<AccessTransformer> accessTransformers = new ArrayList<>();
String line;
int index = 0;
while ((line = reader.readLine()) != null) {
index++;
StringBuilder builder = new StringBuilder();
line.chars().takeWhile(c -> c != '#').forEach(builder::appendCodePoint);
String withoutComments = builder.toString();
List<String> parts = new ArrayList<>();
builder.setLength(0);
for (char c : withoutComments.toCharArray()) {
if (Character.isWhitespace(c)) {
if (!builder.isEmpty()) {
parts.add(builder.toString());
public static List<AccessTransformer> parse(Reader wrappedReader, String originName) throws IOException {
try (LineNumberReader reader = new LineNumberReader(wrappedReader)) {
List<AccessTransformer> accessTransformers = new ArrayList<>();
String line;
while ((line = reader.readLine()) != null) {
StringBuilder builder = new StringBuilder();
line.chars().takeWhile(c -> c != '#').forEach(builder::appendCodePoint);
String withoutComments = builder.toString();
List<String> parts = new ArrayList<>();
builder.setLength(0);
for (char c : withoutComments.toCharArray()) {
if (Character.isWhitespace(c)) {
if (!builder.isEmpty()) {
parts.add(builder.toString());
}
builder.setLength(0);
} else {
builder.appendCodePoint(c);
}
builder.setLength(0);
} else {
builder.appendCodePoint(c);
}
}
if (!builder.isEmpty()) {
parts.add(builder.toString());
}
if (parts.isEmpty()) {
continue;
}
if (parts.size() < 2) {
throw new RuntimeException("Invalid line " + index + "; should be '<modifier> <class name>'");
}
String modifierString = parts.get(0);
AccessTransformer.FinalState finalState = AccessTransformer.FinalState.LEAVE;
if (modifierString.endsWith("-f")) {
finalState = AccessTransformer.FinalState.REMOVEFINAL;
modifierString = modifierString.substring(0, modifierString.length() - 2);
} else if (modifierString.endsWith("+f")) {
finalState = AccessTransformer.FinalState.MAKEFINAL;
modifierString = modifierString.substring(0, modifierString.length() - 2);
}
AccessTransformer.Modifier modifier = parseModifier(modifierString, index);
String className = parts.get(1);
int finalIndex = index;
if (className.chars().reduce(0, (last, current) -> {
if (last == 0 && !Character.isJavaIdentifierStart(current) ||
last != 0 && current != '.' && !Character.isJavaIdentifierPart(current)
) {
throw new RuntimeException("Invalid class name '"+className+"' at line " + finalIndex);
if (!builder.isEmpty()) {
parts.add(builder.toString());
}
if (parts.isEmpty()) {
continue;
}
if (parts.size() < 2) {
throw new RuntimeException("Invalid line " + reader.getLineNumber() + "; should be '<modifier> <class name>'");
}
String modifierString = parts.get(0);
AccessTransformer.FinalState finalState = AccessTransformer.FinalState.LEAVE;
if (modifierString.endsWith("-f")) {
finalState = AccessTransformer.FinalState.REMOVEFINAL;
modifierString = modifierString.substring(0, modifierString.length() - 2);
} else if (modifierString.endsWith("+f")) {
finalState = AccessTransformer.FinalState.MAKEFINAL;
modifierString = modifierString.substring(0, modifierString.length() - 2);
}
AccessTransformer.Modifier modifier = parseModifier(modifierString, reader.getLineNumber());
String className = parts.get(1);
int finalIndex = reader.getLineNumber();
if (className.chars().reduce(0, (last, current) -> {
if (last == 0 && !Character.isJavaIdentifierStart(current) ||
last != 0 && current != '.' && !Character.isJavaIdentifierPart(current)
) {
throw new RuntimeException("Invalid class name '" + className + "' at line " + finalIndex);
}
return current == '.' ? 0 : 1;
}) != 1) {
throw new RuntimeException("Invalid class name '" + className + "' at line " + reader.getLineNumber());
}
return current == '.' ? 0 : 1;
}) != 1) {
throw new RuntimeException("Invalid class name '"+className+"' at line " + index);
}

Target<?> target;
Target<?> target;

if (parts.size() < 3) {
target = new ClassTarget(className);
locateInnerClassAts(className, modifier, finalState, originName, index, accessTransformers);
} else {
String identifier = parts.get(2);
if (identifier.equals("*")) {
target = new WildcardTarget(className, false);
} else if (identifier.equals("*()")) {
target = new WildcardTarget(className, true);
} else if (identifier.contains("(")) {
String name = identifier.substring(0, identifier.indexOf('('));
// For some reason old forge ATs let you use descriptors with dots instead of slashes
// We replicate this behavior here
String desc = identifier.substring(identifier.indexOf('('))
.replace('.', '/');
Type methodDescriptor = validateMethodDescriptor(desc, index);
if (!name.equals("<init>")) {
validateIdentifier(name, "Invalid method name '", index);
}
target = new MethodTarget(className, name, methodDescriptor);
if (parts.size() < 3) {
target = new ClassTarget(className);
locateInnerClassAts(className, modifier, finalState, originName, reader.getLineNumber(), accessTransformers);
} else {
validateIdentifier(identifier, "Invalid field name '", index);
target = new FieldTarget(className, identifier);
String identifier = parts.get(2);
if (identifier.equals("*")) {
target = new WildcardTarget(className, false);
} else if (identifier.equals("*()")) {
target = new WildcardTarget(className, true);
} else if (identifier.contains("(")) {
String name = identifier.substring(0, identifier.indexOf('('));
// For some reason old forge ATs let you use descriptors with dots instead of slashes
// We replicate this behavior here
String desc = identifier.substring(identifier.indexOf('('))
.replace('.', '/');
Type methodDescriptor = validateMethodDescriptor(desc, reader.getLineNumber());
if (!name.equals("<init>")) {
validateIdentifier(name, "Invalid method name '", reader.getLineNumber());
}
target = new MethodTarget(className, name, methodDescriptor);
} else {
validateIdentifier(identifier, "Invalid field name '", reader.getLineNumber());
target = new FieldTarget(className, identifier);
}
}
accessTransformers.add(new AccessTransformer(target, modifier, finalState, originName, reader.getLineNumber()));
}
accessTransformers.add(new AccessTransformer(target, modifier, finalState, originName, index));
return accessTransformers;
}
return accessTransformers;
}

private static void locateInnerClassAts(String className, AccessTransformer.Modifier modifier, AccessTransformer.FinalState finalState, String originName, int index, List<AccessTransformer> ats) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class AtTest {
@Test
void test() {
String string = "public net.minecraft.world.World func_175663_a(ILjava/lang/String;Lcom/mojang/authlib/GameProfile;IISLjava/lang/String;Z)Lnet/minecraft/util/math/BlockPos; # isAreaLoaded";
try (BufferedReader reader = new BufferedReader(new StringReader(string))) {
try (Reader reader = new StringReader(string)) {
AtParser.parse(reader, "test");
} catch (IOException e) {
throw new UncheckedIOException(e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,7 @@
import net.neoforged.accesstransformer.parser.AtParser;
import org.junit.jupiter.api.Test;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.*;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Paths;
Expand All @@ -21,7 +18,7 @@ public class BatATParseTest {
public void testParseBadAT() throws IOException, URISyntaxException {
try (
InputStream stream = getClass().getClassLoader().getResourceAsStream("bad_at.cfg");
BufferedReader reader = new BufferedReader(new InputStreamReader(stream))) {
Reader reader = new InputStreamReader(stream)) {
List<AccessTransformer> transformers = AtParser.parse(reader, "bad_at.cfg");
List<String> lines = new ArrayList<>();
transformers.forEach(t -> lines.add(t.toString()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import net.neoforged.accesstransformer.parser.AtParser;
import org.junit.jupiter.api.Test;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path;
Expand All @@ -14,7 +14,7 @@ public class ForgeATBaseParserTest {
@Test
public void testLoadingForgeAT() throws IOException, URISyntaxException {
final Path path = Paths.get(getClass().getClassLoader().getResource("forge_at.cfg").toURI());
try (BufferedReader reader = Files.newBufferedReader(path)) {
try (Reader reader = Files.newBufferedReader(path)) {
AtParser.parse(reader, "forge_at.cfg");
}
}
Expand Down

0 comments on commit a32109e

Please sign in to comment.