2 // support.cs: Support routines to work around the fact that System.Reflection.Emit
3 // can not introspect types that are being constructed
6 // Miguel de Icaza (miguel@ximian.com)
8 // Copyright 2001 Ximian, Inc (http://www.ximian.com)
9 // Copyright 2003-2008 Novell, Inc
15 using System.Reflection;
16 using System.Collections;
17 using System.Reflection.Emit;
18 using System.Globalization;
20 namespace Mono.CSharp {
23 public class ReflectionConstraints : GenericConstraints
25 GenericParameterAttributes attrs;
27 Type class_constraint;
28 Type[] iface_constraints;
31 public static GenericConstraints GetConstraints (Type t)
33 Type [] constraints = t.GetGenericParameterConstraints ();
34 GenericParameterAttributes attrs = t.GenericParameterAttributes;
35 if (constraints.Length == 0 && attrs == GenericParameterAttributes.None)
37 return new ReflectionConstraints (t.Name, constraints, attrs);
40 private ReflectionConstraints (string name, Type [] constraints, GenericParameterAttributes attrs)
45 if ((constraints.Length > 0) && !constraints [0].IsInterface) {
46 class_constraint = constraints [0];
47 iface_constraints = new Type [constraints.Length - 1];
48 Array.Copy (constraints, 1, iface_constraints, 0, constraints.Length - 1);
50 iface_constraints = constraints;
52 if (HasValueTypeConstraint)
53 base_type = TypeManager.value_type;
54 else if (class_constraint != null)
55 base_type = class_constraint;
57 base_type = TypeManager.object_type;
60 public override string TypeParameter {
64 public override GenericParameterAttributes Attributes {
68 public override Type ClassConstraint {
69 get { return class_constraint; }
72 public override Type EffectiveBaseClass {
73 get { return base_type; }
76 public override Type[] InterfaceConstraints {
77 get { return iface_constraints; }
82 class PtrHashtable : Hashtable {
83 sealed class PtrComparer : IComparer
88 private PtrComparer () {}
90 public static PtrComparer Instance = new PtrComparer ();
92 public int Compare (object x, object y)
100 bool IEqualityComparer.Equals (object x, object y)
105 int IEqualityComparer.GetHashCode (object obj)
107 return obj.GetHashCode ();
114 public PtrHashtable () : base (PtrComparer.Instance) {}
116 public PtrHashtable ()
118 comparer = PtrComparer.Instance;
124 // Workaround System.InvalidOperationException for enums
126 protected override int GetHash (object key)
128 TypeBuilder tb = key as TypeBuilder;
129 if (tb != null && tb.BaseType == TypeManager.enum_type)
132 return base.GetHash (key);
138 * Hashtable whose keys are character arrays with the same length
140 class CharArrayHashtable : Hashtable {
141 sealed class ArrComparer : IComparer {
144 public ArrComparer (int len) {
148 public int Compare (object x, object y)
150 char[] a = (char[])x;
151 char[] b = (char[])y;
153 for (int i = 0; i < len; ++i)
162 protected override int GetHash (Object key)
164 char[] arr = (char[])key;
167 for (int i = 0; i < len; ++i)
168 h = (h << 5) - h + arr [i];
173 public CharArrayHashtable (int len)
176 comparer = new ArrComparer (len);
182 public object Second;
184 public Pair (object f, object s)
191 public class Accessors {
192 public Accessor get_or_add;
193 public Accessor set_or_remove;
195 // was 'set' declared before 'get'? was 'remove' declared before 'add'?
196 public bool declared_in_reverse;
198 public Accessors (Accessor get_or_add, Accessor set_or_remove)
200 this.get_or_add = get_or_add;
201 this.set_or_remove = set_or_remove;
206 /// This is a wrapper around StreamReader which is seekable backwards
207 /// within a window of around 2048 chars.
209 public class SeekableStreamReader
211 const int AverageReadLength = 1024;
217 int buffer_start; // in chars
218 int char_count; // count buffer[] valid characters
219 int pos; // index into buffer[]
221 public SeekableStreamReader (Stream stream, Encoding encoding)
223 this.stream = stream;
224 this.encoding = encoding;
226 this.reader = new StreamReader (stream, encoding, true);
227 this.buffer = new char [AverageReadLength * 3];
229 // Let the StreamWriter autodetect the encoder
234 /// This value corresponds to the current position in a stream of characters.
235 /// The StreamReader hides its manipulation of the underlying byte stream and all
236 /// character set/decoding issues. Thus, we cannot use this position to guess at
237 /// the corresponding position in the underlying byte stream even though there is
238 /// a correlation between them.
240 public int Position {
241 get { return buffer_start + pos; }
244 if (value > buffer_start + char_count)
245 throw new InternalErrorException ("can't seek that far forward: " + (pos - value));
247 if (value < buffer_start){
250 reader = new StreamReader (stream, encoding, true);
256 while (value > buffer_start + char_count){
260 pos = value - buffer_start;
263 pos = value - buffer_start;
267 private bool ReadBuffer ()
269 int slack = buffer.Length - char_count;
270 if (slack <= AverageReadLength / 2) {
271 // shift the buffer to make room for AverageReadLength number of characters
272 int shift = AverageReadLength - slack;
273 Array.Copy (buffer, shift, buffer, 0, char_count - shift);
276 buffer_start += shift;
277 slack += shift; // slack == AverageReadLength
280 int chars_read = reader.Read (buffer, char_count, slack);
281 char_count += chars_read;
283 return pos < char_count;
288 if ((pos >= char_count) && !ReadBuffer ())
296 if ((pos >= char_count) && !ReadBuffer ())
299 return buffer [pos++];
303 public class DoubleHash {
304 const int DEFAULT_INITIAL_BUCKETS = 100;
306 public DoubleHash () : this (DEFAULT_INITIAL_BUCKETS) {}
308 public DoubleHash (int size)
311 buckets = new Entry [size];
325 public Entry (object key1, object key2, int hash, object value, Entry next)
335 public bool Lookup (object a, object b, out object res)
337 int h = (a.GetHashCode () ^ b.GetHashCode ()) & 0x7FFFFFFF;
339 for (Entry e = buckets [h % count]; e != null; e = e.next) {
340 if (e.hash == h && e.key1.Equals (a) && e.key2.Equals (b)) {
349 public void Insert (object a, object b, object value)
351 // Is it an existing one?
353 int h = (a.GetHashCode () ^ b.GetHashCode ()) & 0x7FFFFFFF;
355 for (Entry e = buckets [h % count]; e != null; e = e.next) {
356 if (e.hash == h && e.key1.Equals (a) && e.key2.Equals (b))
360 int bucket = h % count;
361 buckets [bucket] = new Entry (a, b, h, value, buckets [bucket]);
363 // Grow whenever we double in size
364 if (size++ == count) {
368 Entry [] newBuckets = new Entry [count];
369 foreach (Entry root in buckets) {
372 int newLoc = e.hash % count;
374 e.next = newBuckets [newLoc];
375 newBuckets [newLoc] = e;
380 buckets = newBuckets;
385 class PartialMethodDefinitionInfo : MethodInfo
388 MethodAttributes attrs;
390 public PartialMethodDefinitionInfo (MethodOrOperator mc)
393 if ((mc.ModFlags & Modifiers.STATIC) != 0)
394 attrs = MethodAttributes.Static;
397 public override MethodInfo GetBaseDefinition ()
399 throw new NotImplementedException ();
402 public override ICustomAttributeProvider ReturnTypeCustomAttributes
404 get { throw new NotImplementedException (); }
407 public override MethodAttributes Attributes
409 get { return attrs; }
412 public override MethodImplAttributes GetMethodImplementationFlags ()
414 throw new NotImplementedException ();
417 public override ParameterInfo [] GetParameters ()
419 throw new NotImplementedException ();
422 public override object Invoke (object obj, BindingFlags invokeAttr, Binder binder, object [] parameters, CultureInfo culture)
424 throw new NotImplementedException ();
427 public override RuntimeMethodHandle MethodHandle
429 get { throw new NotImplementedException (); }
432 public override Type DeclaringType
434 get { return mc.Parent.TypeBuilder; }
437 public override object [] GetCustomAttributes (Type attributeType, bool inherit)
439 throw new NotImplementedException ();
442 public override object [] GetCustomAttributes (bool inherit)
444 throw new NotImplementedException ();
447 public override Type ReturnType {
449 return mc.MemberType;
453 public override bool IsDefined (Type attributeType, bool inherit)
455 throw new NotImplementedException ();
458 public override string Name
460 get { return mc.Name; }
463 public override Type ReflectedType
465 get { throw new NotImplementedException (); }
469 public class UnixUtils {
470 [System.Runtime.InteropServices.DllImport ("libc", EntryPoint="isatty")]
471 extern static int _isatty (int fd);
473 public static bool isatty (int fd)
476 return _isatty (fd) == 1;