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 {
22 class PtrHashtable : Hashtable {
23 sealed class PtrComparer : IComparer
28 private PtrComparer () {}
30 public static PtrComparer Instance = new PtrComparer ();
32 public int Compare (object x, object y)
40 bool IEqualityComparer.Equals (object x, object y)
45 int IEqualityComparer.GetHashCode (object obj)
47 return obj.GetHashCode ();
54 public PtrHashtable () : base (PtrComparer.Instance) {}
56 public PtrHashtable ()
58 comparer = PtrComparer.Instance;
64 // Workaround System.InvalidOperationException for enums
66 protected override int GetHash (object key)
68 TypeBuilder tb = key as TypeBuilder;
69 if (tb != null && tb.BaseType == TypeManager.enum_type && tb.BaseType != null)
72 return base.GetHash (key);
78 * Hashtable whose keys are character arrays with the same length
80 class CharArrayHashtable : Hashtable {
81 sealed class ArrComparer : IComparer {
84 public ArrComparer (int len) {
88 public int Compare (object x, object y)
93 for (int i = 0; i < len; ++i)
102 protected override int GetHash (Object key)
104 char[] arr = (char[])key;
107 for (int i = 0; i < len; ++i)
108 h = (h << 5) - h + arr [i];
113 public CharArrayHashtable (int len)
116 comparer = new ArrComparer (len);
122 public object Second;
124 public Pair (object f, object s)
131 public class Accessors {
132 public Accessor get_or_add;
133 public Accessor set_or_remove;
135 // was 'set' declared before 'get'? was 'remove' declared before 'add'?
136 public bool declared_in_reverse;
138 public Accessors (Accessor get_or_add, Accessor set_or_remove)
140 this.get_or_add = get_or_add;
141 this.set_or_remove = set_or_remove;
146 /// This is an arbitrarily seekable StreamReader wrapper.
148 /// It uses a self-tuning buffer to cache the seekable data,
149 /// but if the seek is too far, it may read the underly
150 /// stream all over from the beginning.
152 public class SeekableStreamReader
154 const int default_average_read_length = 1024;
155 const int buffer_read_length_spans = 3;
162 int average_read_length;
163 int buffer_start; // in chars
164 int char_count; // count buffer[] valid characters
165 int pos; // index into buffer[]
167 void ResetStream (int read_length_inc)
169 average_read_length += read_length_inc;
171 reader = new StreamReader (stream, encoding, true);
172 buffer = new char [average_read_length * buffer_read_length_spans];
173 buffer_start = char_count = pos = 0;
176 public SeekableStreamReader (Stream stream, Encoding encoding)
178 this.stream = stream;
179 this.encoding = encoding;
181 ResetStream (default_average_read_length);
185 /// This value corresponds to the current position in a stream of characters.
186 /// The StreamReader hides its manipulation of the underlying byte stream and all
187 /// character set/decoding issues. Thus, we cannot use this position to guess at
188 /// the corresponding position in the underlying byte stream even though there is
189 /// a correlation between them.
191 public int Position {
192 get { return buffer_start + pos; }
195 // If the lookahead was too small, re-read from the beginning. Increase the buffer size while we're at it
196 if (value < buffer_start)
197 ResetStream (average_read_length / 2);
199 while (value > buffer_start + char_count) {
202 throw new InternalErrorException ("Seek beyond end of file: " + (buffer_start + char_count - value));
205 pos = value - buffer_start;
209 private bool ReadBuffer ()
211 int slack = buffer.Length - char_count;
212 if (slack <= average_read_length / 2) {
213 // shift the buffer to make room for average_read_length number of characters
214 int shift = average_read_length - slack;
215 Array.Copy (buffer, shift, buffer, 0, char_count - shift);
218 buffer_start += shift;
219 slack += shift; // slack == average_read_length
222 char_count += reader.Read (buffer, char_count, slack);
224 return pos < char_count;
229 if ((pos >= char_count) && !ReadBuffer ())
237 if ((pos >= char_count) && !ReadBuffer ())
240 return buffer [pos++];
244 public class DoubleHash {
245 const int DEFAULT_INITIAL_BUCKETS = 100;
247 public DoubleHash () : this (DEFAULT_INITIAL_BUCKETS) {}
249 public DoubleHash (int size)
252 buckets = new Entry [size];
266 public Entry (object key1, object key2, int hash, object value, Entry next)
276 public bool Lookup (object a, object b, out object res)
278 int h = (a.GetHashCode () ^ b.GetHashCode ()) & 0x7FFFFFFF;
280 for (Entry e = buckets [h % count]; e != null; e = e.next) {
281 if (e.hash == h && e.key1.Equals (a) && e.key2.Equals (b)) {
290 public void Insert (object a, object b, object value)
292 // Is it an existing one?
294 int h = (a.GetHashCode () ^ b.GetHashCode ()) & 0x7FFFFFFF;
296 for (Entry e = buckets [h % count]; e != null; e = e.next) {
297 if (e.hash == h && e.key1.Equals (a) && e.key2.Equals (b))
301 int bucket = h % count;
302 buckets [bucket] = new Entry (a, b, h, value, buckets [bucket]);
304 // Grow whenever we double in size
305 if (size++ == count) {
309 Entry [] newBuckets = new Entry [count];
310 foreach (Entry root in buckets) {
313 int newLoc = e.hash % count;
315 e.next = newBuckets [newLoc];
316 newBuckets [newLoc] = e;
321 buckets = newBuckets;
326 class PartialMethodDefinitionInfo : MethodInfo
329 MethodAttributes attrs;
331 public PartialMethodDefinitionInfo (MethodOrOperator mc)
334 if ((mc.ModFlags & Modifiers.STATIC) != 0)
335 attrs = MethodAttributes.Static;
338 public override MethodInfo GetBaseDefinition ()
340 throw new NotImplementedException ();
343 public override ICustomAttributeProvider ReturnTypeCustomAttributes
345 get { throw new NotImplementedException (); }
348 public override MethodAttributes Attributes
350 get { return attrs; }
353 public override MethodImplAttributes GetMethodImplementationFlags ()
355 throw new NotImplementedException ();
358 public override ParameterInfo [] GetParameters ()
360 throw new NotImplementedException ();
363 public override object Invoke (object obj, BindingFlags invokeAttr, Binder binder, object [] parameters, CultureInfo culture)
365 throw new NotImplementedException ();
368 public override RuntimeMethodHandle MethodHandle
370 get { throw new NotImplementedException (); }
373 public override Type DeclaringType
375 get { return mc.Parent.TypeBuilder; }
378 public override object [] GetCustomAttributes (Type attributeType, bool inherit)
380 throw new NotImplementedException ();
383 public override object [] GetCustomAttributes (bool inherit)
385 throw new NotImplementedException ();
388 public override Type ReturnType {
390 return mc.MemberType;
394 public override bool IsDefined (Type attributeType, bool inherit)
396 throw new NotImplementedException ();
399 public override string Name
401 get { return mc.Name; }
404 public override Type ReflectedType
406 get { throw new NotImplementedException (); }
411 [System.Diagnostics.DebuggerDisplay ("Dynamic type")]
413 class DynamicType : Type
415 public override Assembly Assembly {
416 get { return UnderlyingSystemType.Assembly; }
419 public override string AssemblyQualifiedName {
420 get { throw new NotImplementedException (); }
423 public override Type BaseType {
427 public override string FullName {
428 get { return UnderlyingSystemType.FullName; }
431 public override Guid GUID {
432 get { throw new NotImplementedException (); }
435 protected override TypeAttributes GetAttributeFlagsImpl ()
437 return UnderlyingSystemType.Attributes;
440 protected override ConstructorInfo GetConstructorImpl (BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
442 throw new NotImplementedException ();
445 public override ConstructorInfo[] GetConstructors (BindingFlags bindingAttr)
447 throw new NotImplementedException ();
450 public override Type GetElementType ()
452 throw new NotImplementedException ();
455 public override EventInfo GetEvent (string name, BindingFlags bindingAttr)
457 throw new NotImplementedException ();
460 public override EventInfo[] GetEvents (BindingFlags bindingAttr)
462 throw new NotImplementedException ();
465 public override FieldInfo GetField (string name, BindingFlags bindingAttr)
467 throw new NotImplementedException ();
470 public override FieldInfo[] GetFields (BindingFlags bindingAttr)
472 throw new NotImplementedException ();
475 public override Type GetInterface (string name, bool ignoreCase)
477 throw new NotImplementedException ();
480 public override Type[] GetInterfaces ()
482 throw new NotImplementedException ();
485 public override MemberInfo[] GetMembers (BindingFlags bindingAttr)
487 throw new NotImplementedException ();
490 protected override MethodInfo GetMethodImpl (string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
492 throw new NotImplementedException ();
495 public override MethodInfo[] GetMethods (BindingFlags bindingAttr)
497 throw new NotImplementedException ();
500 public override Type GetNestedType (string name, BindingFlags bindingAttr)
502 throw new NotImplementedException ();
505 public override Type[] GetNestedTypes (BindingFlags bindingAttr)
507 throw new NotImplementedException ();
510 public override PropertyInfo[] GetProperties (BindingFlags bindingAttr)
512 throw new NotImplementedException ();
515 protected override PropertyInfo GetPropertyImpl (string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers)
517 throw new NotImplementedException ();
520 protected override bool HasElementTypeImpl ()
522 throw new NotImplementedException ();
525 public override object InvokeMember (string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, ParameterModifier[] modifiers, System.Globalization.CultureInfo culture, string[] namedParameters)
527 throw new NotImplementedException ();
530 protected override bool IsArrayImpl ()
535 protected override bool IsByRefImpl ()
540 protected override bool IsCOMObjectImpl ()
545 protected override bool IsPointerImpl ()
550 protected override bool IsPrimitiveImpl ()
555 public override Module Module {
556 get { return UnderlyingSystemType.Module; }
559 public override string Namespace {
560 get { throw new NotImplementedException (); }
563 public override Type UnderlyingSystemType {
564 get { return TypeManager.object_type; }
567 public override object[] GetCustomAttributes (Type attributeType, bool inherit)
569 return new object [0];
572 public override object[] GetCustomAttributes (bool inherit)
574 return new object [0];
577 public override bool IsDefined (Type attributeType, bool inherit)
579 throw new NotImplementedException ();
582 public override string Name {
583 get { return UnderlyingSystemType.Name; }
586 public override string ToString ()
588 return UnderlyingSystemType.ToString ();
591 public override RuntimeTypeHandle TypeHandle {
592 get { return UnderlyingSystemType.TypeHandle; }
596 public class UnixUtils {
597 [System.Runtime.InteropServices.DllImport ("libc", EntryPoint="isatty")]
598 extern static int _isatty (int fd);
600 public static bool isatty (int fd)
603 return _isatty (fd) == 1;
611 /// An exception used to terminate the compiler resolution phase and provide completions
614 /// This is thrown when we want to return the completions or
615 /// terminate the completion process by AST nodes used in
616 /// the completion process.
618 public class CompletionResult : Exception {
622 public CompletionResult (string base_text, string [] res)
624 if (base_text == null)
625 throw new ArgumentNullException ("base_text");
626 this.base_text = base_text;
632 public string [] Result {
638 public string BaseText {