X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fsupport.cs;h=b31507195d77b7604c1adb14513bfdf3d6566d64;hb=0c2bb8157f43826a57c39b863a1d67e3aef1b7b2;hp=d24e4f5c2793458b113bf9cd7ffdf1c73f76f956;hpb=2db597d2a1263e0a8409036f8c9baa05cc11199b;p=mono.git diff --git a/mcs/mcs/support.cs b/mcs/mcs/support.cs old mode 100755 new mode 100644 index d24e4f5c279..b31507195d7 --- a/mcs/mcs/support.cs +++ b/mcs/mcs/support.cs @@ -5,216 +5,454 @@ // Author: // Miguel de Icaza (miguel@ximian.com) // -// (C) 2001 Ximian, Inc (http://www.ximian.com) +// Copyright 2001 Ximian, Inc (http://www.ximian.com) +// Copyright 2003-2008 Novell, Inc // using System; +using System.IO; using System.Text; using System.Reflection; using System.Collections; using System.Reflection.Emit; +using System.Globalization; namespace Mono.CSharp { - public interface ParameterData { - Type ParameterType (int pos); - int Count { get; } - string ParameterDesc (int pos); - Parameter.Modifier ParameterModifier (int pos); - } - - public class ReflectionParameters : ParameterData { - ParameterInfo [] pi; - bool last_arg_is_params; - - public ReflectionParameters (ParameterInfo [] pi) + class PtrHashtable : Hashtable { + sealed class PtrComparer : IComparer +#if NET_2_0 + , IEqualityComparer +#endif { - object [] a; - - this.pi = pi; + private PtrComparer () {} - int count = pi.Length-1; + public static PtrComparer Instance = new PtrComparer (); - if (count > 0) { - a = pi [count].GetCustomAttributes (TypeManager.param_array_type, false); - - if (a != null) - if (a.Length != 0) - last_arg_is_params = true; - } + public int Compare (object x, object y) + { + if (x == y) + return 0; + else + return 1; + } +#if NET_2_0 + bool IEqualityComparer.Equals (object x, object y) + { + return x == y; + } + + int IEqualityComparer.GetHashCode (object obj) + { + return obj.GetHashCode (); + } +#endif + } - - public Type ParameterType (int pos) + +#if NET_2_0 + public PtrHashtable () : base (PtrComparer.Instance) {} +#else + public PtrHashtable () { - if (last_arg_is_params && pos >= pi.Length - 1) - return pi [pi.Length -1].ParameterType.GetElementType (); - else - return pi [pos].ParameterType; + comparer = PtrComparer.Instance; } +#endif - public string ParameterDesc (int pos) +#if MS_COMPATIBLE + // + // Workaround System.InvalidOperationException for enums + // + protected override int GetHash (object key) { - StringBuilder sb = new StringBuilder (); + TypeBuilder tb = key as TypeBuilder; + if (tb != null && tb.BaseType == TypeManager.enum_type && tb.BaseType != null) + key = tb.BaseType; - if (pi [pos].IsOut) - sb.Append ("out "); + return base.GetHash (key); + } +#endif + } - if (pi [pos].IsIn) - sb.Append ("in "); + /* + * Hashtable whose keys are character arrays with the same length + */ + class CharArrayHashtable : Hashtable { + sealed class ArrComparer : IComparer { + private int len; - if (pos == pi.Length - 1) - sb.Append ("params "); - - sb.Append (TypeManager.CSharpName (ParameterType (pos))); + public ArrComparer (int len) { + this.len = len; + } - return sb.ToString (); - + public int Compare (object x, object y) + { + char[] a = (char[])x; + char[] b = (char[])y; + + for (int i = 0; i < len; ++i) + if (a [i] != b [i]) + return 1; + return 0; + } } - public Parameter.Modifier ParameterModifier (int pos) + private int len; + + protected override int GetHash (Object key) { - if (pos >= pi.Length - 1) - if (last_arg_is_params) - return Parameter.Modifier.PARAMS; + char[] arr = (char[])key; + int h = 0; - if (pi [pos].IsOut) - return Parameter.Modifier.OUT; - - return Parameter.Modifier.NONE; + for (int i = 0; i < len; ++i) + h = (h << 5) - h + arr [i]; + + return h; } - public int Count { - get { - return pi.Length; - } + public CharArrayHashtable (int len) + { + this.len = len; + comparer = new ArrComparer (len); } - } - public class InternalParameters : ParameterData { - Type [] param_types; + struct Pair { + public object First; + public object Second; - Parameters parameters; - - public InternalParameters (Type [] param_types, Parameters parameters) + public Pair (object f, object s) + { + First = f; + Second = s; + } + } + + public class Accessors { + public Accessor get_or_add; + public Accessor set_or_remove; + + // was 'set' declared before 'get'? was 'remove' declared before 'add'? + public bool declared_in_reverse; + + public Accessors (Accessor get_or_add, Accessor set_or_remove) { - this.param_types = param_types; - this.parameters = parameters; + this.get_or_add = get_or_add; + this.set_or_remove = set_or_remove; } + } - public InternalParameters (TypeContainer tc, Parameters parameters) - : this (parameters.GetParameterInfo (tc), parameters) + /// + /// 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 + { + const int default_average_read_length = 1024; + const int buffer_read_length_spans = 3; + + TextReader reader; + Stream stream; + Encoding encoding; + + char[] buffer; + int average_read_length; + int buffer_start; // in chars + int char_count; // count buffer[] valid characters + int pos; // index into buffer[] + + void ResetStream (int read_length_inc) { + average_read_length += read_length_inc; + stream.Position = 0; + reader = new StreamReader (stream, encoding, true); + buffer = new char [average_read_length * buffer_read_length_spans]; + buffer_start = char_count = pos = 0; } - public int Count { - get { - if (param_types == null) - return 0; + public SeekableStreamReader (Stream stream, Encoding encoding) + { + this.stream = stream; + this.encoding = encoding; + + ResetStream (default_average_read_length); + } - return param_types.Length; + /// + /// 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 + pos; } + + set { + // If the lookahead was too small, re-read from the beginning. Increase the buffer size while we're at it + if (value < buffer_start) + ResetStream (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; } } - public Type ParameterType (int pos) + private bool ReadBuffer () { - if (param_types == null) - return null; + int slack = buffer.Length - char_count; + 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 == average_read_length + } - int len = parameters.FixedParameters.Length; + char_count += reader.Read (buffer, char_count, slack); - if (pos < len) - return parameters.FixedParameters [pos].ParameterType; - else - return parameters.ArrayParameter.ParameterType.GetElementType (); + return pos < char_count; + } + public int Peek () + { + if ((pos >= char_count) && !ReadBuffer ()) + return -1; - // - // Return the internal type. - // - //return p.ParameterType; + return buffer [pos]; } - public string ParameterDesc (int pos) + public int Read () { - string tmp = null; - Parameter p; + if ((pos >= char_count) && !ReadBuffer ()) + return -1; - if (pos >= parameters.FixedParameters.Length) - p = parameters.ArrayParameter; - else - p = parameters.FixedParameters [pos]; - - if (p.ModFlags == Parameter.Modifier.REF) - tmp = "ref "; - else if (p.ModFlags == Parameter.Modifier.OUT) - tmp = "out "; - else if (p.ModFlags == Parameter.Modifier.PARAMS) - tmp = "params "; + return buffer [pos++]; + } + } - Type t = ParameterType (pos); + public class DoubleHash { + const int DEFAULT_INITIAL_BUCKETS = 100; - return tmp + TypeManager.CSharpName (t); - } + public DoubleHash () : this (DEFAULT_INITIAL_BUCKETS) {} - public Parameter.Modifier ParameterModifier (int pos) + public DoubleHash (int size) { - if (pos >= parameters.FixedParameters.Length) - return parameters.ArrayParameter.ModFlags; - else - return parameters.FixedParameters [pos].ModFlags; + count = size; + buckets = new Entry [size]; } - - } - class PtrHashtable : Hashtable { - class PtrComparer : IComparer { - public int Compare (object x, object y) + int count; + Entry [] buckets; + int size = 0; + + class Entry { + public object key1; + public object key2; + public int hash; + public object value; + public Entry next; + + public Entry (object key1, object key2, int hash, object value, Entry next) { - if (x == y) - return 0; - else - return 1; + this.key1 = key1; + this.key2 = key2; + this.hash = hash; + this.next = next; + this.value = value; } } - - public PtrHashtable () + + public bool Lookup (object a, object b, out object res) { - comparer = new PtrComparer (); + int h = (a.GetHashCode () ^ b.GetHashCode ()) & 0x7FFFFFFF; + + for (Entry e = buckets [h % count]; e != null; e = e.next) { + if (e.hash == h && e.key1.Equals (a) && e.key2.Equals (b)) { + res = e.value; + return true; + } + } + res = null; + return false; + } + + public void Insert (object a, object b, object value) + { + // Is it an existing one? + + int h = (a.GetHashCode () ^ b.GetHashCode ()) & 0x7FFFFFFF; + + for (Entry e = buckets [h % count]; e != null; e = e.next) { + if (e.hash == h && e.key1.Equals (a) && e.key2.Equals (b)) + e.value = value; + } + + int bucket = h % count; + buckets [bucket] = new Entry (a, b, h, value, buckets [bucket]); + + // Grow whenever we double in size + if (size++ == count) { + count <<= 1; + count ++; + + Entry [] newBuckets = new Entry [count]; + foreach (Entry root in buckets) { + Entry e = root; + while (e != null) { + int newLoc = e.hash % count; + Entry n = e.next; + e.next = newBuckets [newLoc]; + newBuckets [newLoc] = e; + e = n; + } + } + + buckets = newBuckets; + } } } - // - // Compares member infos based on their name and - // also allows one argument to be a string - // - class MemberInfoCompare : IComparer { + class PartialMethodDefinitionInfo : MethodInfo + { + MethodOrOperator mc; + MethodAttributes attrs; + + public PartialMethodDefinitionInfo (MethodOrOperator mc) + { + this.mc = mc; + if ((mc.ModFlags & Modifiers.STATIC) != 0) + attrs = MethodAttributes.Static; + } + + public override MethodInfo GetBaseDefinition () + { + throw new NotImplementedException (); + } + + public override ICustomAttributeProvider ReturnTypeCustomAttributes + { + get { throw new NotImplementedException (); } + } + + public override MethodAttributes Attributes + { + get { return attrs; } + } + + public override MethodImplAttributes GetMethodImplementationFlags () + { + throw new NotImplementedException (); + } + + public override ParameterInfo [] GetParameters () + { + throw new NotImplementedException (); + } + + public override object Invoke (object obj, BindingFlags invokeAttr, Binder binder, object [] parameters, CultureInfo culture) + { + throw new NotImplementedException (); + } + + public override RuntimeMethodHandle MethodHandle + { + get { throw new NotImplementedException (); } + } + + public override Type DeclaringType + { + get { return mc.Parent.TypeBuilder; } + } + + public override object [] GetCustomAttributes (Type attributeType, bool inherit) + { + throw new NotImplementedException (); + } - public int Compare (object a, object b) + public override object [] GetCustomAttributes (bool inherit) { - if (a == null || b == null){ - Console.WriteLine ("Invalid information passed"); - throw new Exception (); + throw new NotImplementedException (); + } + + public override Type ReturnType { + get { + return mc.MemberType; } - - if (a is string) - return String.Compare ((string) a, ((MemberInfo)b).Name); + } - if (b is string) - return String.Compare (((MemberInfo)a).Name, (string) b); + public override bool IsDefined (Type attributeType, bool inherit) + { + throw new NotImplementedException (); + } - return String.Compare (((MemberInfo)a).Name, ((MemberInfo)b).Name); + public override string Name + { + get { return mc.Name; } + } + + public override Type ReflectedType + { + get { throw new NotImplementedException (); } } } - struct Pair { - public object First; - public object Second; + 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 Pair (object f, object s) - { - First = f; - Second = s; + 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; + } + } } }