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
, IEqualityComparer
25 private PtrComparer () {}
27 public static PtrComparer Instance
= new PtrComparer ();
29 public int Compare (object x
, object y
)
37 bool IEqualityComparer
.Equals (object x
, object y
)
42 int IEqualityComparer
.GetHashCode (object obj
)
44 return obj
.GetHashCode ();
48 public PtrHashtable () : base (PtrComparer
.Instance
) {}
52 // Workaround System.InvalidOperationException for enums
54 protected override int GetHash (object key
)
56 TypeBuilder tb
= key
as TypeBuilder
;
57 if (tb
!= null && tb
.BaseType
== TypeManager
.enum_type
&& tb
.BaseType
!= null)
60 return base.GetHash (key
);
66 * Hashtable whose keys are character arrays with the same length
68 class CharArrayHashtable
: Hashtable
{
69 sealed class ArrComparer
: IComparer
{
72 public ArrComparer (int len
) {
76 public int Compare (object x
, object y
)
81 for (int i
= 0; i
< len
; ++i
)
90 protected override int GetHash (Object key
)
92 char[] arr
= (char[])key
;
95 for (int i
= 0; i
< len
; ++i
)
96 h
= (h
<< 5) - h
+ arr
[i
];
101 public CharArrayHashtable (int len
)
104 comparer
= new ArrComparer (len
);
110 public object Second
;
112 public Pair (object f
, object s
)
119 public class Accessors
{
120 public Accessor get_or_add
;
121 public Accessor set_or_remove
;
123 // was 'set' declared before 'get'? was 'remove' declared before 'add'?
124 public bool declared_in_reverse
;
126 public Accessors (Accessor get_or_add
, Accessor set_or_remove
)
128 this.get_or_add
= get_or_add
;
129 this.set_or_remove
= set_or_remove
;
134 /// This is an arbitrarily seekable StreamReader wrapper.
136 /// It uses a self-tuning buffer to cache the seekable data,
137 /// but if the seek is too far, it may read the underly
138 /// stream all over from the beginning.
140 public class SeekableStreamReader
142 const int default_average_read_length
= 1024;
143 const int buffer_read_length_spans
= 3;
150 int average_read_length
;
151 int buffer_start
; // in chars
152 int char_count
; // count buffer[] valid characters
153 int pos
; // index into buffer[]
155 void ResetStream (int read_length_inc
)
157 average_read_length
+= read_length_inc
;
159 reader
= new StreamReader (stream
, encoding
, true);
160 buffer
= new char [average_read_length
* buffer_read_length_spans
];
161 buffer_start
= char_count
= pos
= 0;
164 public SeekableStreamReader (Stream stream
, Encoding encoding
)
166 this.stream
= stream
;
167 this.encoding
= encoding
;
169 ResetStream (default_average_read_length
);
173 /// This value corresponds to the current position in a stream of characters.
174 /// The StreamReader hides its manipulation of the underlying byte stream and all
175 /// character set/decoding issues. Thus, we cannot use this position to guess at
176 /// the corresponding position in the underlying byte stream even though there is
177 /// a correlation between them.
179 public int Position
{
180 get { return buffer_start + pos; }
183 // If the lookahead was too small, re-read from the beginning. Increase the buffer size while we're at it
184 if (value < buffer_start
)
185 ResetStream (average_read_length
/ 2);
187 while (value > buffer_start
+ char_count
) {
190 throw new InternalErrorException ("Seek beyond end of file: " + (buffer_start
+ char_count
- value));
193 pos
= value - buffer_start
;
197 private bool ReadBuffer ()
199 int slack
= buffer
.Length
- char_count
;
200 if (slack
<= average_read_length
/ 2) {
201 // shift the buffer to make room for average_read_length number of characters
202 int shift
= average_read_length
- slack
;
203 Array
.Copy (buffer
, shift
, buffer
, 0, char_count
- shift
);
206 buffer_start
+= shift
;
207 slack
+= shift
; // slack == average_read_length
210 char_count
+= reader
.Read (buffer
, char_count
, slack
);
212 return pos
< char_count
;
217 if ((pos
>= char_count
) && !ReadBuffer ())
225 if ((pos
>= char_count
) && !ReadBuffer ())
228 return buffer
[pos
++];
232 public class DoubleHash
{
233 const int DEFAULT_INITIAL_BUCKETS
= 100;
235 public DoubleHash () : this (DEFAULT_INITIAL_BUCKETS
) {}
237 public DoubleHash (int size
)
240 buckets
= new Entry
[size
];
254 public Entry (object key1
, object key2
, int hash
, object value, Entry next
)
264 public bool Lookup (object a
, object b
, out object res
)
266 int h
= (a
.GetHashCode () ^ b
.GetHashCode ()) & 0x7FFFFFFF;
268 for (Entry e
= buckets
[h
% count
]; e
!= null; e
= e
.next
) {
269 if (e
.hash
== h
&& e
.key1
.Equals (a
) && e
.key2
.Equals (b
)) {
278 public void Insert (object a
, object b
, object value)
280 // Is it an existing one?
282 int h
= (a
.GetHashCode () ^ b
.GetHashCode ()) & 0x7FFFFFFF;
284 for (Entry e
= buckets
[h
% count
]; e
!= null; e
= e
.next
) {
285 if (e
.hash
== h
&& e
.key1
.Equals (a
) && e
.key2
.Equals (b
))
289 int bucket
= h
% count
;
290 buckets
[bucket
] = new Entry (a
, b
, h
, value, buckets
[bucket
]);
292 // Grow whenever we double in size
293 if (size
++ == count
) {
297 Entry
[] newBuckets
= new Entry
[count
];
298 foreach (Entry root
in buckets
) {
301 int newLoc
= e
.hash
% count
;
303 e
.next
= newBuckets
[newLoc
];
304 newBuckets
[newLoc
] = e
;
309 buckets
= newBuckets
;
314 class PartialMethodDefinitionInfo
: MethodInfo
317 MethodAttributes attrs
;
319 public PartialMethodDefinitionInfo (MethodOrOperator mc
)
322 if ((mc
.ModFlags
& Modifiers
.STATIC
) != 0)
323 attrs
= MethodAttributes
.Static
;
326 public override MethodInfo
GetBaseDefinition ()
328 throw new NotImplementedException ();
331 public override ICustomAttributeProvider ReturnTypeCustomAttributes
333 get { throw new NotImplementedException (); }
336 public override MethodAttributes Attributes
338 get { return attrs; }
341 public override MethodImplAttributes
GetMethodImplementationFlags ()
343 throw new NotImplementedException ();
346 public override ParameterInfo
[] GetParameters ()
348 throw new NotImplementedException ();
351 public override object Invoke (object obj
, BindingFlags invokeAttr
, Binder binder
, object [] parameters
, CultureInfo culture
)
353 throw new NotImplementedException ();
356 public override RuntimeMethodHandle MethodHandle
358 get { throw new NotImplementedException (); }
361 public override Type DeclaringType
363 get { return mc.Parent.TypeBuilder; }
366 public override object [] GetCustomAttributes (Type attributeType
, bool inherit
)
368 throw new NotImplementedException ();
371 public override object [] GetCustomAttributes (bool inherit
)
373 throw new NotImplementedException ();
376 public override Type ReturnType
{
378 return mc
.MemberType
;
382 public override bool IsDefined (Type attributeType
, bool inherit
)
384 throw new NotImplementedException ();
387 public override string Name
389 get { return mc.Name; }
392 public override Type ReflectedType
394 get { throw new NotImplementedException (); }
398 #if NET_4_0 || MS_COMPATIBLE
399 [System
.Diagnostics
.DebuggerDisplay ("Dynamic type")]
401 class DynamicType
: Type
403 public override Assembly Assembly
{
404 get { return UnderlyingSystemType.Assembly; }
407 public override string AssemblyQualifiedName
{
408 get { throw new NotImplementedException (); }
411 public override Type BaseType
{
415 public override string FullName
{
416 get { return UnderlyingSystemType.FullName; }
419 public override Guid GUID
{
420 get { throw new NotImplementedException (); }
423 protected override TypeAttributes
GetAttributeFlagsImpl ()
425 return UnderlyingSystemType
.Attributes
;
428 protected override ConstructorInfo
GetConstructorImpl (BindingFlags bindingAttr
, Binder binder
, CallingConventions callConvention
, Type
[] types
, ParameterModifier
[] modifiers
)
430 throw new NotImplementedException ();
433 public override ConstructorInfo
[] GetConstructors (BindingFlags bindingAttr
)
435 throw new NotImplementedException ();
438 public override Type
GetElementType ()
440 throw new NotImplementedException ();
443 public override EventInfo
GetEvent (string name
, BindingFlags bindingAttr
)
445 throw new NotImplementedException ();
448 public override EventInfo
[] GetEvents (BindingFlags bindingAttr
)
450 throw new NotImplementedException ();
453 public override FieldInfo
GetField (string name
, BindingFlags bindingAttr
)
455 throw new NotImplementedException ();
458 public override FieldInfo
[] GetFields (BindingFlags bindingAttr
)
460 throw new NotImplementedException ();
463 public override Type
GetInterface (string name
, bool ignoreCase
)
465 throw new NotImplementedException ();
468 public override Type
[] GetInterfaces ()
470 return Type
.EmptyTypes
;
473 public override MemberInfo
[] GetMembers (BindingFlags bindingAttr
)
475 throw new NotImplementedException ();
478 protected override MethodInfo
GetMethodImpl (string name
, BindingFlags bindingAttr
, Binder binder
, CallingConventions callConvention
, Type
[] types
, ParameterModifier
[] modifiers
)
480 throw new NotImplementedException ();
483 public override MethodInfo
[] GetMethods (BindingFlags bindingAttr
)
485 throw new NotImplementedException ();
488 public override Type
GetNestedType (string name
, BindingFlags bindingAttr
)
490 throw new NotImplementedException ();
493 public override Type
[] GetNestedTypes (BindingFlags bindingAttr
)
495 throw new NotImplementedException ();
498 public override PropertyInfo
[] GetProperties (BindingFlags bindingAttr
)
500 throw new NotImplementedException ();
503 protected override PropertyInfo
GetPropertyImpl (string name
, BindingFlags bindingAttr
, Binder binder
, Type returnType
, Type
[] types
, ParameterModifier
[] modifiers
)
505 throw new NotImplementedException ();
508 protected override bool HasElementTypeImpl ()
513 public override object InvokeMember (string name
, BindingFlags invokeAttr
, Binder binder
, object target
, object[] args
, ParameterModifier
[] modifiers
, System
.Globalization
.CultureInfo culture
, string[] namedParameters
)
515 throw new NotImplementedException ();
518 protected override bool IsArrayImpl ()
523 protected override bool IsByRefImpl ()
528 protected override bool IsCOMObjectImpl ()
533 protected override bool IsPointerImpl ()
538 protected override bool IsPrimitiveImpl ()
543 public override Module Module
{
544 get { return UnderlyingSystemType.Module; }
547 public override string Namespace
{
548 get { return UnderlyingSystemType.Namespace; }
551 public override Type UnderlyingSystemType
{
552 get { return TypeManager.object_type; }
555 public override object[] GetCustomAttributes (Type attributeType
, bool inherit
)
557 return new object [0];
560 public override object[] GetCustomAttributes (bool inherit
)
562 return new object [0];
565 public override bool IsDefined (Type attributeType
, bool inherit
)
567 throw new NotImplementedException ();
570 public override string Name
{
571 get { return UnderlyingSystemType.Name; }
574 public override string ToString ()
576 return UnderlyingSystemType
.ToString ();
579 public override RuntimeTypeHandle TypeHandle
{
580 get { return UnderlyingSystemType.TypeHandle; }
583 public override Type
MakeByRefType ()
585 // TODO: Wrong, hides dynamic type
586 return UnderlyingSystemType
.MakeByRefType ();
590 public class UnixUtils
{
591 [System
.Runtime
.InteropServices
.DllImport ("libc", EntryPoint
="isatty")]
592 extern static int _isatty (int fd
);
594 public static bool isatty (int fd
)
597 return _isatty (fd
) == 1;
605 /// An exception used to terminate the compiler resolution phase and provide completions
608 /// This is thrown when we want to return the completions or
609 /// terminate the completion process by AST nodes used in
610 /// the completion process.
612 public class CompletionResult
: Exception
{
616 public CompletionResult (string base_text
, string [] res
)
618 if (base_text
== null)
619 throw new ArgumentNullException ("base_text");
620 this.base_text
= base_text
;
626 public string [] Result
{
632 public string BaseText
{