X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;ds=sidebyside;f=mcs%2Fgmcs%2Fsupport.cs;h=328fbbeea7e1d5931cbab066838ee21a9c27d1ad;hb=33828ad95f877e3e5ae6bac604a2db3760b8ea7b;hp=f3e6941700d7b47c9a1cd464076ae2961ff480e5;hpb=5048ba327ef9e7f188d053585e3228f2afcb36af;p=mono.git diff --git a/mcs/gmcs/support.cs b/mcs/gmcs/support.cs old mode 100755 new mode 100644 index f3e6941700d..328fbbeea7e --- a/mcs/gmcs/support.cs +++ b/mcs/gmcs/support.cs @@ -21,11 +21,12 @@ namespace Mono.CSharp { 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 { @@ -50,9 +51,9 @@ namespace Mono.CSharp { if (mb.Mono_IsInflatedMethod) { MethodInfo generic = mb.GetGenericMethodDefinition (); - gpd = Invocation.GetParameterData (generic); + gpd = TypeManager.GetParameterData (generic); - last_arg_is_params = gpd.HasArrayParameter; + last_arg_is_params = gpd.HasParams; return; } @@ -68,9 +69,22 @@ 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) @@ -99,6 +113,9 @@ namespace Mono.CSharp { 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) @@ -128,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 (); @@ -137,16 +154,17 @@ namespace Mono.CSharp { public Parameter.Modifier ParameterModifier (int pos) { - int len = pi.Length; - 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; @@ -160,6 +178,12 @@ namespace Mono.CSharp { return is_varargs ? pi.Length + 1 : pi.Length; } } + + public bool HasParams { + get { + return this.last_arg_is_params; + } + } } public class InternalParameters : ParameterData { @@ -196,8 +220,10 @@ namespace Mono.CSharp { } } - public bool HasArrayParameter { - get { return Parameters.ArrayParameter != null; } + public bool HasParams { + get { + return Parameters.ArrayParameter != null; + } } Parameter GetParameter (int pos) @@ -212,6 +238,23 @@ 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) @@ -244,7 +287,12 @@ namespace Mono.CSharp { if (has_varargs && pos >= count) return "__arglist"; - string tmp = String.Empty; + Type t = ParameterType (pos); + return (ModifierDesc (pos) + " " + TypeManager.CSharpName (t).Replace ("&", "")).TrimStart (); + } + + public string ModifierDesc (int pos) + { Parameter p = GetParameter (pos); // @@ -252,15 +300,12 @@ 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) @@ -284,9 +329,11 @@ namespace Mono.CSharp { 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]; @@ -304,6 +351,10 @@ namespace Mono.CSharp { base_type = TypeManager.object_type; } + public override string TypeParameter { + get { return name; } + } + public override GenericParameterAttributes Attributes { get { return attrs; } } @@ -397,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 ()