public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
{
+#if !NET_2_0
if (a.Type == TypeManager.marshal_as_attr_type) {
UnmanagedMarshal marshal = a.GetMarshal (this);
if (marshal != null) {
}
return;
}
-
+#endif
if (a.HasSecurityAttribute) {
a.Error_InvalidSecurityParent ();
return;
public class ImplicitLambdaParameter : Parameter
{
public ImplicitLambdaParameter (string name, Location loc)
- : base ((Type)null, name, Modifier.NONE, null, loc)
+ : base (null, name, Modifier.NONE, null, loc)
{
}
- public override bool Resolve (IResolveContext ec)
+ public override Type Resolve (IResolveContext ec)
{
if (parameter_type == null)
throw new InternalErrorException ("A type of implicit lambda parameter `{0}' is not set",
Name);
- return true;
+ return parameter_type;
+ }
+
+ public Type Type {
+ set { parameter_type = value; }
}
}
public class ParamsParameter : Parameter {
- public ParamsParameter (Expression type, string name, Attributes attrs, Location loc):
+ public ParamsParameter (FullNamedExpression type, string name, Attributes attrs, Location loc):
base (type, name, Parameter.Modifier.PARAMS, attrs, loc)
{
}
- public override bool Resolve (IResolveContext ec)
+ public override Type Resolve (IResolveContext ec)
{
- if (!base.Resolve (ec))
- return false;
+ if (base.Resolve (ec) == null)
+ return null;
if (!parameter_type.IsArray || parameter_type.GetArrayRank () != 1) {
Report.Error (225, Location, "The params parameter must be a single dimensional array");
- return false;
+ return null;
}
- return true;
+
+ return parameter_type;
}
public override void ApplyAttributes (MethodBuilder mb, ConstructorBuilder cb, int index)
public class ArglistParameter : Parameter {
// Doesn't have proper type because it's never chosen for better conversion
- public ArglistParameter () :
- base (typeof (ArglistParameter), String.Empty, Parameter.Modifier.ARGLIST, null, Location.Null)
+ public ArglistParameter (Location loc) :
+ base (null, String.Empty, Parameter.Modifier.ARGLIST, null, loc)
+ {
+ }
+
+ public override void ApplyAttributes (MethodBuilder mb, ConstructorBuilder cb, int index)
{
+ // Nothing to do
}
public override bool CheckAccessibility (InterfaceMemberBase member)
return true;
}
- public override bool Resolve (IResolveContext ec)
+ public override Type Resolve (IResolveContext ec)
{
- return true;
+ return typeof (ArglistParameter);
}
public override string GetSignatureForError ()
}
}
- /// <summary>
- /// Represents a single method parameter
- /// </summary>
- public class Parameter : ParameterBase {
+ public interface IParameterData
+ {
+ bool HasExtensionMethodModifier { get; }
+ Parameter.Modifier ModFlags { get; }
+ string Name { get; }
+ }
+
+ //
+ // Parameter information created by parser
+ //
+ public class Parameter : ParameterBase, IParameterData, ILocalVariable {
[Flags]
public enum Modifier : byte {
NONE = 0,
static string[] attribute_targets = new string [] { "param" };
- Expression TypeName;
- public Modifier modFlags;
- public string Name;
- public bool IsCaptured;
+ protected FullNamedExpression TypeName;
+ readonly Modifier modFlags;
+ string name;
protected Type parameter_type;
public readonly Location Location;
+ int idx;
+ public bool HasAddressTaken;
IResolveContext resolve_context;
LocalVariableReference expr_tree_variable;
static TypeExpr parameter_expr_tree_type;
- Variable var;
- public Variable Variable {
- get { return var; }
- }
+ public HoistedVariable HoistedVariableReference;
-#if GMCS_SOURCE
- public bool IsTypeParameter;
- GenericConstraints constraints;
-#else
- public bool IsTypeParameter {
- get {
- return false;
- }
- set {
- if (value)
- throw new Exception ("You can not se TypeParameter in MCS");
- }
- }
-#endif
-
- public Parameter (Expression type, string name, Modifier mod, Attributes attrs, Location loc)
- : this (type.Type, name, mod, attrs, loc)
+ public Parameter (FullNamedExpression type, string name, Modifier mod, Attributes attrs, Location loc)
+ : base (attrs)
{
if (type == TypeManager.system_void_expr)
Report.Error (1536, loc, "Invalid parameter type `void'");
-
- TypeName = type;
- }
- public Parameter (Type type, string name, Modifier mod, Attributes attrs, Location loc)
- : base (attrs)
- {
- Name = name;
+ this.name = name;
modFlags = mod;
- parameter_type = type;
Location = loc;
+ TypeName = type;
}
public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
public virtual bool CheckAccessibility (InterfaceMemberBase member)
{
- if (IsTypeParameter)
+ if (parameter_type == null || TypeManager.IsGenericParameter (parameter_type))
return true;
return member.IsAccessibleAs (parameter_type);
// <summary>
// Resolve is used in method definitions
// </summary>
- public virtual bool Resolve (IResolveContext ec)
+ public virtual Type Resolve (IResolveContext ec)
{
// HACK: to resolve attributes correctly
this.resolve_context = ec;
if (parameter_type != null)
- return true;
+ return parameter_type;
TypeExpr texpr = TypeName.ResolveAsTypeTerminal (ec, false);
if (texpr == null)
- return false;
+ return null;
parameter_type = texpr.Type;
+ if ((modFlags & Parameter.Modifier.ISBYREF) != 0 &&
+ TypeManager.IsSpecialType (parameter_type)) {
+ Report.Error (1601, Location, "Method or delegate parameter cannot be of type `{0}'",
+ GetSignatureForError ());
+ return null;
+ }
+
#if GMCS_SOURCE
TypeParameterExpr tparam = texpr as TypeParameterExpr;
if (tparam != null) {
- IsTypeParameter = true;
- constraints = tparam.TypeParameter.Constraints;
- return true;
+ return parameter_type;
}
#endif
if ((parameter_type.Attributes & Class.StaticClassAttribute) == Class.StaticClassAttribute) {
- Report.Error (721, Location, "`{0}': static types cannot be used as parameters",
+ Report.Error (721, Location, "`{0}': static types cannot be used as parameters",
texpr.GetSignatureForError ());
- return false;
- }
-
- if ((modFlags & Parameter.Modifier.ISBYREF) != 0){
- if (parameter_type == TypeManager.typed_reference_type ||
- parameter_type == TypeManager.arg_iterator_type){
- Report.Error (1601, Location, "Method or delegate parameter cannot be of type `{0}'",
- GetSignatureForError ());
- return false;
- }
+ return parameter_type;
}
if ((modFlags & Modifier.This) != 0 && parameter_type.IsPointer) {
Report.Error (1103, Location, "The type of extension method cannot be `{0}'",
TypeManager.CSharpName (parameter_type));
- return false;
}
-
- return true;
- }
- public void ResolveVariable (ToplevelBlock toplevel, int idx)
- {
- if (toplevel.RootScope != null)
- var = toplevel.RootScope.GetCapturedParameter (this);
- if (var == null)
- var = new ParameterVariable (this, idx);
+ return parameter_type;
}
- public Type ExternalType ()
+ public void ResolveVariable (int idx)
{
- if ((modFlags & Parameter.Modifier.ISBYREF) != 0)
- return TypeManager.GetReferenceType (parameter_type);
-
- return parameter_type;
+ this.idx = idx;
}
public bool HasExtensionMethodModifier {
get { return modFlags & ~Modifier.This; }
}
- public Type ParameterType {
- get {
- return parameter_type;
- }
- set {
- parameter_type = value;
- IsTypeParameter = false;
- }
+ public string Name {
+ get { return name; }
+ set { name = value; }
}
-#if GMCS_SOURCE
- public GenericConstraints GenericConstraints {
- get {
- return constraints;
- }
- }
-#endif
-
ParameterAttributes Attributes {
- get {
- return (modFlags & Modifier.OUT) == Modifier.OUT ?
- ParameterAttributes.Out : ParameterAttributes.None;
- }
+ get { return Parameters.GetParameterAttribute (modFlags); }
}
- // TODO: should be removed !!!!!!!
- public static ParameterAttributes GetParameterAttributes (Modifier mod)
- {
- int flags = ((int) mod) & ~((int) Parameter.Modifier.ISBYREF);
- switch ((Modifier) flags) {
- case Modifier.NONE:
- return ParameterAttributes.None;
- case Modifier.REF:
- return ParameterAttributes.None;
- case Modifier.OUT:
- return ParameterAttributes.Out;
- case Modifier.PARAMS:
- return 0;
- }
-
- return ParameterAttributes.None;
- }
-
public override AttributeTargets AttributeTargets {
get {
return AttributeTargets.Parameter;
string mod = GetModifierSignature (modFlags);
if (mod.Length > 0)
- return String.Concat (mod, ' ', type_name);
+ return String.Concat (mod, " ", type_name);
return type_name;
}
public static string GetModifierSignature (Modifier mod)
{
switch (mod) {
- case Modifier.OUT:
- return "out";
- case Modifier.PARAMS:
- return "params";
- case Modifier.REF:
- return "ref";
- case Modifier.ARGLIST:
- return "__arglist";
- case Modifier.This:
- return "this";
- default:
- return "";
+ case Modifier.OUT:
+ return "out";
+ case Modifier.PARAMS:
+ return "params";
+ case Modifier.REF:
+ return "ref";
+ case Modifier.This:
+ return "this";
+ default:
+ return "";
}
}
public void IsClsCompliant ()
{
- if (AttributeTester.IsClsCompliant (ExternalType ()))
+ if (AttributeTester.IsClsCompliant (parameter_type))
return;
- Report.Error (3001, Location, "Argument type `{0}' is not CLS-compliant", GetSignatureForError ());
+ Report.Warning (3001, 1, Location, "Argument type `{0}' is not CLS-compliant", GetSignatureForError ());
}
public virtual void ApplyAttributes (MethodBuilder mb, ConstructorBuilder cb, int index)
{
-#if !GMCS_SOURCE || !MS_COMPATIBLE
- // TODO: It should use mb.DefineGenericParameters
if (mb == null)
builder = cb.DefineParameter (index, Attributes, Name);
- else
+ else
builder = mb.DefineParameter (index, Attributes, Name);
-#endif
if (OptAttributes != null)
OptAttributes.Emit ();
}
}
- protected class ParameterVariable : Variable
- {
- public readonly Parameter Parameter;
- public readonly int Idx;
- public readonly bool IsRef;
-
- public ParameterVariable (Parameter par, int idx)
- {
- this.Parameter = par;
- this.Idx = idx;
- this.IsRef = (par.ModFlags & Parameter.Modifier.ISBYREF) != 0;
- }
-
- public override Type Type {
- get { return Parameter.ParameterType; }
- }
-
- public override bool HasInstance {
- get { return false; }
- }
-
- public override bool NeedsTemporary {
- get { return false; }
- }
-
- public override void EmitInstance (EmitContext ec)
- {
- }
-
- public override void Emit (EmitContext ec)
- {
- int arg_idx = Idx;
- if (!ec.MethodIsStatic)
- arg_idx++;
-
- ParameterReference.EmitLdArg (ec.ig, arg_idx);
- }
-
- public override void EmitAssign (EmitContext ec)
- {
- int arg_idx = Idx;
- if (!ec.MethodIsStatic)
- arg_idx++;
-
- if (arg_idx <= 255)
- ec.ig.Emit (OpCodes.Starg_S, (byte) arg_idx);
- else
- ec.ig.Emit (OpCodes.Starg, arg_idx);
- }
-
- public override void EmitAddressOf (EmitContext ec)
- {
- int arg_idx = Idx;
-
- if (!ec.MethodIsStatic)
- arg_idx++;
-
- if (IsRef) {
- if (arg_idx <= 255)
- ec.ig.Emit (OpCodes.Ldarg_S, (byte) arg_idx);
- else
- ec.ig.Emit (OpCodes.Ldarg, arg_idx);
- } else {
- if (arg_idx <= 255)
- ec.ig.Emit (OpCodes.Ldarga_S, (byte) arg_idx);
- else
- ec.ig.Emit (OpCodes.Ldarga, arg_idx);
- }
- }
- }
-
public Parameter Clone ()
{
- Parameter p = new Parameter (parameter_type, Name, ModFlags, attributes, Location);
- p.IsTypeParameter = IsTypeParameter;
+ Parameter p = (Parameter) MemberwiseClone ();
+ if (attributes != null) {
+ p.attributes = attributes.Clone ();
+ p.attributes.AttachTo (p);
+ }
return p;
}
arguments.Add (new Argument (new TypeOf (
new TypeExpression (parameter_type, Location), Location)));
arguments.Add (new Argument (new StringConstant (Name, Location)));
- return new Assign (ExpressionTreeVariableReference (),
+ return new SimpleAssign (ExpressionTreeVariableReference (),
Expression.CreateExpressionFactoryCall ("Parameter", null, arguments, Location));
}
+ public void Emit (EmitContext ec)
+ {
+ int arg_idx = idx;
+ if (!ec.IsStatic)
+ arg_idx++;
+
+ ParameterReference.EmitLdArg (ec.ig, arg_idx);
+ }
+
+ public void EmitAssign (EmitContext ec)
+ {
+ int arg_idx = idx;
+ if (!ec.IsStatic)
+ arg_idx++;
+
+ if (arg_idx <= 255)
+ ec.ig.Emit (OpCodes.Starg_S, (byte) arg_idx);
+ else
+ ec.ig.Emit (OpCodes.Starg, arg_idx);
+ }
+
+ public void EmitAddressOf (EmitContext ec)
+ {
+ int arg_idx = idx;
+
+ if (!ec.IsStatic)
+ arg_idx++;
+
+ bool is_ref = (ModFlags & Modifier.ISBYREF) != 0;
+ if (is_ref) {
+ if (arg_idx <= 255)
+ ec.ig.Emit (OpCodes.Ldarg_S, (byte) arg_idx);
+ else
+ ec.ig.Emit (OpCodes.Ldarg, arg_idx);
+ } else {
+ if (arg_idx <= 255)
+ ec.ig.Emit (OpCodes.Ldarga_S, (byte) arg_idx);
+ else
+ ec.ig.Emit (OpCodes.Ldarga, arg_idx);
+ }
+ }
+
public Expression ExpressionTreeVariableReference ()
{
return expr_tree_variable;
}
}
- /// <summary>
- /// Represents the methods parameters
- /// </summary>
- public class Parameters : ParameterData {
- // Null object pattern
- public Parameter [] FixedParameters;
- public readonly bool HasArglist;
- Type [] types;
- int count;
-
- public static readonly Parameters EmptyReadOnlyParameters = new Parameters ();
- static readonly Parameter ArgList = new ArglistParameter ();
-
-#if GMCS_SOURCE
-// public readonly TypeParameter[] TypeParameters;
-#endif
+ //
+ // Imported or resolved parameter information
+ //
+ public class ParameterData : IParameterData
+ {
+ readonly string name;
+ readonly Parameter.Modifier modifiers;
- private Parameters ()
+ public ParameterData (string name, Parameter.Modifier modifiers)
{
- FixedParameters = new Parameter[0];
- types = new Type [0];
+ this.name = name;
+ this.modifiers = modifiers;
}
- private Parameters (Parameter[] parameters, Type[] types)
- {
- FixedParameters = parameters;
- this.types = types;
- count = types.Length;
- }
-
- public Parameters (params Parameter[] parameters)
- {
- if (parameters == null)
- throw new ArgumentException ("Use EmptyReadOnlyPatameters");
+ #region IParameterData Members
- FixedParameters = parameters;
- count = parameters.Length;
+ public bool HasExtensionMethodModifier {
+ get { return (modifiers & Parameter.Modifier.This) != 0; }
}
- public Parameters (Parameter[] parameters, bool has_arglist):
- this (parameters)
- {
- HasArglist = has_arglist;
+ public Parameter.Modifier ModFlags {
+ get { return modifiers & ~Parameter.Modifier.This; }
}
-
- public static Parameters CreateFullyResolved (Parameter p)
- {
- return new Parameters (new Parameter [] { p }, new Type [] { p.ParameterType });
- }
-
- public static Parameters CreateFullyResolved (Parameter[] parameters, Type[] types)
- {
- return new Parameters (parameters, types);
+
+ public string Name {
+ get { return name; }
}
- /// <summary>
- /// Use this method when you merge compiler generated argument with user arguments
- /// </summary>
- public static Parameters MergeGenerated (Parameters userParams, params Parameter[] compilerParams)
- {
- Parameter[] all_params = new Parameter [userParams.count + compilerParams.Length];
- Type[] all_types = new Type[all_params.Length];
- userParams.FixedParameters.CopyTo(all_params, 0);
- userParams.Types.CopyTo (all_types, 0);
+ #endregion
+ }
- int last_filled = userParams.Count;
- foreach (Parameter p in compilerParams) {
- for (int i = 0; i < last_filled; ++i) {
- while (p.Name == all_params [i].Name) {
- p.Name = '_' + p.Name;
- }
- }
- all_params [last_filled] = p;
- all_types [last_filled] = p.ParameterType;
- ++last_filled;
- }
-
- return new Parameters (all_params, all_types);
- }
+ public abstract class AParametersCollection
+ {
+ protected bool has_arglist;
+ protected bool has_params;
- public bool Empty {
- get {
- return count == 0;
- }
- }
+ // Null object pattern
+ protected IParameterData [] parameters;
+ protected Type [] types;
public int Count {
- get {
- return HasArglist ? count + 1 : count;
- }
+ get { return parameters.Length; }
}
- //
- // The property can be used after parameter types were resolved.
- //
public Type ExtensionMethodType {
get {
- if (count == 0)
+ if (Count == 0)
return null;
return FixedParameters [0].HasExtensionMethodModifier ?
}
}
- public bool HasExtensionMethodType {
+ public IParameterData [] FixedParameters {
get {
- if (count == 0)
- return false;
-
- return FixedParameters [0].HasExtensionMethodModifier;
+ return parameters;
}
}
-
- bool VerifyArgs ()
+ public static ParameterAttributes GetParameterAttribute (Parameter.Modifier modFlags)
{
- if (count < 2)
- return true;
+ return (modFlags & Parameter.Modifier.OUT) == Parameter.Modifier.OUT ?
+ ParameterAttributes.Out : ParameterAttributes.None;
+ }
- for (int i = 0; i < count; i++){
- string base_name = FixedParameters [i].Name;
- for (int j = i + 1; j < count; j++){
- if (base_name != FixedParameters [j].Name)
- continue;
+ public Type [] GetEmitTypes ()
+ {
+ Type [] types = null;
+ if (has_arglist) {
+ if (Count == 1)
+ return Type.EmptyTypes;
- Report.Error (100, FixedParameters [i].Location,
- "The parameter name `{0}' is a duplicate", base_name);
- return false;
- }
+ types = new Type [Count - 1];
+ Array.Copy (Types, types, types.Length);
}
- return true;
- }
-
-
- /// <summary>
- /// Returns the paramenter information based on the name
- /// </summary>
- public Parameter GetParameterByName (string name, out int idx)
- {
- idx = 0;
- if (count == 0)
- return null;
+ for (int i = 0; i < Count; ++i) {
+ if ((FixedParameters [i].ModFlags & Parameter.Modifier.ISBYREF) == 0)
+ continue;
- int i = 0;
+ if (types == null)
+ types = (Type []) Types.Clone ();
- foreach (Parameter par in FixedParameters){
- if (par.Name == name){
- idx = i;
- return par;
- }
- i++;
+ types [i] = TypeManager.GetReferenceType (types [i]);
}
- return null;
+
+ if (types == null)
+ types = Types;
+
+ return types;
}
- public Parameter GetParameterByName (string name)
+ public string GetSignatureForError ()
{
- int idx;
+ StringBuilder sb = new StringBuilder ("(");
+ for (int i = 0; i < Count; ++i) {
+ if (i != 0)
+ sb.Append (", ");
+ sb.Append (ParameterDesc (i));
+ }
+ sb.Append (')');
+ return sb.ToString ();
+ }
- return GetParameterByName (name, out idx);
+ public bool HasArglist {
+ get { return has_arglist; }
}
-
- public bool Resolve (IResolveContext ec)
- {
- if (types != null)
- return true;
- types = new Type [count];
-
- if (!VerifyArgs ())
- return false;
+ public bool HasExtensionMethodType {
+ get {
+ if (Count == 0)
+ return false;
- bool ok = true;
- Parameter p;
- for (int i = 0; i < FixedParameters.Length; ++i) {
- p = FixedParameters [i];
- if (!p.Resolve (ec)) {
- ok = false;
- continue;
- }
- types [i] = p.ExternalType ();
+ return FixedParameters [0].HasExtensionMethodModifier;
}
-
- return ok;
}
- public void ResolveVariable (ToplevelBlock toplevel)
- {
- for (int i = 0; i < FixedParameters.Length; ++i) {
- Parameter p = FixedParameters [i];
- p.ResolveVariable (toplevel, i);
- }
+ public bool HasParams {
+ get { return has_params; }
}
- public CallingConventions CallingConvention
- {
- get {
- if (HasArglist)
- return CallingConventions.VarArgs;
- else
- return CallingConventions.Standard;
- }
+ public bool IsEmpty {
+ get { return parameters.Length == 0; }
}
- // Define each type attribute (in/out/ref) and
- // the argument names.
- public void ApplyAttributes (MethodBase builder)
+ public string ParameterDesc (int pos)
{
- if (count == 0)
- return;
+ if (types == null || types [pos] == null)
+ return ((Parameter)FixedParameters [pos]).GetSignatureForError ();
- MethodBuilder mb = builder as MethodBuilder;
- ConstructorBuilder cb = builder as ConstructorBuilder;
+ string type = TypeManager.CSharpName (types [pos]);
+ if (FixedParameters [pos].HasExtensionMethodModifier)
+ return "this " + type;
- for (int i = 0; i < FixedParameters.Length; i++) {
- FixedParameters [i].ApplyAttributes (mb, cb, i + 1);
- }
+ Parameter.Modifier mod = FixedParameters [pos].ModFlags & ~Parameter.Modifier.ARGLIST;
+ if (mod == 0)
+ return type;
+
+ return Parameter.GetModifierSignature (mod) + " " + type;
+ }
+
+ public Type[] Types {
+ get { return types; }
+ set { types = value; }
}
#if MS_COMPATIBLE
- public ParameterData InflateTypes (Type[] genArguments, Type[] argTypes)
+ public AParametersCollection InflateTypes (Type[] genArguments, Type[] argTypes)
{
- Parameters p = Clone ();
- for (int i = 0; i < count; ++i) {
+ AParametersCollection p = (AParametersCollection) MemberwiseClone (); // Clone ();
+
+ for (int i = 0; i < Count; ++i) {
if (types[i].IsGenericType) {
- Type[] gen_arguments_open = new Type [types[i].GetGenericTypeDefinition ().GetGenericArguments ().Length];
+ Type[] gen_arguments_open = new Type[types[i].GetGenericTypeDefinition ().GetGenericArguments ().Length];
Type[] gen_arguments = types[i].GetGenericArguments ();
for (int ii = 0; ii < gen_arguments_open.Length; ++ii) {
if (gen_arguments[ii].IsGenericParameter) {
gen_arguments_open[ii] = gen_arguments[ii];
}
- p.FixedParameters [i].ParameterType = p.types[i] =
- types[i].GetGenericTypeDefinition ().MakeGenericType (gen_arguments_open);
+ p.types[i] = types[i].GetGenericTypeDefinition ().MakeGenericType (gen_arguments_open);
continue;
}
if (types[i].IsGenericParameter) {
Type gen_argument = argTypes[types[i].GenericParameterPosition];
- p.FixedParameters[i].ParameterType = p.types[i] = gen_argument;
+ p.types[i] = gen_argument;
continue;
}
}
return p;
}
#endif
+ }
- public void VerifyClsCompliance ()
+ //
+ // A collection of imported or resolved parameters
+ //
+ public class ParametersCollection : AParametersCollection
+ {
+ ParametersCollection (AParametersCollection param, Type[] types)
{
- foreach (Parameter p in FixedParameters)
- p.IsClsCompliant ();
+ this.parameters = param.FixedParameters;
+ this.types = types;
+ has_arglist = param.HasArglist;
+ has_params = param.HasParams;
}
- public string GetSignatureForError ()
+ ParametersCollection (IParameterData [] parameters, Type [] types, MethodBase method, bool hasParams)
{
- StringBuilder sb = new StringBuilder ("(");
- if (count > 0) {
- for (int i = 0; i < FixedParameters.Length; ++i) {
- sb.Append (FixedParameters[i].GetSignatureForError ());
- if (i < FixedParameters.Length - 1)
- sb.Append (", ");
- }
+ this.parameters = parameters;
+ this.types = types;
+ has_arglist = (method.CallingConvention & CallingConventions.VarArgs) != 0;
+ if (has_arglist) {
+ this.parameters = new IParameterData [parameters.Length + 1];
+ parameters.CopyTo (this.parameters, 0);
+ this.parameters [parameters.Length] = new ArglistParameter (Location.Null);
+ this.types = new Type [types.Length + 1];
+ types.CopyTo (this.types, 0);
+ this.types [types.Length] = TypeManager.arg_iterator_type;
}
+ has_params = hasParams;
+ }
- if (HasArglist) {
- if (sb.Length > 1)
- sb.Append (", ");
- sb.Append ("__arglist");
+ public ParametersCollection (IParameterData [] param, Type[] types)
+ {
+ this.parameters = param;
+ this.types = types;
+ }
+
+ public static AParametersCollection Create (MethodBase method)
+ {
+ return Create (method.GetParameters (), method);
+ }
+
+ //
+ // Generic method parameters importer, param is shared between all instances
+ //
+ public static AParametersCollection Create (AParametersCollection param, MethodBase method)
+ {
+ if (param.IsEmpty)
+ return param;
+
+ ParameterInfo [] pi = method.GetParameters ();
+ Type [] types = new Type [pi.Length];
+ for (int i = 0; i < types.Length; i++) {
+ Type t = pi [i].ParameterType;
+ if (t.IsByRef)
+ t = TypeManager.GetElementType (t);
+
+ types [i] = TypeManager.TypeToCoreType (t);
}
- sb.Append (')');
- return sb.ToString ();
+ return new ParametersCollection (param, types);
}
- public Type[] Types {
- get {
- return types;
+ //
+ // Imports SRE parameters
+ //
+ public static AParametersCollection Create (ParameterInfo [] pi, MethodBase method)
+ {
+ if (pi.Length == 0) {
+ if (method != null && (method.CallingConvention & CallingConventions.VarArgs) != 0)
+ return new ParametersCollection (new IParameterData [0], Type.EmptyTypes, method, false);
+
+ return Parameters.EmptyReadOnlyParameters;
}
- //
- // Dangerous, used by implicit lambda parameters
- // only to workaround bad design
- //
- set {
- types = value;
+
+ Type [] types = new Type [pi.Length];
+ IParameterData [] par = new IParameterData [pi.Length];
+ bool is_params = false;
+ for (int i = 0; i < types.Length; i++) {
+ types [i] = TypeManager.TypeToCoreType (pi [i].ParameterType);
+
+ ParameterInfo p = pi [i];
+ Parameter.Modifier mod = 0;
+ if (types [i].IsByRef) {
+ if ((p.Attributes & (ParameterAttributes.Out | ParameterAttributes.In)) == ParameterAttributes.Out)
+ mod = Parameter.Modifier.OUT;
+ else
+ mod = Parameter.Modifier.REF;
+
+ //
+ // Strip reference wrapping
+ //
+ types [i] = TypeManager.GetElementType (types [i]);
+ } else if (i == 0 && TypeManager.extension_attribute_type != null && method != null && method.IsStatic &&
+ (method.DeclaringType.Attributes & Class.StaticClassAttribute) == Class.StaticClassAttribute &&
+ method.IsDefined (TypeManager.extension_attribute_type, false)) {
+ mod = Parameter.Modifier.This;
+ } else if (i >= pi.Length - 2 && types [i].IsArray) {
+ if (p.IsDefined (TypeManager.param_array_type, false)) {
+ mod = Parameter.Modifier.PARAMS;
+ is_params = true;
+ }
+ }
+
+ par [i] = new ParameterData (p.Name, mod);
}
+
+ return method != null ?
+ new ParametersCollection (par, types, method, is_params) :
+ new ParametersCollection (par, types);
+ }
+ }
+
+ /// <summary>
+ /// Represents the methods parameters
+ /// </summary>
+ public class Parameters : AParametersCollection {
+ public static readonly Parameters EmptyReadOnlyParameters = new Parameters ();
+
+ // Used by C# 2.0 delegates
+ public static readonly Parameters Undefined = new Parameters ();
+
+ private Parameters ()
+ {
+ parameters = new Parameter [0];
+ types = Type.EmptyTypes;
}
- public Parameter this [int pos]
+ private Parameters (Parameter [] parameters, Type [] types)
{
- get {
- if (pos >= count && (HasArglist || HasParams)) {
- if (HasArglist && (pos == 0 || pos >= count))
- return ArgList;
- pos = count - 1;
+ this.parameters = parameters;
+ this.types = types;
+ }
+
+ public Parameters (params Parameter[] parameters)
+ {
+ if (parameters == null)
+ throw new ArgumentException ("Use EmptyReadOnlyParameters");
+
+ this.parameters = parameters;
+ int count = parameters.Length;
+
+ if (count == 0)
+ return;
+
+ if (count == 1) {
+ has_params = (parameters [0].ModFlags & Parameter.Modifier.PARAMS) != 0;
+ return;
+ }
+
+ for (int i = 0; i < count; i++){
+ string base_name = parameters [i].Name;
+ has_params |= (parameters [i].ModFlags & Parameter.Modifier.PARAMS) != 0;
+
+ for (int j = i + 1; j < count; j++){
+ if (base_name != parameters [j].Name)
+ continue;
+
+ ErrorDuplicateName (parameters [i]);
+ i = j;
}
+ }
+ }
+
+ public Parameters (Parameter [] parameters, bool has_arglist) :
+ this (parameters)
+ {
+ this.has_arglist = has_arglist;
+ }
+
+ public static Parameters CreateFullyResolved (Parameter p, Type type)
+ {
+ return new Parameters (new Parameter [] { p }, new Type [] { type });
+ }
+
+ public static Parameters CreateFullyResolved (Parameter[] parameters, Type[] types)
+ {
+ return new Parameters (parameters, types);
+ }
+
+ public static Parameters MergeGenerated (Parameters userParams, bool checkConflicts, Parameter compilerParams, Type compilerTypes)
+ {
+ return MergeGenerated (userParams, checkConflicts,
+ new Parameter [] { compilerParams },
+ new Type [] { compilerTypes });
+ }
- return FixedParameters [pos];
+ //
+ // Use this method when you merge compiler generated parameters with user parameters
+ //
+ public static Parameters MergeGenerated (Parameters userParams, bool checkConflicts, Parameter[] compilerParams, Type[] compilerTypes)
+ {
+ Parameter[] all_params = new Parameter [userParams.Count + compilerParams.Length];
+ userParams.FixedParameters.CopyTo(all_params, 0);
+
+ Type [] all_types;
+ if (userParams.types != null) {
+ all_types = new Type [all_params.Length];
+ userParams.Types.CopyTo (all_types, 0);
+ } else {
+ all_types = null;
+ }
+
+ int last_filled = userParams.Count;
+ int index = 0;
+ foreach (Parameter p in compilerParams) {
+ for (int i = 0; i < last_filled; ++i) {
+ while (p.Name == all_params [i].Name) {
+ if (checkConflicts && i < userParams.Count) {
+ Report.Error (316, userParams [i].Location,
+ "The parameter name `{0}' conflicts with a compiler generated name", p.Name);
+ }
+ p.Name = '_' + p.Name;
+ }
+ }
+ all_params [last_filled] = p;
+ if (all_types != null)
+ all_types [last_filled] = compilerTypes [index++];
+ ++last_filled;
}
+
+ Parameters parameters = new Parameters (all_params, all_types);
+ parameters.has_params = userParams.has_params;
+ return parameters;
}
- #region ParameterData Members
+ protected virtual void ErrorDuplicateName (Parameter p)
+ {
+ Report.Error (100, p.Location, "The parameter name `{0}' is a duplicate", p.Name);
+ }
- public Type ParameterType (int pos)
+ /// <summary>
+ /// Returns the parameter information based on the name
+ /// </summary>
+ public int GetParameterIndexByName (string name)
{
- return this [pos].ExternalType ();
+ for (int idx = 0; idx < Count; ++idx) {
+ if (parameters [idx].Name == name)
+ return idx;
+ }
+
+ return -1;
}
- public bool HasParams {
- get {
- if (count == 0)
- return false;
+ public bool Resolve (IResolveContext ec)
+ {
+ if (types != null)
+ return true;
- for (int i = count; i != 0; --i) {
- if ((FixedParameters [i - 1].ModFlags & Parameter.Modifier.PARAMS) != 0)
- return true;
+ types = new Type [Count];
+
+ bool ok = true;
+ Parameter p;
+ for (int i = 0; i < FixedParameters.Length; ++i) {
+ p = this [i];
+ Type t = p.Resolve (ec);
+ if (t == null) {
+ ok = false;
+ continue;
}
- return false;
+
+ types [i] = t;
}
+
+ return ok;
}
- public string ParameterName (int pos)
+ public void ResolveVariable ()
{
- return this [pos].Name;
+ for (int i = 0; i < FixedParameters.Length; ++i) {
+ this [i].ResolveVariable (i);
+ }
}
- public string ParameterDesc (int pos)
+ public CallingConventions CallingConvention
+ {
+ get {
+ if (HasArglist)
+ return CallingConventions.VarArgs;
+ else
+ return CallingConventions.Standard;
+ }
+ }
+
+ // Define each type attribute (in/out/ref) and
+ // the argument names.
+ public void ApplyAttributes (MethodBase builder)
{
- return this [pos].GetSignatureForError ();
+ if (Count == 0)
+ return;
+
+ MethodBuilder mb = builder as MethodBuilder;
+ ConstructorBuilder cb = builder as ConstructorBuilder;
+
+ for (int i = 0; i < Count; i++) {
+ this [i].ApplyAttributes (mb, cb, i + 1);
+ }
}
- public Parameter.Modifier ParameterModifier (int pos)
+ public void VerifyClsCompliance ()
{
- return this [pos].ModFlags;
+ foreach (Parameter p in FixedParameters)
+ p.IsClsCompliant ();
+ }
+
+ public Parameter this [int pos] {
+ get { return (Parameter) parameters [pos]; }
}
public Expression CreateExpressionTree (EmitContext ec, Location loc)
{
- ArrayList initializers = new ArrayList (count);
+ ArrayList initializers = new ArrayList (Count);
foreach (Parameter p in FixedParameters) {
//
// Each parameter expression is stored to local variable
public Parameters Clone ()
{
- Parameter [] parameters_copy = new Parameter [FixedParameters.Length];
- int i = 0;
- foreach (Parameter p in FixedParameters)
- parameters_copy [i++] = p.Clone ();
- Parameters ps = new Parameters (parameters_copy, HasArglist);
- if (types != null)
- ps.types = (Type[])types.Clone ();
- return ps;
+ Parameters p = (Parameters) MemberwiseClone ();
+
+ p.parameters = new IParameterData [parameters.Length];
+ for (int i = 0; i < Count; ++i)
+ p.parameters [i] = this [i].Clone ();
+
+ return p;
}
-
- #endregion
}
}