org.extendj.ast.Signatures Maven / Gradle / Ivy
package org.extendj.ast;
import java.util.ArrayList;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.IOException;
import java.util.Set;
import beaver.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.LinkedHashSet;
import java.util.*;
import org.jastadd.util.PrettyPrintable;
import org.jastadd.util.PrettyPrinter;
import java.util.zip.*;
import java.io.*;
import org.jastadd.util.*;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
/**
* @ast class
* @aspect BytecodeSignatures
* @declaredat /home/jesper/git/extendj/java5/frontend/BytecodeSignatures.jrag:33
*/
public class Signatures extends java.lang.Object {
// Simple parser framework.
String data;
int pos;
public Signatures(String s) {
data = s;
pos = 0;
}
public boolean next(String s) {
for (int i = 0; i < s.length(); i++) {
if (data.charAt(pos + i) != s.charAt(i)) {
return false;
}
}
return true;
}
public void eat(String s) {
for (int i = 0; i < s.length(); i++) {
if (data.charAt(pos + i) != s.charAt(i)) {
error(s);
}
}
pos += s.length();
}
public void error(String s) {
throw new Error("Expected " + s + " but found " + data.substring(pos));
}
public String identifier() {
int i = pos;
while (Character.isJavaIdentifierPart(data.charAt(i))) {
i++;
}
String result = data.substring(pos, i);
pos = i;
return result;
}
public boolean eof() {
return pos == data.length();
}
// 4.4.4 Signatures
public static class ClassSignature extends Signatures {
protected Access superclassSignature;
protected List superinterfaceSignature = new List();
public ClassSignature(String s) {
super(s);
classSignature();
}
void classSignature() {
if (next("<")) {
formalTypeParameters();
}
superclassSignature = parseSuperclassSignature();
while (!eof()) {
superinterfaceSignature.add(parseSuperinterfaceSignature());
}
}
public boolean hasFormalTypeParameters() {
return typeParameters != null;
}
public List typeParameters() {
return typeParameters;
}
public boolean hasSuperclassSignature() {
return superclassSignature != null;
}
public Access superclassSignature() {
return superclassSignature;
}
public boolean hasSuperinterfaceSignature() {
return superinterfaceSignature.getNumChildNoTransform() != 0;
}
public List superinterfaceSignature() {
return superinterfaceSignature;
}
Access parseSuperclassSignature() {
return classTypeSignature();
}
Access parseSuperinterfaceSignature() {
return classTypeSignature();
}
}
public static class FieldSignature extends Signatures {
private Access fieldTypeAccess;
public FieldSignature(String s) {
super(s);
fieldTypeAccess = fieldTypeSignature();
}
Access fieldTypeAccess() {
return fieldTypeAccess;
}
}
public static class MethodSignature extends Signatures {
protected Collection parameterTypes = new ArrayList();
protected List exceptionList = new List();
protected Access returnType = null;
public MethodSignature(String s) {
super(s);
methodTypeSignature();
}
void methodTypeSignature() {
if (next("<")) {
formalTypeParameters();
}
eat("(");
while (!next(")")) {
parameterTypes.add(typeSignature());
}
eat(")");
returnType = parseReturnType();
while (!eof()) {
exceptionList.add(throwsSignature());
}
}
Access parseReturnType() {
if (next("V")) {
eat("V");
return new PrimitiveTypeAccess("void");
} else {
return typeSignature();
}
}
Access throwsSignature() {
eat("^");
if (next("L")) {
return classTypeSignature();
} else {
return typeVariableSignature();
}
}
public boolean hasFormalTypeParameters() {
return typeParameters != null;
}
public List typeParameters() {
return typeParameters;
}
public Collection parameterTypes() {
return parameterTypes;
}
public List exceptionList() {
return exceptionList;
}
public boolean hasExceptionList() {
return exceptionList.getNumChildNoTransform() != 0;
}
public boolean hasReturnType() {
return returnType != null;
}
public Access returnType() {
return returnType;
}
}
protected List typeParameters;
void formalTypeParameters() {
eat("<");
typeParameters = new List();
do {
typeParameters.add(formalTypeParameter());
} while (!next(">"));
eat(">");
}
TypeVariable formalTypeParameter() {
String id = identifier();
List bounds = new List();
Access classBound = classBound();
if (classBound != null) {
bounds.add(classBound);
}
while (next(":")) {
bounds.add(interfaceBound());
}
if (bounds.getNumChildNoTransform() == 0) {
bounds.add(new TypeAccess("java.lang", "Object"));
}
return new TypeVariable(new Modifiers(new List()), id, new List(), bounds);
}
Access classBound() {
eat(":");
if (nextIsFieldTypeSignature()) {
return fieldTypeSignature();
} else {
return null;
}
}
Access interfaceBound() {
eat(":");
return fieldTypeSignature();
}
Access fieldTypeSignature() {
if (next("L")) {
return classTypeSignature();
} else if (next("[")) {
return arrayTypeSignature();
} else if (next("T")) {
return typeVariableSignature();
} else {
error("L or [ or T");
}
return null; // Error never returns.
}
boolean nextIsFieldTypeSignature() {
return next("L") || next("[") || next("T");
}
Access classTypeSignature() {
eat("L");
// Package and Type Name.
StringBuilder packageName = new StringBuilder();
String typeName = identifier();
while (next("/")) {
eat("/");
if (packageName.length() != 0) {
packageName.append(".");
}
packageName.append(typeName);
typeName = identifier();
}
Access a = typeName.indexOf('$') == -1 ?
new TypeAccess(packageName.toString(), typeName) :
new BytecodeTypeAccess(packageName.toString(), typeName);
if (next("<")) { // Type arguments of top level type.
a = new ParTypeAccess(a, typeArguments());
}
while (next(".")) { // Inner classes.
a = a.qualifiesAccess(classTypeSignatureSuffix());
}
eat(";");
return a;
}
Access classTypeSignatureSuffix() {
eat(".");
String id = identifier();
Access a = id.indexOf('$') == -1 ?
new TypeAccess(id) : new BytecodeTypeAccess("", id);
if (next("<")) {
a = new ParTypeAccess(a, typeArguments());
}
return a;
}
Access typeVariableSignature() {
eat("T");
String id = identifier();
eat(";");
return new TypeAccess(id);
}
List typeArguments() {
eat("<");
List list = new List();
do {
list.add(typeArgument());
} while (!next(">"));
eat(">");
return list;
}
Access typeArgument() {
if (next("*")) {
eat("*");
return new Wildcard();
} else if (next("+")) {
eat("+");
return new WildcardExtends(fieldTypeSignature());
} else if (next("-")) {
eat("-");
return new WildcardSuper(fieldTypeSignature());
} else {
return fieldTypeSignature();
}
}
Access arrayTypeSignature() {
eat("[");
return new ArrayTypeAccess(typeSignature());
}
Access typeSignature() {
if (nextIsFieldTypeSignature()) {
return fieldTypeSignature();
} else {
return baseType();
}
}
Access baseType() {
if (next("B")) {
eat("B");
return new PrimitiveTypeAccess("byte");
} else if (next("C")) {
eat("C");
return new PrimitiveTypeAccess("char");
} else if (next("D")) {
eat("D");
return new PrimitiveTypeAccess("double");
} else if (next("F")) {
eat("F");
return new PrimitiveTypeAccess("float");
} else if (next("I")) {
eat("I");
return new PrimitiveTypeAccess("int");
} else if (next("J")) {
eat("J");
return new PrimitiveTypeAccess("long");
} else if (next("S")) {
eat("S");
return new PrimitiveTypeAccess("short");
} else if (next("Z")) {
eat("Z");
return new PrimitiveTypeAccess("boolean");
}
error("baseType");
return null; // Error never returns.
}
}