remove experimental code in #if false .. #endif
[mono.git] / mcs / mcs / support.cs
old mode 100755 (executable)
new mode 100644 (file)
index f3b4b29..85ede8b
@@ -21,6 +21,7 @@ namespace Mono.CSharp {
        public interface ParameterData {
                Type ParameterType (int pos);
                int  Count { get; }
+               bool HasParams { get; }
                string ParameterName (int pos);
                string ParameterDesc (int pos);
                Parameter.Modifier ParameterModifier (int pos);
@@ -29,10 +30,14 @@ namespace Mono.CSharp {
        public class ReflectionParameters : ParameterData {
                ParameterInfo [] pi;
                bool last_arg_is_params = false;
+               bool is_varargs = false;
                
-               public ReflectionParameters (ParameterInfo [] pi)
+               public ReflectionParameters (MethodBase mb)
                {
                        object [] attrs;
+
+                       ParameterInfo [] pi = mb.GetParameters ();
+                       is_varargs = (mb.CallingConvention & CallingConventions.VarArgs) != 0;
                        
                        this.pi = pi;
                        int count = pi.Length-1;
@@ -54,6 +59,8 @@ namespace Mono.CSharp {
                {
                        if (last_arg_is_params && pos >= pi.Length - 1)
                                return pi [pi.Length - 1].ParameterType;
+                       else if (is_varargs && pos >= pi.Length)
+                               return TypeManager.runtime_argument_handle_type;
                        else {
                                Type t = pi [pos].ParameterType;
 
@@ -65,12 +72,17 @@ namespace Mono.CSharp {
                {
                        if (last_arg_is_params && pos >= pi.Length - 1)
                                return pi [pi.Length - 1].Name;
+                       else if (is_varargs && pos >= pi.Length)
+                               return "__arglist";
                        else 
                                return pi [pos].Name;
                }
 
                public string ParameterDesc (int pos)
                {
+                       if (is_varargs && pos >= pi.Length)
+                               return "";                      
+
                        StringBuilder sb = new StringBuilder ();
 
                        if (pi [pos].IsIn)
@@ -96,11 +108,10 @@ namespace Mono.CSharp {
 
                public Parameter.Modifier ParameterModifier (int pos)
                {
-                       int len = pi.Length;
-
-                       if (pos >= len - 1)
-                               if (last_arg_is_params)
-                                       return Parameter.Modifier.PARAMS;
+                       if (last_arg_is_params && pos >= pi.Length - 1)
+                               return Parameter.Modifier.PARAMS;
+                       else if (is_varargs && pos >= pi.Length)
+                               return Parameter.Modifier.ARGLIST;
                        
                        Type t = pi [pos].ParameterType;
                        if (t.IsByRef){
@@ -115,7 +126,13 @@ namespace Mono.CSharp {
 
                public int Count {
                        get {
-                               return pi.Length;
+                               return is_varargs ? pi.Length + 1 : pi.Length;
+                       }
+               }
+
+               public bool HasParams {
+                       get {
+                               return this.last_arg_is_params;
                        }
                }
                
@@ -123,6 +140,8 @@ namespace Mono.CSharp {
 
        public class InternalParameters : ParameterData {
                Type [] param_types;
+               bool has_varargs;
+               int count;
 
                public readonly Parameters Parameters;
                
@@ -130,19 +149,24 @@ namespace Mono.CSharp {
                {
                        this.param_types = param_types;
                        this.Parameters = parameters;
-               }
 
-               public InternalParameters (DeclSpace ds, Parameters parameters)
-                       : this (parameters.GetParameterInfo (ds), parameters)
-               {
+                       has_varargs = parameters.HasArglist;
+
+                       if (param_types == null)
+                               count = 0;
+                       else
+                               count = param_types.Length;
                }
 
                public int Count {
                        get {
-                               if (param_types == null)
-                                       return 0;
+                               return has_varargs ? count + 1 : count;
+                       }
+               }
 
-                               return param_types.Length;
+               public bool HasParams {
+                       get {
+                               return Parameters.ArrayParameter != null;
                        }
                }
 
@@ -160,6 +184,9 @@ namespace Mono.CSharp {
 
                public Type ParameterType (int pos)
                {
+                       if (has_varargs && pos >= count)
+                               return TypeManager.runtime_argument_handle_type;
+
                        if (param_types == null)
                                return null;
 
@@ -169,11 +196,17 @@ namespace Mono.CSharp {
 
                public string ParameterName (int pos)
                {
+                       if (has_varargs && pos >= count)
+                               return "__arglist";
+
                        return GetParameter (pos).Name;
                }
 
                public string ParameterDesc (int pos)
                {
+                       if (has_varargs && pos >= count)
+                               return "__arglist";
+
                        string tmp = String.Empty;
                        Parameter p = GetParameter (pos);
 
@@ -195,6 +228,9 @@ namespace Mono.CSharp {
 
                public Parameter.Modifier ParameterModifier (int pos)
                {
+                       if (has_varargs && pos >= count)
+                               return Parameter.Modifier.ARGLIST;
+
                        Parameter.Modifier mod = GetParameter (pos).ModFlags;
 
                        if ((mod & (Parameter.Modifier.REF | Parameter.Modifier.OUT)) != 0)
@@ -269,29 +305,6 @@ namespace Mono.CSharp {
                }
        }                       
 
-       //
-       // 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, false, CultureInfo.InvariantCulture);
-
-                       if (b is string)
-                               return String.Compare (((MemberInfo)a).Name, (string) b, false, CultureInfo.InvariantCulture);
-
-                       return String.Compare (((MemberInfo)a).Name, ((MemberInfo)b).Name, false, CultureInfo.InvariantCulture);
-               }
-       }
-
        struct Pair {
                public object First;
                public object Second;
@@ -379,10 +392,20 @@ namespace Mono.CSharp {
                                // buffer.
                                if ((value >= buffer_start) && (value < buffer_start + buffer_size)) {
                                        int byte_offset = value - buffer_start;
+
+                                       // pos is an index into a char
+                                       // buffer so it might be
+                                       // greater than the buffer
+                                       // length now, if the buffer
+                                       // contains multibyte chars
                                        pos = byte_offset;
-                                       // encoded characters can take more than 1 byte length
-                                       while (reader.CurrentEncoding.GetByteCount (buffer, 0, pos) > byte_offset)
+                                       
+                                       // encoded characters can take
+                                       // more than 1 byte length.
+                                       while ((pos > buffer.Length) ||
+                                              reader.CurrentEncoding.GetByteCount (buffer, 0, pos) > byte_offset) {
                                                pos--;
+                                       }
                                        
                                        return;
                                }