X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fsupport.cs;h=93ff972d7b60667a42c4d49292b26d687cbbb21a;hb=925873231901020ab6cdc869b0966b6b02378738;hp=115c4d917f1efd27c961bb7833a441342e813f07;hpb=2ff91853df471ca8a36e73a2fb5fdcfa40953b56;p=mono.git diff --git a/mcs/mcs/support.cs b/mcs/mcs/support.cs index 115c4d917f1..93ff972d7b6 100755 --- a/mcs/mcs/support.cs +++ b/mcs/mcs/support.cs @@ -8,30 +8,67 @@ // (C) 2001 Ximian, Inc (http://www.ximian.com) // -using System.Reflection.Emit; -using System.Reflection; using System; using System.Text; +using System.Reflection; +using System.Collections; +using System.Reflection.Emit; +using System.Globalization; -namespace CIR { +namespace Mono.CSharp { public interface ParameterData { Type ParameterType (int pos); int Count { get; } + string ParameterName (int pos); string ParameterDesc (int pos); + Parameter.Modifier ParameterModifier (int pos); } public class ReflectionParameters : ParameterData { ParameterInfo [] pi; - + bool last_arg_is_params = false; + public ReflectionParameters (ParameterInfo [] pi) { + object [] attrs; + this.pi = pi; + int count = pi.Length-1; + + if (count >= 0) { + attrs = pi [count].GetCustomAttributes (TypeManager.param_array_type, true); + + if (attrs == null) + return; + + if (attrs.Length == 0) + return; + + last_arg_is_params = true; + } } public Type ParameterType (int pos) { - return pi [pos].ParameterType; + if (last_arg_is_params && pos >= pi.Length - 1) + return pi [pi.Length - 1].ParameterType; + else { + Type t = pi [pos].ParameterType; + + if (t.IsByRef) + return t.GetElementType (); + else + return t; + } + } + + public string ParameterName (int pos) + { + if (last_arg_is_params && pos >= pi.Length - 1) + return pi [pi.Length - 1].Name; + else + return pi [pos].Name; } public string ParameterDesc (int pos) @@ -44,12 +81,34 @@ namespace CIR { if (pi [pos].IsIn) sb.Append ("in "); + if (pos >= pi.Length - 1 && last_arg_is_params) + sb.Append ("params "); + sb.Append (TypeManager.CSharpName (ParameterType (pos))); return sb.ToString (); } + public Parameter.Modifier ParameterModifier (int pos) + { + int len = pi.Length; + + if (pos >= len - 1) + if (last_arg_is_params) + return Parameter.Modifier.PARAMS; + + Type t = pi [pos].ParameterType; + if (t.IsByRef){ + if ((pi [pos].Attributes & ParameterAttributes.Out) != 0) + return Parameter.Modifier.ISBYREF | Parameter.Modifier.OUT; + else + return Parameter.Modifier.ISBYREF | Parameter.Modifier.REF; + } + + return Parameter.Modifier.NONE; + } + public int Count { get { return pi.Length; @@ -59,33 +118,138 @@ namespace CIR { } public class InternalParameters : ParameterData { - Type [] pars; + Type [] param_types; + + public readonly Parameters Parameters; - public InternalParameters (Type [] pars) + public InternalParameters (Type [] param_types, Parameters parameters) + { + this.param_types = param_types; + this.Parameters = parameters; + } + + public InternalParameters (DeclSpace ds, Parameters parameters) + : this (parameters.GetParameterInfo (ds), parameters) { - this.pars = pars; } public int Count { get { - if (pars == null) + if (param_types == null) return 0; - - return pars.Length; + + return param_types.Length; } } + Parameter GetParameter (int pos) + { + Parameter [] fixed_pars = Parameters.FixedParameters; + if (fixed_pars != null){ + int len = fixed_pars.Length; + if (pos < len) + return Parameters.FixedParameters [pos]; + } + + return Parameters.ArrayParameter; + } + public Type ParameterType (int pos) { - if (pars == null) + if (param_types == null) return null; - - return pars [pos]; + + return GetParameter (pos).ParameterType; + } + + + public string ParameterName (int pos) + { + return GetParameter (pos).Name; } public string ParameterDesc (int pos) { - return TypeManager.CSharpName (ParameterType (pos)); + string tmp = String.Empty; + Parameter p = GetParameter (pos); + + // + // We need to and for REF/OUT, because if either is set the + // extra flag ISBYREF will be set as well + // + if ((p.ModFlags & Parameter.Modifier.REF) != 0) + tmp = "ref "; + else if ((p.ModFlags & Parameter.Modifier.OUT) != 0) + tmp = "out "; + else if (p.ModFlags == Parameter.Modifier.PARAMS) + tmp = "params "; + + Type t = ParameterType (pos); + + return tmp + TypeManager.CSharpName (t); + } + + public Parameter.Modifier ParameterModifier (int pos) + { + Parameter.Modifier mod = GetParameter (pos).ModFlags; + + if ((mod & (Parameter.Modifier.REF | Parameter.Modifier.OUT)) != 0) + mod |= Parameter.Modifier.ISBYREF; + + return mod; + } + + } + + class PtrHashtable : Hashtable { + class PtrComparer : IComparer { + public int Compare (object x, object y) + { + if (x == y) + return 0; + else + return 1; + } + } + + public PtrHashtable () + { + comparer = new PtrComparer (); + } + } + + // + // Compares member infos based on their name and + // also allows one argument to be a string + // + class MemberInfoCompare : IComparer { + + public int Compare (object a, object b) + { + if (a == null || b == null){ + Console.WriteLine ("Invalid information passed"); + throw new Exception (); + } + + if (a is string) + return String.Compare ((string) a, ((MemberInfo)b).Name); + + if (b is string) + return String.Compare (((MemberInfo)a).Name, (string) b); + + return String.Compare (((MemberInfo)a).Name, ((MemberInfo)b).Name); + } + } + + struct Pair { + public object First; + public object Second; + + public Pair (object f, object s) + { + First = f; + Second = s; } } + }