X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fgmcs%2Fsupport.cs;h=328fbbeea7e1d5931cbab066838ee21a9c27d1ad;hb=33828ad95f877e3e5ae6bac604a2db3760b8ea7b;hp=59989b5b4d40ff2e8e1668e9cfb702c837b530ee;hpb=4ee1800ffc45783719c1de26db7172ba6baf4d0e;p=mono.git diff --git a/mcs/gmcs/support.cs b/mcs/gmcs/support.cs old mode 100755 new mode 100644 index 59989b5b4d4..328fbbeea7e --- a/mcs/gmcs/support.cs +++ b/mcs/gmcs/support.cs @@ -18,48 +18,48 @@ using System.Globalization; namespace Mono.CSharp { - public interface GenericConstraints { - bool HasConstructor { get; } - bool IsReferenceType { get; } - bool IsValueType { get; } - bool HasClassConstraint { get; } - Type ClassConstraint { get; } - Type[] InterfaceConstraints { get; } - } - public interface ParameterData { Type ParameterType (int pos); GenericConstraints GenericConstraints (int pos); - bool HasArrayParameter { get; } int Count { get; } + bool HasParams { get; } string ParameterName (int pos); string ParameterDesc (int pos); Parameter.Modifier ParameterModifier (int pos); + string GetSignatureForError (); } public class ReflectionParameters : ParameterData { ParameterInfo [] pi; + Type[] type_params; bool last_arg_is_params = false; + bool is_varargs = false; ParameterData gpd; - public ReflectionParameters (MethodBase method) + public ReflectionParameters (MethodBase mb) { object [] attrs; - this.pi = method.GetParameters (); + ParameterInfo [] pi = mb.GetParameters (); + is_varargs = (mb.CallingConvention & CallingConventions.VarArgs) != 0; + + this.pi = pi; int count = pi.Length-1; if (count < 0) return; - if (method.Mono_IsInflatedMethod) { - MethodInfo generic = method.GetGenericMethodDefinition (); - gpd = Invocation.GetParameterData (generic); + if (mb.Mono_IsInflatedMethod) { + MethodInfo generic = mb.GetGenericMethodDefinition (); + gpd = TypeManager.GetParameterData (generic); - last_arg_is_params = gpd.HasArrayParameter; + last_arg_is_params = gpd.HasParams; return; } + if (mb.IsGenericMethodDefinition) + type_params = mb.GetGenericArguments (); + attrs = pi [count].GetCustomAttributes (TypeManager.param_array_type, true); if (attrs == null) return; @@ -69,15 +69,30 @@ namespace Mono.CSharp { last_arg_is_params = true; } - - public bool HasArrayParameter { - get { return last_arg_is_params; } + + public string GetSignatureForError () + { + StringBuilder sb = new StringBuilder ("("); + for (int i = 0; i < pi.Length; ++i) { + if (i != 0) + sb.Append (", "); + sb.Append (ParameterDesc (i)); + } + if (is_varargs) { + if (pi.Length > 0) + sb.Append (", "); + sb.Append ("__arglist"); + } + sb.Append (')'); + return sb.ToString (); } public Type ParameterType (int pos) { 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; @@ -90,23 +105,30 @@ namespace Mono.CSharp { if (gpd != null) return gpd.GenericConstraints (pos); - Type t = ParameterType (pos); - if (!t.IsGenericParameter) + if (type_params == null) return null; - return ReflectionConstraints.Create (t); + return new ReflectionConstraints (type_params [pos]); } public string ParameterName (int pos) { + if (gpd != null) + return gpd.ParameterName (pos); + 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) @@ -123,8 +145,8 @@ namespace Mono.CSharp { if (pos >= pi.Length - 1 && last_arg_is_params) sb.Append ("params "); - - sb.Append (TypeManager.CSharpName (partype)); + + sb.Append (TypeManager.CSharpName (partype).Replace ("&", "")); return sb.ToString (); @@ -132,15 +154,17 @@ namespace Mono.CSharp { public Parameter.Modifier ParameterModifier (int pos) { - int len = pi.Length; - - if (pos >= len - 1) - if (last_arg_is_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; + if (gpd != null) + return gpd.ParameterModifier (pos); + Type t = pi [pos].ParameterType; if (t.IsByRef){ - if ((pi [pos].Attributes & ParameterAttributes.Out) != 0) + if ((pi [pos].Attributes & (ParameterAttributes.Out|ParameterAttributes.In)) == ParameterAttributes.Out) return Parameter.Modifier.ISBYREF | Parameter.Modifier.OUT; else return Parameter.Modifier.ISBYREF | Parameter.Modifier.REF; @@ -151,99 +175,55 @@ namespace Mono.CSharp { public int Count { get { - return pi.Length; + return is_varargs ? pi.Length + 1 : pi.Length; } } - protected class ReflectionConstraints : GenericConstraints - { - bool has_ctor; - bool is_reference_type; - bool is_value_type; - Type class_constraint; - Type[] iface_constraints; - - protected ReflectionConstraints (bool has_ctor, Type class_constr, - Type[] iface_constrs) - { - this.has_ctor = has_ctor; - this.class_constraint = class_constr; - this.iface_constraints = iface_constrs; - - if (class_constraint != null) { - if (class_constraint == TypeManager.object_type) - is_reference_type = true; - else if (class_constraint == TypeManager.value_type) - is_value_type = true; - } - } - - public static GenericConstraints Create (Type t) - { - Type class_constr = null; - Type[] iface_constrs = t.GetInterfaces (); - if (iface_constrs == null) - iface_constrs = Type.EmptyTypes; - if (t.BaseType != TypeManager.object_type) - class_constr = t.BaseType; - - return new ReflectionConstraints ( - false, class_constr, iface_constrs); - } - - public bool HasConstructor { - get { return has_ctor; } - } - - public bool HasClassConstraint { - get { return class_constraint != null; } - } - - public bool IsReferenceType { - get { return is_reference_type; } - } - - public bool IsValueType { - get { return is_value_type; } - } - - public Type ClassConstraint { - get { return class_constraint; } - } - - public Type[] InterfaceConstraints { - get { return iface_constraints; } + public bool HasParams { + get { + return this.last_arg_is_params; } } } public class InternalParameters : ParameterData { Type [] param_types; + bool has_varargs; + int count; public readonly Parameters Parameters; + public readonly TypeParameter[] TypeParameters; public InternalParameters (Type [] param_types, Parameters parameters) { this.param_types = param_types; this.Parameters = parameters; + + has_varargs = parameters.HasArglist; + + if (param_types == null) + count = 0; + else + count = param_types.Length; } - public InternalParameters (DeclSpace ds, Parameters parameters) - : this (parameters.GetParameterInfo (ds), parameters) + public InternalParameters (Type [] param_types, Parameters parameters, + TypeParameter [] type_params) + : this (param_types, parameters) { + this.TypeParameters = type_params; } public int Count { get { - if (param_types == null) - return 0; - - return param_types.Length; + return has_varargs ? count + 1 : count; } } - public bool HasArrayParameter { - get { return Parameters.ArrayParameter != null; } + public bool HasParams { + get { + return Parameters.ArrayParameter != null; + } } Parameter GetParameter (int pos) @@ -258,8 +238,28 @@ namespace Mono.CSharp { return Parameters.ArrayParameter; } + public string GetSignatureForError () + { + StringBuilder sb = new StringBuilder ("("); + for (int i = 0; i < count; ++i) { + if (i != 0) + sb.Append (", "); + sb.Append (ParameterDesc (i)); + } + if (has_varargs) { + if (count > 0) + sb.Append (", "); + sb.Append ("__arglist"); + } + sb.Append (')'); + return sb.ToString (); + } + public Type ParameterType (int pos) { + if (has_varargs && pos >= count) + return TypeManager.runtime_argument_handle_type; + if (param_types == null) return null; @@ -268,20 +268,31 @@ namespace Mono.CSharp { public GenericConstraints GenericConstraints (int pos) { - if (param_types == null) + if (TypeParameters == null) return null; - return GetParameter (pos).GenericConstraints; + return TypeParameters [pos].Constraints; } public string ParameterName (int pos) { + if (has_varargs && pos >= count) + return "__arglist"; + return GetParameter (pos).Name; } public string ParameterDesc (int pos) { - string tmp = String.Empty; + if (has_varargs && pos >= count) + return "__arglist"; + + Type t = ParameterType (pos); + return (ModifierDesc (pos) + " " + TypeManager.CSharpName (t).Replace ("&", "")).TrimStart (); + } + + public string ModifierDesc (int pos) + { Parameter p = GetParameter (pos); // @@ -289,19 +300,19 @@ namespace Mono.CSharp { // 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); + return "ref"; + if ((p.ModFlags & Parameter.Modifier.OUT) != 0) + return "out"; + if (p.ModFlags == Parameter.Modifier.PARAMS) + return "params"; + return ""; } 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) @@ -312,6 +323,55 @@ namespace Mono.CSharp { } + public class ReflectionConstraints : GenericConstraints + { + GenericParameterAttributes attrs; + Type base_type; + Type class_constraint; + Type[] iface_constraints; + string name; + + public ReflectionConstraints (Type t) + { + name = t.Name; + Type[] constraints = t.GetGenericParameterConstraints (); + if ((constraints.Length > 0) && !constraints [0].IsInterface) { + class_constraint = constraints [0]; + iface_constraints = new Type [constraints.Length - 1]; + Array.Copy (constraints, 1, iface_constraints, 0, constraints.Length - 1); + } else + iface_constraints = constraints; + attrs = t.GenericParameterAttributes; + + if (HasValueTypeConstraint) + base_type = TypeManager.value_type; + else if (class_constraint != null) + base_type = class_constraint; + else + base_type = TypeManager.object_type; + } + + public override string TypeParameter { + get { return name; } + } + + public override GenericParameterAttributes Attributes { + get { return attrs; } + } + + public override Type ClassConstraint { + get { return class_constraint; } + } + + public override Type EffectiveBaseClass { + get { return base_type; } + } + + public override Type[] InterfaceConstraints { + get { return iface_constraints; } + } + } + class PtrHashtable : Hashtable { sealed class PtrComparer : IComparer { private PtrComparer () {} @@ -376,29 +436,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; @@ -411,106 +448,67 @@ namespace Mono.CSharp { } /// - /// This is a wrapper around StreamReader which is seekable. + /// This is a wrapper around StreamReader which is seekable backwards + /// within a window of around 2048 chars. /// public class SeekableStreamReader { public SeekableStreamReader (StreamReader reader) { this.reader = reader; - this.buffer = new char [DefaultCacheSize]; - - // Compute the preamble size - + this.buffer = new char [AverageReadLength * 3]; + // Let the StreamWriter autodetect the encoder reader.Peek (); - - reader.BaseStream.Position = 0; - Encoding enc = reader.CurrentEncoding; - // First of all, get at least a char - - byte[] auxb = new byte [50]; - int num_bytes = 0; - int num_chars = 0; - int br = 0; - do { - br = reader.BaseStream.Read (auxb, num_bytes, auxb.Length - num_bytes); - num_bytes += br; - num_chars = enc.GetCharCount (auxb, 0, num_bytes); - } - while (num_chars == 0 && br > 0); - - if (num_chars != 0) - { - // Now, check which bytes at the beginning have no effect in the - // char count - - int p = 0; - while (enc.GetCharCount (auxb, p, num_bytes-p) >= num_chars) - p++; - - preamble_size = p - 1; - reader.BaseStream.Position = 0; - reader.DiscardBufferedData (); - - buffer_start = preamble_size; - } } - public SeekableStreamReader (Stream stream, Encoding encoding, bool detect_encoding_from_bytemarks) - : this (new StreamReader (stream, encoding, detect_encoding_from_bytemarks)) + public SeekableStreamReader (Stream stream, Encoding encoding) + : this (new StreamReader (stream, encoding, true)) { } StreamReader reader; - private const int DefaultCacheSize = 1024; + private const int AverageReadLength = 1024; char[] buffer; - int buffer_start; // in bytes - int buffer_size; // in bytes + int buffer_start; // in chars int char_count; // count buffer[] valid characters int pos; // index into buffer[] - int preamble_size; /// - /// The difference to the StreamReader's BaseStream.Position is that this one is reliable; ie. it - // always reports the correct position and if it's modified, it also takes care of the buffered data. + /// This value corresponds to the current position in a stream of characters. + /// The StreamReader hides its manipulation of the underlying byte stream and all + /// character set/decoding issues. Thus, we cannot use this position to guess at + /// the corresponding position in the underlying byte stream even though there is + /// a correlation between them. /// public int Position { - get { - return buffer_start + reader.CurrentEncoding.GetByteCount (buffer, 0, pos); - } + get { return buffer_start + pos; } set { - // This one is easy: we're modifying the position within our current - // buffer. - if ((value >= buffer_start) && (value < buffer_start + buffer_size)) { - int byte_offset = value - buffer_start; - pos = byte_offset; - // encoded characters can take more than 1 byte length - while (reader.CurrentEncoding.GetByteCount (buffer, 0, pos) > byte_offset) - pos--; - - return; - } - - if (value == 0) // Skip preamble - value = preamble_size; - - // Ok, now we need to seek. - reader.DiscardBufferedData (); - reader.BaseStream.Position = buffer_start = value; - char_count = buffer_size = pos = 0; + if (value < buffer_start || value > buffer_start + char_count) + throw new InternalErrorException ("can't seek that far back: " + (pos - value)); + pos = value - buffer_start; } } private bool ReadBuffer () { - pos = 0; - buffer_start += buffer_size; - char_count = reader.Read (buffer, 0, buffer.Length); - buffer_size = reader.CurrentEncoding.GetByteCount (buffer, 0, char_count); - return buffer_size > 0; + int slack = buffer.Length - char_count; + if (slack <= AverageReadLength / 2) { + // shift the buffer to make room for AverageReadLength number of characters + int shift = AverageReadLength - slack; + Array.Copy (buffer, shift, buffer, 0, char_count - shift); + pos -= shift; + char_count -= shift; + buffer_start += shift; + slack += shift; // slack == AverageReadLength + } + + int chars_read = reader.Read (buffer, char_count, slack); + char_count += chars_read; + + return pos < char_count; } public int Peek ()