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 (); }
410 class DynamicType
: Type
412 public override Assembly Assembly
{
413 get { return UnderlyingSystemType.Assembly; }
416 public override string AssemblyQualifiedName
{
417 get { throw new NotImplementedException (); }
420 public override Type BaseType
{
424 public override string FullName
{
425 get { return UnderlyingSystemType.FullName; }
428 public override Guid GUID
{
429 get { throw new NotImplementedException (); }
432 protected override TypeAttributes
GetAttributeFlagsImpl ()
434 return UnderlyingSystemType
.Attributes
;
437 protected override ConstructorInfo
GetConstructorImpl (BindingFlags bindingAttr
, Binder binder
, CallingConventions callConvention
, Type
[] types
, ParameterModifier
[] modifiers
)
439 throw new NotImplementedException ();
442 public override ConstructorInfo
[] GetConstructors (BindingFlags bindingAttr
)
444 throw new NotImplementedException ();
447 public override Type
GetElementType ()
449 throw new NotImplementedException ();
452 public override EventInfo
GetEvent (string name
, BindingFlags bindingAttr
)
454 throw new NotImplementedException ();
457 public override EventInfo
[] GetEvents (BindingFlags bindingAttr
)
459 throw new NotImplementedException ();
462 public override FieldInfo
GetField (string name
, BindingFlags bindingAttr
)
464 throw new NotImplementedException ();
467 public override FieldInfo
[] GetFields (BindingFlags bindingAttr
)
469 throw new NotImplementedException ();
472 public override Type
GetInterface (string name
, bool ignoreCase
)
474 throw new NotImplementedException ();
477 public override Type
[] GetInterfaces ()
479 throw new NotImplementedException ();
482 public override MemberInfo
[] GetMembers (BindingFlags bindingAttr
)
484 throw new NotImplementedException ();
487 protected override MethodInfo
GetMethodImpl (string name
, BindingFlags bindingAttr
, Binder binder
, CallingConventions callConvention
, Type
[] types
, ParameterModifier
[] modifiers
)
489 throw new NotImplementedException ();
492 public override MethodInfo
[] GetMethods (BindingFlags bindingAttr
)
494 throw new NotImplementedException ();
497 public override Type
GetNestedType (string name
, BindingFlags bindingAttr
)
499 throw new NotImplementedException ();
502 public override Type
[] GetNestedTypes (BindingFlags bindingAttr
)
504 throw new NotImplementedException ();
507 public override PropertyInfo
[] GetProperties (BindingFlags bindingAttr
)
509 throw new NotImplementedException ();
512 protected override PropertyInfo
GetPropertyImpl (string name
, BindingFlags bindingAttr
, Binder binder
, Type returnType
, Type
[] types
, ParameterModifier
[] modifiers
)
514 throw new NotImplementedException ();
517 protected override bool HasElementTypeImpl ()
519 throw new NotImplementedException ();
522 public override object InvokeMember (string name
, BindingFlags invokeAttr
, Binder binder
, object target
, object[] args
, ParameterModifier
[] modifiers
, System
.Globalization
.CultureInfo culture
, string[] namedParameters
)
524 throw new NotImplementedException ();
527 protected override bool IsArrayImpl ()
532 protected override bool IsByRefImpl ()
537 protected override bool IsCOMObjectImpl ()
542 protected override bool IsPointerImpl ()
547 protected override bool IsPrimitiveImpl ()
552 public override Module Module
{
553 get { return UnderlyingSystemType.Module; }
556 public override string Namespace
{
557 get { throw new NotImplementedException (); }
560 public override Type UnderlyingSystemType
{
561 get { return TypeManager.object_type; }
564 public override object[] GetCustomAttributes (Type attributeType
, bool inherit
)
566 return new object [0];
569 public override object[] GetCustomAttributes (bool inherit
)
571 return new object [0];
574 public override bool IsDefined (Type attributeType
, bool inherit
)
576 throw new NotImplementedException ();
579 public override string Name
{
580 get { return UnderlyingSystemType.Name; }
583 public override string ToString ()
585 return GetType ().ToString ();
588 public override RuntimeTypeHandle TypeHandle
{
589 get { return UnderlyingSystemType.TypeHandle; }
593 public class UnixUtils
{
594 [System
.Runtime
.InteropServices
.DllImport ("libc", EntryPoint
="isatty")]
595 extern static int _isatty (int fd
);
597 public static bool isatty (int fd
)
600 return _isatty (fd
) == 1;
608 /// An exception used to terminate the compiler resolution phase and provide completions
611 /// This is thrown when we want to return the completions or
612 /// terminate the completion process by AST nodes used in
613 /// the completion process.
615 public class CompletionResult
: Exception
{
619 public CompletionResult (string base_text
, string [] res
)
621 if (base_text
== null)
622 throw new ArgumentNullException ("base_text");
623 this.base_text
= base_text
;
629 public string [] Result
{
635 public string BaseText
{