/*
* Copyright 2013 Guidewire Software, Inc.
*/
package gw.internal.gosu.parser.expressions;
import gw.internal.gosu.parser.Expression;
import gw.internal.gosu.parser.GenericTypeVariable;
import gw.internal.gosu.parser.TypeVariableType;
import gw.lang.parser.expressions.ITypeVariableDefinition;
import gw.lang.parser.expressions.ITypeVariableDefinitionExpression;
import gw.lang.reflect.IType;
import gw.lang.reflect.gs.IGenericTypeVariable;
import gw.lang.reflect.java.JavaTypes;
import java.util.List;
/**
*/
public class TypeVariableDefinition extends Expression implements ITypeVariableDefinition, ITypeVariableDefinitionExpression
{
//!! Note we delegate the ITypeVariableDefinition impl so we can separate it from the Expression
// i.e., we don't want the memory attached to the Expression to hang around in the TypeVariableType
TypeVariableDefinitionImpl _typeVarDef;
public TypeVariableDefinition( IType enclosingType, boolean forFunction )
{
_typeVarDef = new TypeVariableDefinitionImpl();
_typeVarDef._enclosingType = enclosingType;
_type = new TypeVariableType( _typeVarDef, forFunction );
_typeVarDef._type = (TypeVariableType)_type;
}
// This ctor is useful only when coming from a generic JavaType
public TypeVariableDefinition( IType enclosingType, IGenericTypeVariable typeVar )
{
_typeVarDef = new TypeVariableDefinitionImpl();
_typeVarDef._typeVar = (GenericTypeVariable)typeVar;
_type = new TypeVariableType( _typeVarDef, false );
_typeVarDef._enclosingType = enclosingType;
_typeVarDef._strName = typeVar.getName();
_typeVarDef._boundingType = typeVar.getBoundingType();
_typeVarDef._type = (TypeVariableType)_type;
}
// Copy constructor used for cloning
private TypeVariableDefinition(TypeVariableDefinitionImpl typeVarDef, boolean isFunctionStatement) {
_typeVarDef = typeVarDef;
_type = new TypeVariableType( _typeVarDef, isFunctionStatement );
}
@Override
public TypeVariableType getType()
{
return (TypeVariableType) super.getType();
}
@Override
public TypeVariableType getTypeImpl()
{
return _typeVarDef.getType();
}
public void setType( IType type )
{
super.setType( type );
_typeVarDef._type = (TypeVariableType)type;
}
public IType getEnclosingType()
{
return _typeVarDef.getEnclosingType();
}
public void setEnclosingType( IType enclosingType )
{
_typeVarDef.setEnclosingType( enclosingType );
}
public String getName()
{
return _typeVarDef.getName();
}
public void setName( String strName )
{
_typeVarDef.setName( strName );
}
public GenericTypeVariable getTypeVar()
{
return _typeVarDef.getTypeVar();
}
public Object evaluate()
{
return null;
}
@Override
public boolean equals( Object o )
{
if( this == o )
{
return true;
}
// Note the interface, not the class...
if( !(o instanceof ITypeVariableDefinition) )
{
return false;
}
TypeVariableDefinitionImpl thatTypeVarDef = o instanceof TypeVariableDefinition ? ((TypeVariableDefinition)o)._typeVarDef : (TypeVariableDefinitionImpl)o;
return !(_typeVarDef != null ? !_typeVarDef.equals( thatTypeVarDef ) : thatTypeVarDef != null);
}
@Override
public int hashCode()
{
return _typeVarDef != null ? _typeVarDef.hashCode() : 0;
}
@Override
public String toString()
{
return _typeVarDef.toString();
}
public static IGenericTypeVariable[] getTypeVars( List<ITypeVariableDefinitionExpression> typeVarDefs )
{
if( typeVarDefs.isEmpty() )
{
return GenericTypeVariable.EMPTY_TYPEVARS;
}
IGenericTypeVariable[] typeVars = new IGenericTypeVariable[typeVarDefs.size()];
for( int i = 0; i < typeVarDefs.size(); i++ )
{
ITypeVariableDefinition typeVarDef = (ITypeVariableDefinition)typeVarDefs.get( i );
typeVars[i] = typeVarDef.getTypeVar();
}
return typeVars;
}
@Override
public int getNameOffset( String identifierName )
{
return getLocation().getOffset();
}
@Override
public void setNameOffset( int iOffset, String identifierName )
{
throw new UnsupportedOperationException();
}
public boolean declares( String identifierName )
{
return getType().getName().equals( identifierName );
}
public String[] getDeclarations() {
return new String[] {getType().getName()};
}
@Override
public ITypeVariableDefinition clone() {
return new TypeVariableDefinition(_typeVarDef.clone(), ((TypeVariableType) _type).isFunctionStatement());
}
public IType getBoundingType()
{
return _typeVarDef._boundingType;
}
public void setBoundingType( IType type )
{
_typeVarDef._boundingType = type;
if( _typeVarDef._typeVar != null )
{
_typeVarDef._typeVar = new GenericTypeVariable( _typeVarDef, type == null
? JavaTypes.OBJECT()
: type );
}
}
public ITypeVariableDefinition getTypeVarDef() {
return _typeVarDef;
}
public void setTypeVarDef( TypeVariableDefinitionImpl typeVarDef )
{
_typeVarDef = typeVarDef;
}
}