package jetbrains.mps.baseLanguage.javastub.asm;
/*Generated by MPS */
import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.signature.SignatureReader;
import org.jetbrains.org.objectweb.asm.signature.SignatureVisitor;
import java.util.List;
import java.util.Collections;
import java.util.ArrayList;
import java.util.Stack;
/*package*/ class TypeUtil {
/*package*/ TypeUtil() {
}
/*package*/ static ASMType fromDescriptor(String desc) {
return TypeUtil.fromType(Type.getType(desc));
}
/*package*/ static ASMType fromType(Type type) {
switch (type.getSort()) {
case Type.VOID:
return ASMPrimitiveType.VOID;
case Type.BOOLEAN:
return ASMPrimitiveType.BOOLEAN;
case Type.CHAR:
return ASMPrimitiveType.CHAR;
case Type.BYTE:
return ASMPrimitiveType.BYTE;
case Type.SHORT:
return ASMPrimitiveType.SHORT;
case Type.INT:
return ASMPrimitiveType.INT;
case Type.FLOAT:
return ASMPrimitiveType.FLOAT;
case Type.LONG:
return ASMPrimitiveType.LONG;
case Type.DOUBLE:
return ASMPrimitiveType.DOUBLE;
case Type.OBJECT:
return new ASMClassType(type.getClassName());
case Type.ARRAY:
{
ASMType result = new ASMArrayType(TypeUtil.fromType(type.getElementType()));
for (int i = 1; i < type.getDimensions(); i++) {
result = new ASMArrayType(result);
}
return result;
}
default:
}
return null;
}
/*package*/ static ASMType getReturnType(String signature) {
if (signature == null) {
return null;
}
SignatureReader reader = new SignatureReader(signature);
final TypeUtil.TypeBuilderVisitor builder = new TypeUtil.TypeBuilderVisitor();
reader.accept(new SignatureVisitorAdapter() {
@Override
public SignatureVisitor visitReturnType() {
return builder;
}
});
return builder.getResult();
}
/*package*/ static List<ASMType> getParameterTypes(String signature) {
if (signature == null) {
return Collections.emptyList();
}
SignatureReader reader = new SignatureReader(signature);
final List<TypeUtil.TypeBuilderVisitor> visitors = new ArrayList<TypeUtil.TypeBuilderVisitor>();
reader.accept(new SignatureVisitorAdapter() {
@Override
public SignatureVisitor visitParameterType() {
TypeUtil.TypeBuilderVisitor v = new TypeUtil.TypeBuilderVisitor();
visitors.add(v);
return v;
}
});
List<ASMType> types = new ArrayList<ASMType>(visitors.size());
for (TypeUtil.TypeBuilderVisitor v : visitors) {
types.add(v.getResult());
}
return types;
}
public static List<ASMFormalTypeParameter> getFormalTypeParameters(String signature) {
final List<ASMFormalTypeParameter> result = new ArrayList<ASMFormalTypeParameter>();
if (signature == null) {
return result;
}
SignatureReader reader = new SignatureReader(signature);
reader.accept(new SignatureVisitorAdapter() {
private String name = null;
private TypeUtil.TypeBuilderVisitor classBoundVisitor = new TypeUtil.TypeBuilderVisitor();
private List<TypeUtil.TypeBuilderVisitor> interfaceBoundVisitors = new ArrayList<TypeUtil.TypeBuilderVisitor>();
@Override
public void visitFormalTypeParameter(String name) {
if (this.name != null) {
flush();
}
this.name = name;
}
@Override
public SignatureVisitor visitClassBound() {
classBoundVisitor = new TypeUtil.TypeBuilderVisitor();
return classBoundVisitor;
}
@Override
public SignatureVisitor visitInterfaceBound() {
TypeUtil.TypeBuilderVisitor visitor = new TypeUtil.TypeBuilderVisitor();
interfaceBoundVisitors.add(visitor);
return visitor;
}
@Override
public SignatureVisitor visitReturnType() {
if (name != null) {
flush();
}
return super.visitReturnType();
}
@Override
public SignatureVisitor visitSuperclass() {
if (name != null) {
flush();
}
return super.visitSuperclass();
}
private void flush() {
List<ASMType> interfaceBounds = new ArrayList<ASMType>(interfaceBoundVisitors.size());
for (TypeUtil.TypeBuilderVisitor v : interfaceBoundVisitors) {
interfaceBounds.add(v.getResult());
}
ASMType formalType = null;
if (classBoundVisitor != null) {
formalType = classBoundVisitor.getResult();
if (formalType instanceof ASMClassType) {
ASMClassType classFormalType = (ASMClassType) formalType;
if (classFormalType.getName().equals(Object.class.getName())) {
formalType = null;
}
}
}
result.add(new ASMFormalTypeParameter(name, formalType, interfaceBounds));
name = null;
classBoundVisitor = null;
interfaceBoundVisitors.clear();
}
});
return result;
}
public static List<ASMType> getExceptionTypes(String signature) {
if (signature == null) {
return Collections.emptyList();
}
SignatureReader reader = new SignatureReader(signature);
final List<TypeUtil.TypeBuilderVisitor> visitors = new ArrayList<TypeUtil.TypeBuilderVisitor>();
reader.accept(new SignatureVisitorAdapter() {
@Override
public SignatureVisitor visitExceptionType() {
TypeUtil.TypeBuilderVisitor v = new TypeUtil.TypeBuilderVisitor();
visitors.add(v);
return v;
}
});
final List<ASMType> types = new ArrayList<ASMType>(visitors.size());
for (TypeUtil.TypeBuilderVisitor v : visitors) {
types.add(v.getResult());
}
return types;
}
public static ASMType getFieldType(String signature) {
if (signature == null) {
return null;
}
final TypeUtil.TypeBuilderVisitor builder = new TypeUtil.TypeBuilderVisitor();
SignatureReader reader = new SignatureReader(signature);
reader.acceptType(builder);
return builder.getResult();
}
/*package*/ static class TypeBuilderVisitor extends SignatureVisitorAdapter {
private ASMType myResult;
private Stack<ASMType> myTypes = new Stack<ASMType>();
private char myWildcard;
private TypeUtil.TypeBuilderVisitor myArrayVisitor = null;
public TypeBuilderVisitor() {
}
protected void setResult(ASMType type) {
myResult = type;
}
protected void addPart(ASMType type) {
if (myTypes.isEmpty()) {
myTypes.add(type);
return;
}
if (myTypes.peek() instanceof ASMClassType) {
ASMClassType ct = (ASMClassType) myTypes.pop();
ASMParameterizedType replacement = new ASMParameterizedType(ct, new ArrayList<ASMType>());
if (!(myTypes.isEmpty())) {
ASMParameterizedType parent = (ASMParameterizedType) unwrap(myTypes.peek());
parent.removeArgument(ct);
parent.addArgument(replacement);
}
myTypes.push(replacement);
} else if (myTypes.peek() instanceof ASMBoundedType) {
ASMBoundedType bounded = (ASMBoundedType) myTypes.peek();
ASMType bound = bounded.getBound();
ASMType wrapped = wrap(type);
if (bound instanceof ASMParameterizedType) {
((ASMParameterizedType) bound).addArgument(wrapped);
} else {
ASMParameterizedType newBound = new ASMParameterizedType(bound, new ArrayList<ASMType>());
newBound.addArgument(wrapped);
bounded.setBound(newBound);
}
}
ASMType wrapped = wrap(type);
if (myTypes.peek() instanceof ASMParameterizedType) {
((ASMParameterizedType) myTypes.peek()).addArgument(wrapped);
}
if (type instanceof ASMClassType) {
myTypes.push(wrapped);
}
}
private void finish() {
if (myTypes.size() == 1) {
setResult(myTypes.peek());
}
if (!(myTypes.isEmpty())) {
myTypes.pop();
}
}
private ASMType wrap(ASMType type) {
if (myWildcard == '+') {
myWildcard = '=';
return new ASMExtendsType(type);
}
if (myWildcard == '-') {
myWildcard = '=';
return new ASMSuperType(type);
}
return type;
}
private ASMType unwrap(ASMType type) {
if (type instanceof ASMBoundedType) {
return ((ASMBoundedType) type).getBound();
} else {
return type;
}
}
@Override
public void visitTypeArgument() {
addPart(new ASMUnboundedType());
}
@Override
public SignatureVisitor visitTypeArgument(char wildcard) {
myWildcard = wildcard;
return this;
}
@Override
public void visitBaseType(char descriptor) {
addPart(TypeUtil.fromType(Type.getType("" + descriptor)));
}
@Override
public void visitTypeVariable(String name) {
addPart(new ASMTypeVariable(name));
}
@Override
public SignatureVisitor visitArrayType() {
return myArrayVisitor = new TypeUtil.TypeBuilderVisitor();
}
@Override
public void visitClassType(String name) {
addPart(new ASMClassType(name.replace('/', '.')));
}
@Override
public void visitEnd() {
if (myArrayVisitor != null) {
addPart(new ASMArrayType(myArrayVisitor.getResult()));
myArrayVisitor = null;
} else {
finish();
}
}
/*package*/ ASMType getResult() {
if (myArrayVisitor != null) {
addPart(new ASMArrayType(myArrayVisitor.getResult()));
myArrayVisitor = null;
}
if (myResult == null) {
finish();
}
return myResult;
}
}
}