AParametersCollection CreateParameters(TypeSpec parent, ParameterInfo[] pi, MethodBase method)
{
int varargs = method != null && (method.CallingConvention & CallingConventions.VarArgs) != 0 ? 1 : 0;
if (pi.Length == 0 && varargs == 0)
return ParametersCompiled.EmptyReadOnlyParameters;
TypeSpec[] types = new TypeSpec[pi.Length + varargs];
IParameterData[] par = new IParameterData[pi.Length + varargs];
bool is_params = false;
for (int i = 0; i < pi.Length; i++) {
ParameterInfo p = pi[i];
Parameter.Modifier mod = 0;
Expression default_value = null;
if (p.ParameterType.IsByRef) {
if ((p.Attributes & (ParameterAttributes.Out | ParameterAttributes.In)) == ParameterAttributes.Out)
mod = Parameter.Modifier.OUT;
else
mod = Parameter.Modifier.REF;
//
// Strip reference wrapping
//
var el = p.ParameterType.GetElementType ();
types[i] = ImportType (el, new DynamicTypeReader (p)); // TODO: 1-based positio to be csc compatible
} else if (i == 0 && method.IsStatic && parent.IsStatic && parent.MemberDefinition.DeclaringAssembly.HasExtensionMethod &&
HasAttribute (CustomAttributeData.GetCustomAttributes (method), "ExtensionAttribute", CompilerServicesNamespace)) {
mod = Parameter.Modifier.This;
types[i] = ImportType (p.ParameterType);
} else {
types[i] = ImportType (p.ParameterType, new DynamicTypeReader (p));
if (i >= pi.Length - 2 && types[i] is ArrayContainer) {
if (HasAttribute (CustomAttributeData.GetCustomAttributes (p), "ParamArrayAttribute", "System")) {
mod = Parameter.Modifier.PARAMS;
is_params = true;
}
}
if (!is_params && p.IsOptional) {
object value = p.RawDefaultValue;
var ptype = types[i];
if ((p.Attributes & ParameterAttributes.HasDefault) != 0 && ptype.Kind != MemberKind.TypeParameter && (value != null || TypeManager.IsReferenceType (ptype))) {
if (value == null) {
default_value = Constant.CreateConstant (null, ptype, null, Location.Null);
} else {
default_value = ImportParameterConstant (value).Resolve (null);
if (ptype.IsEnum) {
default_value = new EnumConstant ((Constant) default_value, ptype).Resolve (null);
}
}
} else if (value == Missing.Value) {
default_value = EmptyExpression.MissingValue;
} else if (value == null) {
default_value = new DefaultValueExpression (new TypeExpression (ptype, Location.Null), Location.Null);
} else if (ptype == TypeManager.decimal_type) {
default_value = ImportParameterConstant (value).Resolve (null);
}
}
}
par[i] = new ParameterData (p.Name, mod, default_value);
}
if (varargs != 0) {
par[par.Length - 1] = new ArglistParameter (Location.Null);
types[types.Length - 1] = InternalType.Arglist;
}
return method != null ?
new ParametersImported (par, types, varargs != 0, is_params) :
new ParametersImported (par, types, is_params);
}