added final for methodlocal vars

This commit is contained in:
Sander Hautvast 2020-07-28 15:39:53 +02:00
parent caf43cfb19
commit e22d507c30
6 changed files with 74 additions and 66 deletions

View file

@ -43,7 +43,7 @@ public class JsonReader {
* array => List
*/
public static Object read(InputStream inputStream) {
InputStream in = ensureBuffered(inputStream);
final InputStream in = ensureBuffered(inputStream);
try (Parser parser = getParser(in)) {
return read(parser);
}

View file

@ -37,37 +37,37 @@ public class Parser extends Lexer {
}
public Integer parseInteger() {
String value = parseNumber();
final String value = parseNumber();
return Double.valueOf(value).intValue();
}
public Long parseLong() {
String value = parseNumber();
final String value = parseNumber();
return Long.parseLong(value);
}
public Float parseFloat() {
String value = parseNumber();
final String value = parseNumber();
return Float.parseFloat(value);
}
public Double parseDouble() {
String value = parseNumber();
final String value = parseNumber();
return Double.parseDouble(value);
}
public Short parseShort() {
String value = parseNumber();
final String value = parseNumber();
return Short.parseShort(value);
}
public Byte parseByte() {
String value = parseNumber();
final String value = parseNumber();
return Byte.parseByte(value);
}
public Character parseCharacter() {
String string = parseString();
final String string = parseString();
return string.charAt(0);
}
@ -78,7 +78,7 @@ public class Parser extends Lexer {
advance();
}
String maybeBoolean = characterBuffer.toString();
final String maybeBoolean = characterBuffer.toString();
boolean returnValue;
if ((returnValue = maybeBoolean.equals("true")) || maybeBoolean.equals("false")) {
return returnValue;
@ -109,10 +109,10 @@ public class Parser extends Lexer {
if (current != '[') {
throw new JsonParseException("no list found");
}
List<Object> list = new ArrayList<>();
final List<Object> list = new ArrayList<>();
advance();
while (current != -1 && current != ']') {
Maybe<Object> maybeValue = parseValue();
final Maybe<Object> maybeValue = parseValue();
if (!maybeValue.isPresent()) {
break;
} else {
@ -125,7 +125,7 @@ public class Parser extends Lexer {
}
public Map<?, ?> parseObject() {
HashMap<Object, Object> map = new HashMap<>();
final HashMap<Object, Object> map = new HashMap<>();
skipWhitespace();
if (current != '{') {
throw new JsonParseException("no map found");
@ -134,7 +134,7 @@ public class Parser extends Lexer {
while (current != -1 && current != '}') {
skipWhitespace();
if (current == '"') {
String key = parseString();
final String key = parseString();
skipWhitespace();
if (current == ':') {
advance();
@ -142,7 +142,7 @@ public class Parser extends Lexer {
throw new JsonParseException("expected colon");
}
skipWhitespace();
Maybe<Object> maybeValue = parseValue();
final Maybe<Object> maybeValue = parseValue();
maybeValue.ifPresent(value -> map.put(key, value));
}
advance();
@ -152,7 +152,7 @@ public class Parser extends Lexer {
}
public Object parseAny() {
Maybe<Object> maybe = parseValue();
final Maybe<Object> maybe = parseValue();
if (maybe.isPresent()) {
return maybe.get();
} else {
@ -161,7 +161,7 @@ public class Parser extends Lexer {
}
private Maybe<Object> parseValue() {
Object value;
final Object value;
skipWhitespace();
switch (current) {
case ']':
@ -251,8 +251,8 @@ public class Parser extends Lexer {
}
private void parseEncoded() {
StringBuilder buf = new StringBuilder();
char codePoint = parseCodePoint();
final StringBuilder buf = new StringBuilder();
final char codePoint = parseCodePoint();
buf.append(codePoint);
if (Character.isHighSurrogate(codePoint)) {
expect(() -> new JsonParseException("Invalid unicode codepoint at line " + linecount), '\\', 'u');

View file

@ -7,12 +7,20 @@ import java.util.Arrays;
import java.util.Set;
import java.util.stream.Collectors;
/**
* Contains info from parsed bytecode
*/
public class ClassObject {
public class ClassObject<T> {
private final ConstantPoolEntry[] constantPool;
private final Info[] fieldInfos;
private final Info[] methodInfos;
private ConstantPoolEntry[] constantPool;
private Info[] fieldInfos;
private Info[] methodInfos;
private ClassObject(ConstantPoolEntry[] constantPool, Info[] fieldInfos, Info[] methodInfos) {
this.constantPool = constantPool;
this.fieldInfos = fieldInfos;
this.methodInfos = methodInfos;
}
private String getUtf8(int index) {
return ((Utf8Entry) constantPool[index - 1]).getUtf8();
@ -41,41 +49,44 @@ public class ClassObject<T> {
public static class Builder<T> {
private final ClassObject<T> classObject = new ClassObject<>();
private int constantPoolIndex = 0;
private int fieldInfoIndex = 0;
private int methodInfoIndex = 0;
public ClassObject<T> build() {
return classObject;
private ConstantPoolEntry[] constantPool;
private Info[] fieldInfos;
private Info[] methodInfos;
public ClassObject build() {
return new ClassObject(constantPool, fieldInfos, methodInfos);
}
public Builder<T> constantPoolCount(int constantPoolCount) {
classObject.constantPool = new ConstantPoolEntry[constantPoolCount - 1];
constantPool = new ConstantPoolEntry[constantPoolCount - 1];
return this;
}
void constantPoolEntry(ConstantPoolEntry entry) {
classObject.constantPool[constantPoolIndex++] = entry;
constantPool[constantPoolIndex++] = entry;
}
public Builder<T> fieldInfoCount(int fieldInfoCount) {
classObject.fieldInfos = new Info[fieldInfoCount];
fieldInfos = new Info[fieldInfoCount];
return this;
}
public Builder<T> fieldInfo(Info fieldInfo) {
classObject.fieldInfos[fieldInfoIndex++] = fieldInfo;
fieldInfos[fieldInfoIndex++] = fieldInfo;
return this;
}
public Builder<T> methodInfoCount(int methodInfoCount) {
classObject.methodInfos = new Info[methodInfoCount];
methodInfos = new Info[methodInfoCount];
return this;
}
public Builder<T> methodInfo(Info methodInfo) {
classObject.methodInfos[methodInfoIndex++] = methodInfo;
methodInfos[methodInfoIndex++] = methodInfo;
return this;
}
}

View file

@ -8,8 +8,8 @@ import java.io.IOException;
public class ClassReader extends DataReader {
public <T> ClassObject<T> parse(Class<T> type) {
DataInputStream in = new DataInputStream(new BufferedInputStream(type.getResourceAsStream(getResourceName(type))));
public <T> ClassObject parse(Class<T> type) {
final DataInputStream in = new DataInputStream(new BufferedInputStream(type.getResourceAsStream(getResourceName(type))));
expect(in, 0xCAFEBABE);
ClassObject.Builder<T> builder = new ClassObject.Builder<>();
@ -19,7 +19,7 @@ public class ClassReader extends DataReader {
readConstantPool(in, builder);
skip(in, 6); // u2 access_flags, u2 this_class, u2 super_class
int interfacesCount = readU16(in);
final int interfacesCount = readUnsignedShort(in);
skip(in, interfacesCount * 2); // interfaces[u2;]
readFields(in, builder);
@ -29,7 +29,7 @@ public class ClassReader extends DataReader {
}
private <T> void readConstantPool(DataInputStream in, ClassObject.Builder<T> builder) {
int constantPoolCount = readU16(in);
final int constantPoolCount = readUnsignedShort(in);
builder.constantPoolCount(constantPoolCount);
for (int i = 1; i < constantPoolCount; i++) {
builder.constantPoolEntry(readConstantPoolEntry(in));
@ -37,7 +37,7 @@ public class ClassReader extends DataReader {
}
private <T> void readFields(DataInputStream in, ClassObject.Builder<T> builder) {
int fieldInfoCount = readU16(in);
final int fieldInfoCount = readUnsignedShort(in);
builder.fieldInfoCount(fieldInfoCount);
for (int i = 0; i < fieldInfoCount; i++) {
builder.fieldInfo(readField(in));
@ -45,7 +45,7 @@ public class ClassReader extends DataReader {
}
private <T> void readMethods(DataInputStream in, ClassObject.Builder<T> builder) {
int methodInfoCount = readU16(in);
final int methodInfoCount = readUnsignedShort(in);
builder.methodInfoCount(methodInfoCount);
for (int i = 0; i < methodInfoCount; i++) {
builder.methodInfo(readMethod(in));
@ -53,7 +53,7 @@ public class ClassReader extends DataReader {
}
private <T> Info readField(DataInputStream in) {
Info fieldInfo = new Info(readU16(in), readU16(in), readU16(in), readU16(in));
final Info fieldInfo = new Info(readUnsignedShort(in), readUnsignedShort(in), readUnsignedShort(in), readUnsignedShort(in));
for (int i = 0; i < fieldInfo.getAttributesCount(); i++) {
fieldInfo.add(readAttribute(in));
}
@ -62,7 +62,7 @@ public class ClassReader extends DataReader {
}
private <T> Info readMethod(DataInputStream in) {
Info methodInfo = new Info(readU16(in), readU16(in), readU16(in), readU16(in));
final Info methodInfo = new Info(readUnsignedShort(in), readUnsignedShort(in), readUnsignedShort(in), readUnsignedShort(in));
for (int i = 0; i < methodInfo.getAttributesCount(); i++) {
methodInfo.add(readAttribute(in));
}
@ -71,9 +71,9 @@ public class ClassReader extends DataReader {
}
private AttributeInfo readAttribute(DataInputStream in) {
int attributeNameIndex = readU16(in);
int attributeLength = readS32(in);
byte[] info;
final int attributeNameIndex = readUnsignedShort(in);
final int attributeLength = readS32(in);
final byte[] info;
if (attributeLength > 0) {
info = new byte[attributeLength];
try {
@ -87,32 +87,32 @@ public class ClassReader extends DataReader {
return new AttributeInfo(attributeNameIndex, info);
}
private <T> ConstantPoolEntry readConstantPoolEntry(DataInputStream in) {
byte tag = readByte(in);
private ConstantPoolEntry readConstantPoolEntry(DataInputStream in) {
final byte tag = readByte(in);
switch (tag) {
case 1: return readUtf8Entry(in);
case 1: return new Utf8Entry(readString(in, readUnsignedShort(in)));
case 2: throw new IllegalStateException("2: invalid classpool tag");
case 3: return new IntEntry(readS32(in));
case 4: return new FloatEntry(readF32(in));
case 5: return new LongEntry(readS64(in));
case 6: return new DoubleEntry(readF64(in));
case 7: return new ClassEntry(readU16(in));
case 8: return new StringEntry(readU16(in));
case 9: return new FieldRefEntry(readU16(in), readU16(in));
case 10: return new MethodRefEntry(readU16(in), readU16(in));
case 11: return new InterfaceMethodRefEntry(readU16(in), readU16(in));
case 12: return new NameAndTypeEntry(readU16(in), readU16(in));
case 15: return new MethodHandleEntry(readU16(in), readU16(in));
case 16: return new MethodTypeEntry(readU16(in));
case 18: return new InvokeDynamicEntry(readU16(in), readU16(in));
case 19: return new ModuleEntry(readU16(in));
case 20: return new PackageEntry(readU16(in));
case 7: return new ClassEntry(readUnsignedShort(in));
case 8: return new StringEntry(readUnsignedShort(in));
case 9: return new FieldRefEntry(readUnsignedShort(in), readUnsignedShort(in));
case 10: return new MethodRefEntry(readUnsignedShort(in), readUnsignedShort(in));
case 11: return new InterfaceMethodRefEntry(readUnsignedShort(in), readUnsignedShort(in));
case 12: return new NameAndTypeEntry(readUnsignedShort(in), readUnsignedShort(in));
case 15: return new MethodHandleEntry(readUnsignedShort(in), readUnsignedShort(in));
case 16: return new MethodTypeEntry(readUnsignedShort(in));
case 18: return new InvokeDynamicEntry(readUnsignedShort(in), readUnsignedShort(in));
case 19: return new ModuleEntry(readUnsignedShort(in));
case 20: return new PackageEntry(readUnsignedShort(in));
default: throw new IllegalStateException("invalid classpool");
}
}
protected <T> String getResourceName(Class<T> type) {
StringBuilder typeName = new StringBuilder("/" + type.getName());
final StringBuilder typeName = new StringBuilder("/" + type.getName());
for (int i = 0; i < typeName.length(); i++) {
if (typeName.charAt(i) == '.') {

View file

@ -1,12 +1,13 @@
package nl.sander.jsontoy2.java;
import nl.sander.jsontoy2.java.constantpool.Utf8Entry;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
/**
* basic IO operations with runtime exceptions
*/
public class DataReader {
protected long readS64(DataInputStream in) {
@ -33,7 +34,7 @@ public class DataReader {
}
}
protected int readU16(DataInputStream in) {
protected int readUnsignedShort(DataInputStream in) {
try {
return in.readUnsignedShort();
} catch (IOException e) {
@ -49,11 +50,6 @@ public class DataReader {
}
}
protected Utf8Entry readUtf8Entry(DataInputStream in) {
int length = readU16(in);
return new Utf8Entry(readString(in, length));
}
protected String readString(DataInputStream in, int length) {
try {
byte[] bytes = in.readNBytes(length);

View file

@ -8,11 +8,12 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
public class ClassReaderTest {
//part of the test
public int field;
@Test
public void testReadClass() {
ClassObject<ClassReaderTest> object = new ClassReader().parse(ClassReaderTest.class);
ClassObject object = new ClassReader().parse(ClassReaderTest.class);
assertEquals(Set.of(new Field("field", "I")), object.getFields());
assertEquals(Set.of(new Method("<init>", "()V"), new Method("testReadClass", "()V")), object.getMethods());
}