/*
* Copyright 2013 Guidewire Software, Inc.
*/
package gw.internal.gosu.ir.nodes;
import gw.internal.gosu.compiler.GosuClassLoader;
import gw.internal.gosu.parser.IGosuClassInternal;
import gw.lang.ir.IRType;
import gw.lang.reflect.IType;
import gw.lang.reflect.gs.IGosuArrayClass;
import gw.lang.reflect.gs.IGosuClass;
import gw.lang.reflect.java.IJavaType;
import gw.util.GosuClassUtil;
import java.lang.reflect.Array;
public class GosuClassIRType implements IRType {
private IType _type;
private Boolean _structural;
public static GosuClassIRType get(IType type) {
if (!(type instanceof IGosuClassInternal || type instanceof IGosuArrayClass)) {
throw new IllegalArgumentException("Cannot create a GosuClassIRType from a type of type " + type.getClass());
}
return new GosuClassIRType(type);
}
private GosuClassIRType(IType type) {
_type = type;
}
public IType getType() {
return _type;
}
@Override
public String getName() {
return _type.getName();
}
@Override
public String getRelativeName() {
return _type.getRelativeName();
}
@Override
public String getDescriptor() {
if (isArray()) {
return '[' + getComponentType().getDescriptor();
} else {
return 'L' + getSlashName( ) + ';';
}
}
@Override
public boolean isStructural() {
return _structural == null
? _structural = (_type instanceof IGosuClass && ((IGosuClass)_type).isStructure())
: _structural;
}
@Override
public boolean isStructuralAndErased( IRType ownersType ) {
return isStructural() && ownersType instanceof GosuClassIRType;
}
@Override
public Class getJavaClass() {
if ( isArray() ) {
return Array.newInstance(getComponentType().getJavaClass(), 0).getClass();
} else {
try
{
return GosuClassLoader.instance().loadClass( _type.getName() );
}
catch( ClassNotFoundException e )
{
throw new RuntimeException( e );
}
}
}
@Override
public String getSlashName() {
if( isArray() ) {
return getComponentType().getSlashName() + "[]";
}
IType outerType = _type.getEnclosingType();
if( outerType != null )
{
return IRTypeFactory.get( outerType).getSlashName( ) + "$" + GosuClassUtil.getNameNoPackage( _type.getName() );
}
IType type = _type;
IJavaType jtype = ((IGosuClassInternal)_type).getJavaType();
if( jtype != null && !jtype.getBackingClassInfo().isAnnotation() )
{
// The Gosu type here is a proxy to a java class; use the java class
type = jtype;
}
return type.getName().replace( '.', '/' );
}
@Override
public IRType getArrayType() {
return IRTypeFactory.get(_type.getArrayType());
}
@Override
public IRType getComponentType() {
return IRTypeFactory.get(_type.getComponentType());
}
@Override
public boolean isArray() {
return _type.isArray();
}
@Override
public boolean equals(Object obj) {
return obj instanceof GosuClassIRType && _type.equals(((GosuClassIRType) obj)._type);
}
@Override
public boolean isAssignableFrom(IRType otherType) {
if (isArray() && otherType.isArray()) {
return getComponentType().isAssignableFrom( otherType.getComponentType() );
} else if (isArray() || otherType.isArray()) {
return false;
}
if (otherType instanceof GosuClassIRType) {
return _type.isAssignableFrom(((GosuClassIRType) otherType)._type);
} else {
return false;
}
}
@Override
public boolean isByte() {
return false;
}
@Override
public boolean isBoolean() {
return false;
}
@Override
public boolean isShort() {
return false;
}
@Override
public boolean isChar() {
return false;
}
@Override
public boolean isInt() {
return false;
}
@Override
public boolean isLong() {
return false;
}
@Override
public boolean isFloat() {
return false;
}
@Override
public boolean isDouble() {
return false;
}
@Override
public boolean isVoid() {
return false;
}
@Override
public boolean isPrimitive() {
return false;
}
@Override
public boolean isInterface() {
return _type.isInterface();
}
@Override
public String toString()
{
return getName();
}
}