From 73313b0f1c1660986afc1449960889cac242eee0 Mon Sep 17 00:00:00 2001 From: jeff Date: Thu, 5 Feb 2015 23:51:40 -0500 Subject: add new type/signature system --- src/cuchaz/enigma/mapping/BehaviorSignature.java | 96 ++++++++++++ src/cuchaz/enigma/mapping/Type.java | 179 +++++++++++++++++++++++ 2 files changed, 275 insertions(+) create mode 100644 src/cuchaz/enigma/mapping/BehaviorSignature.java create mode 100644 src/cuchaz/enigma/mapping/Type.java (limited to 'src') diff --git a/src/cuchaz/enigma/mapping/BehaviorSignature.java b/src/cuchaz/enigma/mapping/BehaviorSignature.java new file mode 100644 index 00000000..a6371f85 --- /dev/null +++ b/src/cuchaz/enigma/mapping/BehaviorSignature.java @@ -0,0 +1,96 @@ +package cuchaz.enigma.mapping; + +import java.util.List; + +import com.beust.jcommander.internal.Lists; + +public class BehaviorSignature { + + public static interface ClassReplacer { + ClassEntry replace(ClassEntry entry); + } + + private List m_argumentTypes; + private Type m_returnType; + + public BehaviorSignature(String signature) { + m_argumentTypes = Lists.newArrayList(); + int i=0; + while (i getArgumentTypes() { + return m_argumentTypes; + } + + public Type getReturnType() { + return m_returnType; + } + + @Override + public String toString() { + StringBuilder buf = new StringBuilder(); + buf.append("("); + for (int i=0; i 0) { + buf.append(","); + } + buf.append(m_argumentTypes.get(i).toString()); + } + buf.append(")"); + buf.append(m_returnType.toString()); + return buf.toString(); + } + + public Iterable types() { + List types = Lists.newArrayList(); + types.addAll(m_argumentTypes); + types.add(m_returnType); + return types; + } + + public Iterable classes() { + List out = Lists.newArrayList(); + for (Type type : types()) { + if (type.isClass()) { + out.add(type.getClassEntry()); + } + } + return out; + } +} diff --git a/src/cuchaz/enigma/mapping/Type.java b/src/cuchaz/enigma/mapping/Type.java new file mode 100644 index 00000000..2273e21b --- /dev/null +++ b/src/cuchaz/enigma/mapping/Type.java @@ -0,0 +1,179 @@ +package cuchaz.enigma.mapping; + +import java.util.Map; + +import com.google.common.collect.Maps; + +public class Type { + + public enum Primitive { + Byte('B'), + Character('C'), + Short('S'), + Integer('I'), + Long('J'), + Float('F'), + Double('D'), + Boolean('Z'); + + private static final Map m_lookup; + + static { + m_lookup = Maps.newTreeMap(); + for (Primitive val : values()) { + m_lookup.put(val.getCode(), val); + } + } + + public static Primitive get(char code) { + return m_lookup.get(code); + } + + private char m_code; + + private Primitive(char code) { + m_code = code; + } + + public char getCode() { + return m_code; + } + } + + public static String parseFirst(String in) { + + // read one type from the input + + char c = in.charAt(0); + + // first check for void + if (c == 'V') { + return "V"; + } + + // then check for primitives + Primitive primitive = Primitive.get(c); + if (primitive != null) { + return in.substring(0, 1); + } + + // then check for classes + if (c == 'L') { + return readClass(in); + } + + // then check for arrays + int dim = countArrayDimension(in); + if (dim > 0) { + String arrayType = Type.parseFirst(in.substring(dim)); + return in.substring(0, dim + arrayType.length()); + } + + throw new IllegalArgumentException("don't know how to parse: " + in); + } + + private String m_name; + + public Type(String name) { + m_name = name; + } + + public Type(ClassEntry classEntry) { + m_name = "L" + classEntry.getClassName() + ";"; + } + + @Override + public String toString() { + return m_name; + } + + public boolean isVoid() { + return m_name.length() == 1 && m_name.charAt(0) == 'V'; + } + + public boolean isPrimitive() { + return m_name.length() == 1 && Primitive.get(m_name.charAt(0)) != null; + } + + public Primitive getPrimitive() { + if (!isPrimitive()) { + throw new IllegalStateException("not a primitive"); + } + return Primitive.get(m_name.charAt(0)); + } + + public boolean isClass() { + return m_name.charAt(0) == 'L' && m_name.charAt(m_name.length() - 1) == ';'; + } + + public ClassEntry getClassEntry() { + if (!isClass()) { + throw new IllegalStateException("not a class"); + } + String name = m_name.substring(1, m_name.length() - 1); + + int pos = name.indexOf('<'); + if (pos >= 0) { + // remove the parameters from the class name + name = name.substring(0, pos); + } + + return new ClassEntry(name); + } + + public boolean isArray() { + return m_name.charAt(0) == '['; + } + + public int getArrayDimension() { + if (!isArray()) { + throw new IllegalStateException("not an array"); + } + return countArrayDimension(m_name); + } + + public Type getArrayType() { + if (!isArray()) { + throw new IllegalStateException("not an array"); + } + return new Type(m_name.substring(getArrayDimension(), m_name.length())); + } + + @Override + public boolean equals(Object other) { + if (other instanceof Type) { + return equals((Type)other); + } + return false; + } + + public boolean equals(Type other) { + return m_name.equals(other.m_name); + } + + private static int countArrayDimension(String in) { + int i=0; + for(; i < in.length() && in.charAt(i) == '['; i++); + return i; + } + + private static String readClass(String in) { + // read all the characters in the buffer until we hit a ';' + // remember to treat parameters correctly + StringBuilder buf = new StringBuilder(); + int depth = 0; + for (int i=0; i') { + depth--; + } else if (depth == 0 && c == ';') { + return buf.toString(); + } + } + return null; + } +} -- cgit v1.2.3