package gw.internal.gosu.dynamic;
import gw.lang.reflect.BaseTypeInfo;
import gw.lang.reflect.IConstructorInfo;
import gw.lang.reflect.IExpando;
import gw.lang.reflect.IMethodInfo;
import gw.lang.reflect.IPropertyInfo;
import gw.lang.reflect.IType;
import gw.lang.reflect.TypeSystem;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
*/
public class DynamicTypeInfo extends BaseTypeInfo
{
private Map<CharSequence, IPropertyInfo> _piCache;
private List<DynamicConstructorInfo> _dci;
public DynamicTypeInfo( IType type )
{
super( type );
_piCache = new HashMap<CharSequence, IPropertyInfo>();
_dci = Arrays.asList(
new DynamicConstructorInfo( this ),
new DynamicConstructorInfo( this, TypeSystem.get( IExpando.class ) ) );
}
@Override
public List<? extends IConstructorInfo> getConstructors() {
return _dci;
}
@Override
public IConstructorInfo getConstructor( IType... params ) {
if( params == null || params.length == 0 ) {
return _dci.get( 0 );
}
else if( params.length == 1 && TypeSystem.get( IExpando.class ) == params[0] ) {
return _dci.get( 1 );
}
return null;
}
@Override
public IConstructorInfo getCallableConstructor( IType... params ) {
if( params == null || params.length == 0 ) {
return _dci.get( 0 );
}
else if( params.length == 1 && TypeSystem.get( IExpando.class ).isAssignableFrom( params[0] ) ) {
return _dci.get( 1 );
}
return null;
}
@Override
public IPropertyInfo getProperty( CharSequence propName )
{
IPropertyInfo pi = _piCache.get( propName );
if( pi == null )
{
TypeSystem.lock();
try
{
pi = _piCache.get( propName );
if( pi == null )
{
pi = new DynamicPropertyInfo( this, propName.toString() );
_piCache.put( propName, pi );
}
}
finally
{
TypeSystem.unlock();
}
}
return pi;
}
@Override
public IMethodInfo getMethod( CharSequence methodName, IType... params )
{
// Probably should cache these, but doing so could be more expensive e.g., the lookup involves param types
return new DynamicMethodInfo( this, methodName.toString(), params );
}
@Override
public IMethodInfo getCallableMethod( CharSequence method, IType... params )
{
return new DynamicMethodInfo( this, method.toString(), params );
}
}