/*
* Copyright 2013 Guidewire Software, Inc.
*/
package gw.lang.reflect;
import gw.internal.gosu.parser.StringCache;
import gw.lang.parser.GosuParserTypes;
import gw.lang.parser.IExpression;
import gw.lang.parser.StandardCoercionManager;
import gw.lang.reflect.gs.IGosuClass;
import gw.lang.reflect.java.JavaTypes;
import gw.lang.reflect.gs.IGenericTypeVariable;
import gw.lang.parser.IScriptPartId;
import gw.lang.reflect.java.IJavaClassInfo;
import gw.lang.parser.IBlockClass;
import gw.lang.parser.ScriptPartId;
import gw.lang.parser.TypeVarToTypeMap;
import gw.util.Pair;
import gw.util.concurrent.LockingLazyVar;
import java.io.ObjectStreamException;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
public class FunctionType extends AbstractType implements IFunctionType, IGenericMethodInfo
{
public static final ThreadLocal<IFunctionType> CURRENT = new ThreadLocal<IFunctionType>();
private static final IGenericTypeVariable[] EMPTY_TYPE_VARS = new IGenericTypeVariable[0];
private static final IType[] EMPTY_ARGS = new IType[0];
private IType _retType;
private volatile IType[] _paramTypes;
private IMethodInfo _mi;
private String _strFunctionName;
private IScriptPartId _scriptPart;
private IGosuClass _owningParameterizedType;
private volatile IGenericTypeVariable[] _typeVars;
private int _iModifiers;
transient private FunctionTypeInfo _typeInfo;
transient protected Set<IType> _allTypesInHierarchy;
transient private String _signature;
volatile transient private Map<String, ParameterizedFunctionType> _parameterizationByParamsName;
private LockingLazyVar<FunctionArrayType> _arrType =
new LockingLazyVar<FunctionArrayType>()
{
@Override
protected FunctionArrayType init()
{
return new FunctionArrayType( FunctionType.this, getFunctionClass(), getTypeLoader() );
}
};
/**
* Construct a FunctionType with the specified return type and parameter types array.
*
* @param strFunctionName The name of the function
* @param retType The return type of the function.
* @param paramTypes The parameter types. Can be null if no params.
*/
public FunctionType( String strFunctionName, IType retType, IType[] paramTypes )
{
_retType = retType;
if (_retType == null) {
_retType = JavaTypes.pVOID();
}
_paramTypes = paramTypes == null || paramTypes.length == 0 ? EMPTY_ARGS : paramTypes;
setName(strFunctionName);
_mi = null;
_allTypesInHierarchy = Collections.<IType>singleton( this );
_typeVars = EMPTY_TYPE_VARS;
}
/**
* Construct a generic FunctionType with the specified return type, parameter
* types, and generic type variables.
*
* @param strFunctionName The name of the function
* @param retType The return type of the function.
* @param paramTypes The parameter types. Can be null if no params.
* @param typeVars The generic type variables. If null, does not create a
* generic function type.
*/
public FunctionType( String strFunctionName, IType retType, IType[] paramTypes, IGenericTypeVariable[] typeVars )
{
this( strFunctionName, retType, paramTypes );
if( typeVars != null )
{
_typeVars = typeVars;
for( IGenericTypeVariable gtv : typeVars )
{
gtv.getTypeVariableDefinition().setEnclosingType( this );
}
}
}
public FunctionType( IMethodInfo mi )
{
this(mi, false);
}
public FunctionType( IMethodInfo mi, boolean lazyTypes )
{
_mi = mi;
if (!lazyTypes) {
initLazyMethodInfoState();
}
setName(mi.getDisplayName());
_allTypesInHierarchy = Collections.<IType>singleton( this );
}
private void setName(String name) {
_strFunctionName = StringCache.get( name );
}
private void initLazyMethodInfoState()
{
TypeSystem.lock();
try
{
if( _paramTypes == null )
{
IParameterInfo[] pd = _mi.getParameters();
int iArgs = pd.length;
_paramTypes = new IType[iArgs];
for( int i = 0; i < iArgs; i++ )
{
_paramTypes[i] = pd[i].getFeatureType();
}
if( _paramTypes.length == 0 )
{
_paramTypes = EMPTY_ARGS;
}
_typeVars = EMPTY_TYPE_VARS;
if( _mi instanceof IGenericMethodInfo)
{
_typeVars = ((IGenericMethodInfo)_mi).getTypeVariables();
}
clearParamSignature();
}
_retType = _mi.getReturnType();
if( _retType == null )
{
_retType = JavaTypes.pVOID();
}
}
finally
{
TypeSystem.unlock();
}
}
public FunctionType( FunctionType source, IGosuClass gsClass )
{
if( gsClass.isParameterizedType() )
{
_owningParameterizedType = gsClass;
TypeVarToTypeMap actualParamByVarName = TypeSystem.mapTypeByVarName( gsClass, gsClass, true );
IGenericTypeVariable[] tvs = source.getTypeVariables();
if( tvs != null )
{
for( IGenericTypeVariable tv : tvs )
{
if( actualParamByVarName.isEmpty() )
{
actualParamByVarName = new TypeVarToTypeMap();
}
actualParamByVarName.put( tv.getTypeVariableDefinition().getType(), tv.getTypeVariableDefinition().getType() );
}
}
assignReturnTypeFromTypeParams( source, actualParamByVarName, true );
assignParamTypesFromTypeParams( source, actualParamByVarName, true );
}
else
{
_retType = source.getReturnType();
if (_retType == null) {
_retType = JavaTypes.pVOID();
}
_paramTypes = source._paramTypes;
//clearParamSignature(); TODO - reenable if you dare
}
copyFields( source );
}
protected FunctionType(FunctionType source, IType returnType, IType[] paramTypes) {
_retType = returnType;
_paramTypes = paramTypes;
copyFields( source );
}
protected FunctionType( FunctionType source, TypeVarToTypeMap actualParamByVarName, boolean bKeepTypeVars )
{
assignReturnTypeFromTypeParams( source, actualParamByVarName, bKeepTypeVars );
assignParamTypesFromTypeParams( source, actualParamByVarName, bKeepTypeVars );
copyFields( source );
clearParamSignature();
}
protected void copyFields( FunctionType source )
{
_mi = source._mi;
_strFunctionName = source._strFunctionName;
_scriptPart = source._scriptPart;
_typeVars = source.getGenericTypeVariables();
_typeInfo = source._typeInfo;
_allTypesInHierarchy = source._allTypesInHierarchy;
_signature = source._signature;
_parameterizationByParamsName = source._parameterizationByParamsName;
}
/**
* Create a new FunctionType based on the type parameters assigned to the type
* vars in actualParamByVarName.
* <p>
* It is important to note that this form of parameterization is different
* from calling getParameterizedType(). The latter creates a parameterization
* of a generic function e.g., function foo<T>() where T is a type var
* on the function.
* <p>
* This here method is for parameterizing a function type that has references
* to external type vars e.g., class Fred<T> { function foo( t : T ){} }
* where T is a type var on the containing class.
*
* @param source The raw form of a FunctionType having possible references to
* type vars defined in its containing class.
* @param actualParamByVarName A map of concrete types by type var name
* e.g., "T" -> String
* @param bKeepTypeVars Indicates whether or not a type var referenced in the
* source FunctionType that cannot be resolved via the actualParamByVarName
* map should remain as a TypeVariableType or should be converted to its
* bounding type.
* @return A parameterized version of the source FunctionType
*/
public FunctionType parameterize( FunctionType source, TypeVarToTypeMap actualParamByVarName, boolean bKeepTypeVars )
{
return new FunctionType( source, actualParamByVarName, bKeepTypeVars );
}
private void assignParamTypesFromTypeParams( FunctionType source, TypeVarToTypeMap actualParamByVarName, boolean bKeepTypeVars )
{
IType[] genParamTypes = source.getParameterTypes();
if( genParamTypes != null )
{
_paramTypes = new IType[genParamTypes.length];
for( int j = 0; j < genParamTypes.length; j++ )
{
_paramTypes[j] = TypeSystem.getActualType( genParamTypes[j], actualParamByVarName, bKeepTypeVars );
if( _paramTypes[j] == null )
{
_paramTypes[j] = genParamTypes[j];
}
}
if (_paramTypes.length == 0) {
_paramTypes = EMPTY_ARGS;
}
clearParamSignature();
}
}
private void assignReturnTypeFromTypeParams( FunctionType source, TypeVarToTypeMap actualParamByVarName, boolean bKeepTypeVars )
{
_retType = TypeSystem.getActualType( source.getReturnType(), actualParamByVarName, bKeepTypeVars );
if( _retType == null )
{
_retType = source.getReturnType();
}
if (_retType == null) {
_retType = JavaTypes.pVOID();
}
}
/**
* @return The instrinic type of this FunctionType's return type.
*/
public IType getIntrinsicType()
{
return getReturnType();
}
public IType getReturnType()
{
if (_retType == null) {
initLazyMethodInfoState();
}
return _retType;
}
public void setRetType( IType retType )
{
_retType = retType == null ? JavaTypes.pVOID() : retType;
}
public IType[] getParameterTypes()
{
if (_paramTypes == null) {
initLazyMethodInfoState();
}
return _paramTypes;
}
public void setArgumentTypes( IType[] paramTypes )
{
_paramTypes = paramTypes == null || paramTypes.length == 0 ? EMPTY_ARGS : paramTypes;
clearParamSignature();
}
public IMethodInfo getMethodInfo()
{
if( _mi == null )
{
if( getScriptPart() != null )
{
IType type = getScriptPart().getContainingType();
if( type instanceof IGosuClass )
{
IGosuClass gsClass = (IGosuClass)type;
_mi = gsClass.getTypeInfo().getMethod( type, getName(), getParameterTypes() );
} else if (type != null) {
_mi = type.getTypeInfo().getMethod(getName(), getParameterTypes());
}
}
}
return _mi;
}
public IFeatureInfo getMethodOrConstructorInfo()
{
IMethodInfo mi = getMethodInfo();
if( mi == null )
{
if( getScriptPart() != null )
{
IType type = getScriptPart().getContainingType();
if( type instanceof IGosuClass && type.getRelativeName().equals( getName() ) )
{
IGosuClass gsClass = (IGosuClass)type;
return gsClass.getTypeInfo().getConstructor( type, getParameterTypes() );
}
}
}
return mi;
}
private void clearParamSignature()
{
_signature = null;
}
public String getParamSignature()
{
if( _signature == null )
{
IType[] paramTypes = getParameterTypes();
if( paramTypes.length == 0 )
{
return _signature = _strFunctionName + "()";
}
String strParams = _strFunctionName + "(";
for( int i = 0; i < paramTypes.length; i++ )
{
strParams += (i == 0 ? "" : ", " ) + (paramTypes[i] == null ? "" : paramTypes[i].getName());
}
strParams += ")";
_signature = strParams;
}
return _signature;
}
public String getParamSignatureForCurrentModule() {
String sig;
IType[] paramTypes = getParameterTypes();
if( paramTypes.length == 0 )
{
sig = (String)(_strFunctionName + "()");
}
else
{
String strParams = _strFunctionName + "(";
for( int i = 0; i < paramTypes.length; i++ )
{
strParams += (i == 0 ? "" : ", " ) + (paramTypes[i] == null ? "" : getParamTypeNameFromJavaBackedType(paramTypes[i]));
}
strParams += ")";
sig = (String)strParams;
}
return sig;
}
public static String getParamTypeNameFromJavaBackedType(IType paramType) {
return TypeSystem.getTypeFromJavaBackedType(paramType).getName();
}
public String getName()
{
return _strFunctionName;
}
public String getDisplayName()
{
return getName();
}
public String getRelativeName()
{
return getName();
}
public String getNamespace()
{
IType enclosingType = getEnclosingType();
return enclosingType != null
? enclosingType.getName()
: null;
}
public ITypeLoader getTypeLoader()
{
return null;
}
public boolean isInterface()
{
return false;
}
public IType[] getInterfaces()
{
return EMPTY_TYPE_ARRAY;
}
public boolean isEnum()
{
return false;
}
public IType getSupertype()
{
return null;
}
public IType getEnclosingType()
{
if( _scriptPart instanceof IType)
{
return (IType)_scriptPart;
}
final IMethodInfo methodInfo = getMethodInfo();
if( methodInfo != null )
{
return methodInfo.getOwnersType();
}
return null;
}
public IType getGenericType()
{
return isGenericType() ? this : null;
}
public boolean isFinal()
{
return false;
}
public boolean isParameterizedType()
{
return false;
}
public boolean isGenericType()
{
return getGenericTypeVariables().length > 0;
}
public IGenericTypeVariable[] getGenericTypeVariables()
{
if (_typeVars == null) {
initLazyMethodInfoState();
}
return _typeVars;
}
public ParameterizedFunctionType getParameterizedType( IType... typeParams )
{
if( typeParams == null || typeParams.length == 0 )
{
throw new IllegalArgumentException( "Parameter types required." );
}
if( _parameterizationByParamsName == null )
{
TypeSystem.lock();
try
{
if( _parameterizationByParamsName == null )
{
_parameterizationByParamsName = new ConcurrentHashMap<String, ParameterizedFunctionType>( 2 );
}
}
finally
{
TypeSystem.unlock();
}
}
String strNameOfParams = TypeSystem.getNameOfParams( typeParams, false, true );
ParameterizedFunctionType parameterizedType = _parameterizationByParamsName.get( strNameOfParams );
if( parameterizedType == null )
{
TypeSystem.lock();
try
{
parameterizedType = _parameterizationByParamsName.get( strNameOfParams );
if( parameterizedType == null )
{
parameterizedType = new ParameterizedFunctionType( this, typeParams );
_parameterizationByParamsName.put( strNameOfParams, parameterizedType );
}
}
finally
{
TypeSystem.unlock();
}
}
return parameterizedType;
}
public IFunctionType inferParameterizedTypeFromArgTypesAndContextType(IType[] argTypes, IType ctxType)
{
TypeVarToTypeMap map = TypeVarToTypeMap.EMPTY_MAP;
if( argTypes.length > 0 )
{
if( getMethodInfo() == null )
{
map = inferTypeParametersFromArgumentTypes( argTypes );
}
else
{
map = ((IGenericMethodInfo)getMethodInfo()).inferTypeParametersFromArgumentTypes2( _owningParameterizedType, argTypes );
}
}
IGenericTypeVariable[] typeVars = getGenericTypeVariables();
if( typeVars.length == 0 )
{
return this;
}
IType[] typeParams = new IType[typeVars.length];
for( int i = 0; i < typeVars.length; i++ )
{
IType inferredType = map.get( typeVars[i].getTypeVariableDefinition().getType() );
if( inferredType == null && ctxType != null )
{
//try to infer type from context type
TypeVarToTypeMap returnTypeVars = new TypeVarToTypeMap();
TypeSystem.inferTypeVariableTypesFromGenParamTypeAndConcreteType( getReturnType(), ctxType, returnTypeVars );
inferredType = returnTypeVars.get( typeVars[i].getTypeVariableDefinition().getType() );
}
typeParams[i] = inferredType;
if( typeParams[i] == null )
{
return this;
}
}
return getParameterizedType( typeParams );
}
public IType[] getTypeParameters()
{
return null;
}
public Set<IType> getAllTypesInHierarchy()
{
return _allTypesInHierarchy;
}
public boolean isArray()
{
return false;
}
public boolean isPrimitive()
{
return false;
}
public IType getArrayType()
{
return _arrType.get();
}
public Object makeArrayInstance( int iLength )
{
return TypeSystem.get( getFunctionClass() ).makeArrayInstance( iLength );
}
private IJavaClassInfo getFunctionClass()
{
return TypeSystem.getGosuClassLoader().getFunctionClassForArity( getParameterTypes().length ).getBackingClassInfo();
}
public Object getArrayComponent( Object array, int iIndex ) throws IllegalArgumentException, ArrayIndexOutOfBoundsException
{
return TypeSystem.get( getFunctionClass() ).getArrayComponent( array, iIndex );
}
public void setArrayComponent( Object array, int iIndex, Object value ) throws IllegalArgumentException, ArrayIndexOutOfBoundsException
{
TypeSystem.get( getFunctionClass() ).setArrayComponent( array, iIndex, value );
}
public int getArrayLength( Object array ) throws IllegalArgumentException
{
return TypeSystem.get( getFunctionClass() ).getArrayLength( array );
}
public IType getComponentType()
{
return null;
}
public boolean isAssignableFrom( IType type )
{
if( this == type )
{
return true;
}
if( type instanceof IBlockClass )
{
return isAssignableFrom( ((IBlockClass)type).getBlockType() );
}
if( type instanceof FunctionType )
{
FunctionType otherType = (FunctionType)type;
//contravariant arg types
if( areParamsCompatible( this, otherType ) )
{
//covariant return types
return getReturnType().isAssignableFrom( otherType.getReturnType() ) ||
StandardCoercionManager.arePrimitiveTypesAssignable( getReturnType(), otherType.getReturnType() ) ||
getReturnType() == GosuParserTypes.NULL_TYPE();
}
}
return false;
}
public boolean areParamsCompatible(IFunctionType rhsFunctionType) {
return areParamsCompatible(this, rhsFunctionType);
}
public static boolean areParamsCompatible( IFunctionType lhsType, IFunctionType rhsType )
{
IType[] lhsParams = lhsType.getParameterTypes();
IType[] rhsParams = rhsType.getParameterTypes();
if( lhsParams.length != rhsParams.length )
{
return false;
}
for( int i = 0; i < rhsParams.length; i++ )
{
IType myParamType = lhsParams[i];
IType otherParamType = rhsParams[i]; //## todo: this is a hack; we need to tighten this up
if( !StandardCoercionManager.arePrimitiveTypesAssignable( otherParamType, myParamType ) ) {
if( !(otherParamType.isAssignableFrom( myParamType ) || myParamType instanceof ITypeVariableType) )
{
return false;
}
}
}
return true;
}
public boolean isMutable()
{
return false;
}
public ITypeInfo getTypeInfo()
{
return _typeInfo == null ? _typeInfo = new FunctionTypeInfo( this ) : _typeInfo;
}
public void unloadTypeInfo()
{
_typeInfo = null;
}
public Object readResolve() throws ObjectStreamException
{
return this;
}
public boolean isValid()
{
return true;
}
public int getModifiers()
{
if( _iModifiers == 0 )
{
return _mi != null ? Modifier.getModifiersFrom( _mi ) : Modifier.PUBLIC;
}
return _iModifiers;
}
public void setModifiers( int iModifiers )
{
_iModifiers = iModifiers;
}
public boolean isAbstract()
{
return false;
}
public IScriptPartId getScriptPart()
{
return _scriptPart;
}
@Override
public IType newInstance( IType[] paramTypes, IType returnType )
{
FunctionType functionType = new FunctionType(this._strFunctionName, returnType, paramTypes, cloneTypeVars() );
if (getScriptPart() == null && _mi != null) {
if (_mi instanceof MethodInfoDelegate) {
functionType.setScriptPart(new ScriptPartId(((MethodInfoDelegate)_mi).getSource().getOwnersType(), null));
} else {
functionType.setScriptPart(new ScriptPartId(_mi.getOwnersType(), null));
}
} else {
functionType.setScriptPart(getScriptPart());
}
return functionType;
}
@Override
public Pair<Long, String> getRetainedMemory() {
return null;
}
private IGenericTypeVariable[] cloneTypeVars() {
IGenericTypeVariable[] typeVars = new IGenericTypeVariable[_typeVars.length];
for (int i = 0; i < typeVars.length; i++) {
typeVars[i] = _typeVars[i].clone();
}
return typeVars;
}
public void setScriptPart( IScriptPartId scriptPart )
{
_scriptPart = scriptPart;
}
public boolean equals( Object o )
{
if( this == o )
{
return true;
}
if( !getClass().isInstance( o ) )
{
return false;
}
final FunctionType funcType = (FunctionType)o;
// Name
if( !funcType.getDisplayName().equals( getDisplayName() ) &&
!(o instanceof IBlockType) &&
!(this instanceof IBlockType))
{
return false;
}
// Enclosing Type
if( !areEnclosingTypesEqual( funcType ) )
{
return false;
}
// Parameter Types
if( funcType.getParameterTypes().length != getParameterTypes().length )
{
return false;
}
for( int i = 0; i < getParameterTypes().length; i++ )
{
if( !areSameTypes( getParameterTypes()[i], funcType.getParameterTypes()[i] ) )
{
return false;
}
}
// Return Type
return areSameTypes( getReturnType(), funcType.getReturnType() );
}
protected boolean areEnclosingTypesEqual( FunctionType funcType )
{
if( areSameTypes( getEnclosingType(), funcType.getEnclosingType() ) )
{
return true;
}
// crappy fix for when block types are compared as parameter types for methodinfo lookup
return getEnclosingType() == null || funcType.getEnclosingType() == null;
}
private boolean areSameTypes( IType t1, IType t2 )
{
return t1 instanceof INonLoadableType
? t1.equals( t2 )
: t1 == t2;
}
public int hashCode()
{
int result = getDisplayName().hashCode();
for( int i = 0; i < getParameterTypes().length; i++ )
{
if( getParameterTypes()[i] instanceof INonLoadableType )
{
result = 31 * result + getParameterTypes()[i].hashCode();
}
else
{
result = 31 * result + getParameterTypes()[i].getName().hashCode();
}
}
if( getReturnType() instanceof INonLoadableType )
{
result = 31 * result + getReturnType().hashCode();
}
else
{
result = 31 * result + getReturnType().getName().hashCode();
}
return result;
}
public String toString()
{
return getParamSignature().toString() + ":" + getReturnType().getName();
}
public TypeVarToTypeMap inferTypeParametersFromArgumentTypes2( IGosuClass owningParameterizedType, IType... argTypes )
{
return inferTypeParametersFromArgumentTypes( argTypes );
}
public TypeVarToTypeMap inferTypeParametersFromArgumentTypes( IType... argTypes )
{
IType[] genParamTypes = getParameterTypes();
TypeVarToTypeMap map = new TypeVarToTypeMap();
for( int i = 0; i < argTypes.length; i++ )
{
if( genParamTypes.length > i )
{
TypeSystem.inferTypeVariableTypesFromGenParamTypeAndConcreteType( genParamTypes[i], argTypes[i], map );
}
}
return map;
}
public IGenericTypeVariable[] getTypeVariables()
{
return getGenericTypeVariables();
}
public IType getParameterizedReturnType( IType... typeParams )
{
TypeVarToTypeMap actualParamByVarName = new TypeVarToTypeMap();
int i = 0;
for( IGenericTypeVariable tv : getTypeVariables() )
{
actualParamByVarName.put( tv.getTypeVariableDefinition().getType(), typeParams[i++] );
}
return TypeSystem.getActualType( getReturnType(), actualParamByVarName, false );
}
public IType[] getParameterizedParameterTypes( IType... typeParams )
{
return getParameterizedParameterTypes2( null, typeParams );
}
public IType[] getParameterizedParameterTypes2( IGosuClass ownersType, IType... typeParams )
{
TypeVarToTypeMap actualParamByVarName = new TypeVarToTypeMap();
int i = 0;
for( IGenericTypeVariable tv : getTypeVariables() )
{
actualParamByVarName.put( tv.getTypeVariableDefinition().getType(), typeParams[i++] );
}
IType[] genParamTypes = getParameterTypes();
IType[] paramTypes = new IType[genParamTypes.length];
for( int j = 0; j < genParamTypes.length; j++ )
{
paramTypes[j] = TypeSystem.getActualType( genParamTypes[j], actualParamByVarName, false );
}
return paramTypes;
}
public IType getRuntimeType()
{
TypeVarToTypeMap actualParamByVarName = new TypeVarToTypeMap();
actualParamByVarName = mapTypes( actualParamByVarName, getParameterTypes() );
actualParamByVarName = mapTypes( actualParamByVarName, getReturnType() );
return actualParamByVarName.size() != 0
? parameterize( this, actualParamByVarName, false )
: this;
}
//Move Intrinsic type helper up here
private TypeVarToTypeMap mapTypes( TypeVarToTypeMap actualParamByVarName, IType... types )
{
for( int i = 0; i < types.length; i++ )
{
IType type = types[i];
if( type instanceof ITypeVariableType )
{
actualParamByVarName.put( (ITypeVariableType)types[i], types[i] );
}
if( type instanceof ITypeVariableArrayType )
{
mapTypes( actualParamByVarName, type.getComponentType() );
}
if( type.isParameterizedType() )
{
IType[] parameters = type.getTypeParameters();
mapTypes( actualParamByVarName, parameters );
}
if( type instanceof IFunctionType )
{
IFunctionType funType = (IFunctionType)type;
mapTypes( actualParamByVarName, funType.getReturnType() );
IType[] paramTypes = funType.getParameterTypes();
for( IType paramType : paramTypes )
{
mapTypes( actualParamByVarName, paramType );
}
}
}
return actualParamByVarName;
}
public boolean isDiscarded()
{
return false;
}
public void setDiscarded( boolean bDiscarded )
{
}
public boolean isCompoundType()
{
return false;
}
public Set<IType> getCompoundTypeComponents()
{
return null;
}
@Override
public IExpression[] getDefaultValueExpressions()
{
if( getMethodInfo() instanceof IOptionalParamCapable )
{
return ((IOptionalParamCapable)getMethodInfo()).getDefaultValueExpressions();
}
return IExpression.EMPTY_ARRAY;
}
@Override
public boolean hasOptionalParams()
{
for( IExpression o : getDefaultValueExpressions() )
{
if( o != null )
{
return true;
}
}
return false;
}
public String[] getParameterNames()
{
IFeatureInfo miOrCi = getMethodOrConstructorInfo();
if( miOrCi instanceof IOptionalParamCapable )
{
return ((IOptionalParamCapable)miOrCi).getParameterNames();
}
return new String[0];
}
public IGosuClass getOwningParameterizedType()
{
return _owningParameterizedType;
}
}