X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fsupport.cs;h=b31507195d77b7604c1adb14513bfdf3d6566d64;hb=0c2bb8157f43826a57c39b863a1d67e3aef1b7b2;hp=78b4870c10ae40b74a7ef5ebe10be7734c094593;hpb=64afc10a1fc9a248d13ac78d0e3d1534d45d30d3;p=mono.git diff --git a/mcs/mcs/support.cs b/mcs/mcs/support.cs index 78b4870c10a..b31507195d7 100644 --- a/mcs/mcs/support.cs +++ b/mcs/mcs/support.cs @@ -5,7 +5,8 @@ // 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; @@ -18,310 +19,12 @@ using System.Globalization; namespace Mono.CSharp { - public interface ParameterData { - Type ParameterType (int pos); - Type [] Types { get; } - int Count { get; } - Type ExtensionMethodType { get; } - bool HasParams { get; } - string ParameterName (int pos); - string ParameterDesc (int pos); - - Parameter.Modifier ParameterModifier (int pos); - string GetSignatureForError (); - -#if MS_COMPATIBLE - void InflateTypes (Type[] genArguments, Type[] argTypes); -#endif - } - - public class ReflectionParameters : ParameterData { - ParameterInfo [] pi; - Type [] types; - int params_idx = -1; - bool is_varargs; - bool is_extension; - ParameterData gpd; - - public ReflectionParameters (MethodBase mb) - { - ParameterInfo [] pi = mb.GetParameters (); - is_varargs = (mb.CallingConvention & CallingConventions.VarArgs) != 0; - - this.pi = pi; - int count = pi.Length; - - if (count == 0) { - types = Type.EmptyTypes; - return; - } - - types = new Type [count]; - for (int i = 0; i < count; i++) - types [i] = pi [i].ParameterType; - - // TODO: This (if) should be done one level higher to correctly use - // out caching facilities. - MethodBase generic = TypeManager.DropGenericMethodArguments (mb); - if (generic != mb) { - gpd = TypeManager.GetParameterData (generic); - if (gpd.HasParams) { - for (int i = gpd.Count; i != 0; --i) { - if ((gpd.ParameterModifier (i-1) & Parameter.Modifier.PARAMS) != 0) { - this.params_idx = i-1; - break; - } - } - } - return; - } - - // - // So far, the params attribute can be used in C# for the last - // and next to last method parameters. - // If some other language can place it anywhere we will - // have to analyze all parameters and not just last 2. - // - --count; - for (int i = count; i >= 0 && i > count - 2; --i) { - if (!pi [i].ParameterType.IsArray) - continue; - - if (pi [i].IsDefined (TypeManager.param_array_type, false)) { - params_idx = i; - return; - } - } - - if (TypeManager.extension_attribute_type != null && mb.IsStatic && - (mb.DeclaringType.Attributes & Class.StaticClassAttribute) == Class.StaticClassAttribute && - mb.IsDefined (TypeManager.extension_attribute_type, false)) - is_extension = true; - } - - public override bool Equals (object obj) - { - ReflectionParameters rp = obj as ReflectionParameters; - if (rp == null) - return false; - - if (Count != rp.Count) - return false; - - for (int i = 0; i < Count; ++i) { - if (!types [i].Equals (rp.types [i])) - return false; - } - return true; - } - - public override int GetHashCode () - { - return base.GetHashCode (); - } - - 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 (); - } - -#if MS_COMPATIBLE - public void InflateTypes (Type[] genArguments, Type[] argTypes) - { - for (int i = 0; i < types.Length; ++i) { - if (types[i].IsGenericParameter) { - for (int ii = 0; ii < genArguments.Length; ++ii) { - if (types[i] != genArguments[ii]) - continue; - - types[i] = argTypes[ii]; - break; - } - continue; - } - - if (types[i].IsGenericType) { - Type[] gen_arguments_open = types[i].GetGenericTypeDefinition ().GetGenericArguments (); - Type[] gen_arguments = types[i].GetGenericArguments (); - for (int ii = 0; ii < gen_arguments_open.Length; ++ii) { - if (gen_arguments[ii].IsGenericParameter) - gen_arguments_open[ii] = argTypes[gen_arguments_open[ii].GenericParameterPosition]; - else - gen_arguments_open[ii] = gen_arguments[ii]; - } - - types[i] = types[i].GetGenericTypeDefinition ().MakeGenericType (gen_arguments_open); - } - } - } + class PtrHashtable : Hashtable { + sealed class PtrComparer : IComparer +#if NET_2_0 + , IEqualityComparer #endif - - public Type ParameterType (int pos) - { - if (is_varargs && pos >= pi.Length) - return TypeManager.runtime_argument_handle_type; - - return types [pos]; - } - - public string ParameterName (int pos) { - if (gpd != null) - return gpd.ParameterName (pos); - - if (is_varargs && pos >= pi.Length) - return "__arglist"; - - return pi [pos].Name; - } - - 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 (params_idx == pos) - sb.Append ("params "); - - if (pos == 0 && ExtensionMethodType != null) - sb.Append ("this "); - - sb.Append (TypeManager.CSharpName (partype).Replace ("&", "")); - - return sb.ToString (); - } - - public Parameter.Modifier ParameterModifier (int pos) - { - if (pos == params_idx) - return Parameter.Modifier.PARAMS; - else if (is_varargs && pos >= pi.Length) - return Parameter.Modifier.ARGLIST; - - if (gpd != null) - return gpd.ParameterModifier (pos); - - Type t = types [pos]; - 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; - } - - public int Count { - get { return is_varargs ? pi.Length + 1 : pi.Length; } - } - - public Type ExtensionMethodType { - get { - if (!is_extension) - return null; - - return types [0]; - } - } - - public bool HasParams { - get { return params_idx != -1; } - } - - public Type[] Types { - get { return types; } - } - } - -#if GMCS_SOURCE - public class ReflectionConstraints : GenericConstraints - { - 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) - { - 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; } - } - } -#endif - - class PtrHashtable : Hashtable { - sealed class PtrComparer : IComparer { private PtrComparer () {} public static PtrComparer Instance = new PtrComparer (); @@ -333,12 +36,42 @@ namespace Mono.CSharp { 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 PtrHashtable () +#if NET_2_0 + public PtrHashtable () : base (PtrComparer.Instance) {} +#else + public PtrHashtable () { comparer = PtrComparer.Instance; } +#endif + +#if MS_COMPATIBLE + // + // Workaround System.InvalidOperationException for enums + // + protected override int GetHash (object key) + { + TypeBuilder tb = key as TypeBuilder; + if (tb != null && tb.BaseType == TypeManager.enum_type && tb.BaseType != null) + key = tb.BaseType; + + return base.GetHash (key); + } +#endif } /* @@ -410,33 +143,44 @@ namespace Mono.CSharp { } /// - /// This is a wrapper around StreamReader which is seekable backwards - /// within a window of around 2048 chars. + /// 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 { - public SeekableStreamReader (TextReader reader) - { - this.reader = reader; - this.buffer = new char [AverageReadLength * 3]; - - // Let the StreamWriter autodetect the encoder - reader.Peek (); - } - - public SeekableStreamReader (Stream stream, Encoding encoding) - : this (new StreamReader (stream, encoding, true)) - { } + const int default_average_read_length = 1024; + const int buffer_read_length_spans = 3; TextReader reader; - - private const int AverageReadLength = 1024; + 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 SeekableStreamReader (Stream stream, Encoding encoding) + { + this.stream = stream; + this.encoding = encoding; + + ResetStream (default_average_read_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 @@ -448,8 +192,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) + 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; } } @@ -457,18 +209,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; } @@ -571,4 +322,137 @@ namespace Mono.CSharp { } } } + + 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 override object [] GetCustomAttributes (bool inherit) + { + throw new NotImplementedException (); + } + + public override Type ReturnType { + get { + return mc.MemberType; + } + } + + public override bool IsDefined (Type attributeType, bool inherit) + { + throw new NotImplementedException (); + } + + public override string Name + { + get { return mc.Name; } + } + + public override Type ReflectedType + { + get { throw new NotImplementedException (); } + } + } + + 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; + } + } + } }