// // Imports System.Reflection parameters // 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.Modifiers & Modifiers.METHOD_EXTENSION) != 0 && HasAttribute (CustomAttributeData.GetCustomAttributes (method), "ExtensionAttribute", CompilerServicesNamespace)) { mod = Parameter.Modifier.This; types[i] = ImportType (p.ParameterType, new DynamicTypeReader (p)); } 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 || TypeSpec.IsReferenceType (ptype))) { if (value == null) { default_value = Constant.CreateConstantFromValue (ptype, null, Location.Null); } else { default_value = ImportParameterConstant (value); if (ptype.IsEnum) { default_value = new EnumConstant ((Constant) default_value, ptype); } } var attrs = CustomAttributeData.GetCustomAttributes (p); for (int ii = 0; ii < attrs.Count; ++ii) { var attr = attrs[ii]; var dt = attr.Constructor.DeclaringType; if (dt.Namespace != CompilerServicesNamespace) continue; if (dt.Name == "CallerLineNumberAttribute" && (ptype.BuiltinType == BuiltinTypeSpec.Type.Int || Convert.ImplicitNumericConversionExists (module.Compiler.BuiltinTypes.Int, ptype))) mod |= Parameter.Modifier.CallerLineNumber; else if (dt.Name == "CallerFilePathAttribute" && Convert.ImplicitReferenceConversionExists (module.Compiler.BuiltinTypes.String, ptype)) mod |= Parameter.Modifier.CallerFilePath; else if (dt.Name == "CallerMemberNameAttribute" && Convert.ImplicitReferenceConversionExists (module.Compiler.BuiltinTypes.String, ptype)) mod |= Parameter.Modifier.CallerMemberName; } } 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.BuiltinType == BuiltinTypeSpec.Type.Decimal) { default_value = ImportParameterConstant (value); } } } 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); }
// // TODO: This does not fit here, it should go to different version of AParametersCollection // as the underlying type is not Parameter and some methods will fail to cast // public static AParametersCollection CreateFullyResolved (params TypeSpec[] types) { var pd = new ParameterData [types.Length]; for (int i = 0; i < pd.Length; ++i) pd[i] = new ParameterData (null, Parameter.Modifier.NONE, null); return new ParametersCompiled (pd, types); }