X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fsupport.cs;h=8fcb5bf6081b058042eb984fdb684167c9412570;hb=b7dc3a9663532553ea61bcaee3b41bc808617829;hp=74b81a5f8dbd28eb5287745a05079318f4a245f6;hpb=af90548a08ef5effc93b083b7eec44daa178b141;p=mono.git diff --git a/mcs/mcs/support.cs b/mcs/mcs/support.cs index 74b81a5f8db..8fcb5bf6081 100644 --- a/mcs/mcs/support.cs +++ b/mcs/mcs/support.cs @@ -4,343 +4,137 @@ // // Author: // Miguel de Icaza (miguel@ximian.com) +// Marek Safar (marek.safar@gmail.com) // -// (C) 2001 Ximian, Inc (http://www.ximian.com) +// Copyright 2001 Ximian, Inc (http://www.ximian.com) +// Copyright 2003-2009 Novell, Inc // using System; using System.IO; using System.Text; using System.Reflection; -using System.Collections; using System.Reflection.Emit; using System.Globalization; +using System.Collections.Generic; namespace Mono.CSharp { - public interface ParameterData { - Type ParameterType (int pos); - Type [] Types { 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 [] types; - bool last_arg_is_params = false; - bool is_varargs = false; - ParameterData gpd; + sealed class ReferenceEquality : IEqualityComparer where T : class + { + public static readonly IEqualityComparer Default = new ReferenceEquality (); - public ReflectionParameters (MethodBase mb) + private ReferenceEquality () { - object [] attrs; - - ParameterInfo [] pi = mb.GetParameters (); - is_varargs = (mb.CallingConvention & CallingConventions.VarArgs) != 0; - - this.pi = pi; - int count = pi.Length-1; - - if (pi.Length == 0) { - types = Type.EmptyTypes; - } else { - types = new Type [pi.Length]; - for (int i = 0; i < pi.Length; i++) - types [i] = pi [i].ParameterType; - } - - if (count < 0) - return; - - MethodBase generic = TypeManager.DropGenericMethodArguments (mb); - if (generic != mb) { - gpd = TypeManager.GetParameterData (generic); - last_arg_is_params = gpd.HasParams; - return; - } - - attrs = pi [count].GetCustomAttributes (TypeManager.param_array_type, true); - if (attrs == null) - return; - - if (attrs.Length == 0) - return; - - last_arg_is_params = true; } - public string GetSignatureForError () + public bool Equals (T x, T y) { - 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 (); + return ReferenceEquals (x, y); } - public Type ParameterType (int pos) + public int GetHashCode (T obj) { - 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; - - return t; - } + return System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode (obj); } + } - public string ParameterName (int pos) + class Tuple : IEquatable> + { + public Tuple (T1 item1, T2 item2) { - 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; + Item1 = item1; + Item2 = item2; } - public string ParameterDesc (int pos) - { - if (is_varargs && pos >= pi.Length) - return ""; - - StringBuilder sb = new StringBuilder (); - - if (pi [pos].IsIn) - sb.Append ("in "); - - Type partype = ParameterType (pos); - if (partype.IsByRef){ - partype = TypeManager.GetElementType (partype); - if (pi [pos].IsOut) - sb.Append ("out "); - else - sb.Append ("ref "); - } - - if (pos >= pi.Length - 1 && last_arg_is_params) - sb.Append ("params "); - - sb.Append (TypeManager.CSharpName (partype).Replace ("&", "")); + public T1 Item1 { get; private set; } + public T2 Item2 { get; private set; } - return sb.ToString (); - } - - public Parameter.Modifier ParameterModifier (int pos) + public override int GetHashCode () { - 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|ParameterAttributes.In)) == ParameterAttributes.Out) - return Parameter.Modifier.OUT; - else - return Parameter.Modifier.REF; - } - - return Parameter.Modifier.NONE; + return Item1.GetHashCode () ^ Item2.GetHashCode (); } - public int Count { - get { return is_varargs ? pi.Length + 1 : pi.Length; } - } + #region IEquatable> Members - public bool HasParams { - get { return last_arg_is_params; } + public bool Equals (Tuple other) + { + return EqualityComparer.Default.Equals (Item1, other.Item1) && + EqualityComparer.Default.Equals (Item2, other.Item2); } - public Type[] Types { - get { return types; } - } + #endregion } -#if GMCS_SOURCE - public class ReflectionConstraints : GenericConstraints + static class Tuple { - GenericParameterAttributes attrs; - Type base_type; - Type class_constraint; - Type[] iface_constraints; - string name; - - public static GenericConstraints GetConstraints (Type t) - { - Type [] constraints = t.GetGenericParameterConstraints (); - GenericParameterAttributes attrs = t.GenericParameterAttributes; - if (constraints.Length == 0 && attrs == GenericParameterAttributes.None) - return null; - return new ReflectionConstraints (t.Name, constraints, attrs); - } - - private ReflectionConstraints (string name, Type [] constraints, GenericParameterAttributes attrs) + public static Tuple Create (T1 item1, T2 item2) { - this.name = name; - this.attrs = attrs; - - 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; - - 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; } + return new Tuple (item1, item2); } } -#endif - - class PtrHashtable : Hashtable { - sealed class PtrComparer : IComparer { - private PtrComparer () {} - public static PtrComparer Instance = new PtrComparer (); + public class Accessors { + public Accessor get_or_add; + public Accessor set_or_remove; - public int Compare (object x, object y) - { - if (x == y) - return 0; - else - return 1; - } - } + // was 'set' declared before 'get'? was 'remove' declared before 'add'? + public bool declared_in_reverse; - public PtrHashtable () + public Accessors (Accessor get_or_add, Accessor set_or_remove) { - comparer = PtrComparer.Instance; + this.get_or_add = get_or_add; + this.set_or_remove = set_or_remove; } } - /* - * Hashtable whose keys are character arrays with the same length - */ - class CharArrayHashtable : Hashtable { - sealed class ArrComparer : IComparer { - private int len; - - public ArrComparer (int len) { - this.len = len; - } + /// + /// This is an arbitrarily seekable StreamReader wrapper. + /// + /// It uses a self-tuning buffer to cache the seekable data, + /// but if the seek is too far, it may read the underly + /// stream all over from the beginning. + /// + public class SeekableStreamReader : IDisposable + { + const int buffer_read_length_spans = 3; - public int Compare (object x, object y) - { - char[] a = (char[])x; - char[] b = (char[])y; + TextReader reader; + Stream stream; - for (int i = 0; i < len; ++i) - if (a [i] != b [i]) - return 1; - return 0; - } - } - - private int len; + static char[] buffer; + int average_read_length; + int buffer_start; // in chars + int char_count; // count buffer[] valid characters + int pos; // index into buffer[] - protected override int GetHash (Object key) + public SeekableStreamReader (Stream stream, Encoding encoding) { - char[] arr = (char[])key; - int h = 0; + this.stream = stream; - for (int i = 0; i < len; ++i) - h = (h << 5) - h + arr [i]; - - return h; + const int default_average_read_length = 1024; + InitializeStream (default_average_read_length); + reader = new StreamReader (stream, encoding, true); } - public CharArrayHashtable (int len) + public void Dispose () { - this.len = len; - comparer = new ArrComparer (len); + // Needed to release stream reader buffers + reader.Dispose (); } - } - - struct Pair { - public object First; - public object Second; - public Pair (object f, object s) + void InitializeStream (int read_length_inc) { - First = f; - Second = s; - } - } + average_read_length += read_length_inc; - /// - /// 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 [AverageReadLength * 3]; + int required_buffer_size = average_read_length * buffer_read_length_spans; + if (buffer == null || buffer.Length < required_buffer_size) + buffer = new char [required_buffer_size]; - // Let the StreamWriter autodetect the encoder - reader.Peek (); + stream.Position = 0; + buffer_start = char_count = pos = 0; } - public SeekableStreamReader (Stream stream, Encoding encoding) - : this (new StreamReader (stream, encoding, true)) - { } - - StreamReader reader; - - private const int AverageReadLength = 1024; - - char[] buffer; - int buffer_start; // in chars - int char_count; // count buffer[] valid characters - int pos; // index into buffer[] - /// /// This value corresponds to the current position in a stream of characters. /// The StreamReader hides its manipulation of the underlying byte stream and all @@ -352,8 +146,16 @@ namespace Mono.CSharp { get { return buffer_start + pos; } set { - if (value < buffer_start || value > buffer_start + char_count) - throw new InternalErrorException ("can't seek that far back: " + (pos - value)); + // If the lookahead was too small, re-read from the beginning. Increase the buffer size while we're at it + if (value < buffer_start) + InitializeStream (average_read_length / 2); + + while (value > buffer_start + char_count) { + pos = char_count; + if (!ReadBuffer ()) + throw new InternalErrorException ("Seek beyond end of file: " + (buffer_start + char_count - value)); + } + pos = value - buffer_start; } } @@ -361,18 +163,17 @@ namespace Mono.CSharp { private bool ReadBuffer () { 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; + if (slack <= average_read_length / 2) { + // shift the buffer to make room for average_read_length number of characters + int shift = average_read_length - slack; Array.Copy (buffer, shift, buffer, 0, char_count - shift); pos -= shift; char_count -= shift; buffer_start += shift; - slack += shift; // slack == AverageReadLength + slack += shift; // slack == average_read_length } - int chars_read = reader.Read (buffer, char_count, slack); - char_count += chars_read; + char_count += reader.Read (buffer, char_count, slack); return pos < char_count; } @@ -475,4 +276,53 @@ namespace Mono.CSharp { } } } + + public class UnixUtils { + [System.Runtime.InteropServices.DllImport ("libc", EntryPoint="isatty")] + extern static int _isatty (int fd); + + public static bool isatty (int fd) + { + try { + return _isatty (fd) == 1; + } catch { + return false; + } + } + } + + /// + /// An exception used to terminate the compiler resolution phase and provide completions + /// + /// + /// This is thrown when we want to return the completions or + /// terminate the completion process by AST nodes used in + /// the completion process. + /// + public class CompletionResult : Exception { + string [] result; + string base_text; + + public CompletionResult (string base_text, string [] res) + { + if (base_text == null) + throw new ArgumentNullException ("base_text"); + this.base_text = base_text; + + result = res; + Array.Sort (result); + } + + public string [] Result { + get { + return result; + } + } + + public string BaseText { + get { + return base_text; + } + } + } }