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)
7 // Marek Safar (marek.safar@gmail.com)
9 // Copyright 2001 Ximian, Inc (http://www.ximian.com)
10 // Copyright 2003-2009 Novell, Inc
16 using System
.Reflection
;
17 using System
.Reflection
.Emit
;
18 using System
.Globalization
;
19 using System
.Collections
.Generic
;
21 namespace Mono
.CSharp
{
23 class ReferenceEquality
<T
> : IEqualityComparer
<T
> where T
: class
25 public static readonly IEqualityComparer
<T
> Default
= new ReferenceEquality
<T
> ();
27 private ReferenceEquality ()
31 public bool Equals (T x
, T y
)
33 return object.ReferenceEquals (x
, y
);
36 public int GetHashCode (T obj
)
38 return obj
== null ? 0 : obj
.GetHashCode ();
44 public Tuple (T1 item1
, T2 item2
)
50 public T1 Item1 { get; private set; }
51 public T2 Item2 { get; private set; }
54 public class Accessors
{
55 public Accessor get_or_add
;
56 public Accessor set_or_remove
;
58 // was 'set' declared before 'get'? was 'remove' declared before 'add'?
59 public bool declared_in_reverse
;
61 public Accessors (Accessor get_or_add
, Accessor set_or_remove
)
63 this.get_or_add
= get_or_add
;
64 this.set_or_remove
= set_or_remove
;
69 /// This is an arbitrarily seekable StreamReader wrapper.
71 /// It uses a self-tuning buffer to cache the seekable data,
72 /// but if the seek is too far, it may read the underly
73 /// stream all over from the beginning.
75 public class SeekableStreamReader
: IDisposable
77 const int buffer_read_length_spans
= 3;
83 int average_read_length
;
84 int buffer_start
; // in chars
85 int char_count
; // count buffer[] valid characters
86 int pos
; // index into buffer[]
88 public SeekableStreamReader (Stream stream
, Encoding encoding
)
92 const int default_average_read_length
= 1024;
93 InitializeStream (default_average_read_length
);
94 reader
= new StreamReader (stream
, encoding
, true);
97 public void Dispose ()
99 // Needed to release stream reader buffers
103 void InitializeStream (int read_length_inc
)
105 average_read_length
+= read_length_inc
;
107 int required_buffer_size
= average_read_length
* buffer_read_length_spans
;
108 if (buffer
== null || buffer
.Length
< required_buffer_size
)
109 buffer
= new char [required_buffer_size
];
112 buffer_start
= char_count
= pos
= 0;
116 /// This value corresponds to the current position in a stream of characters.
117 /// The StreamReader hides its manipulation of the underlying byte stream and all
118 /// character set/decoding issues. Thus, we cannot use this position to guess at
119 /// the corresponding position in the underlying byte stream even though there is
120 /// a correlation between them.
122 public int Position
{
123 get { return buffer_start + pos; }
126 // If the lookahead was too small, re-read from the beginning. Increase the buffer size while we're at it
127 if (value < buffer_start
)
128 InitializeStream (average_read_length
/ 2);
130 while (value > buffer_start
+ char_count
) {
133 throw new InternalErrorException ("Seek beyond end of file: " + (buffer_start
+ char_count
- value));
136 pos
= value - buffer_start
;
140 private bool ReadBuffer ()
142 int slack
= buffer
.Length
- char_count
;
143 if (slack
<= average_read_length
/ 2) {
144 // shift the buffer to make room for average_read_length number of characters
145 int shift
= average_read_length
- slack
;
146 Array
.Copy (buffer
, shift
, buffer
, 0, char_count
- shift
);
149 buffer_start
+= shift
;
150 slack
+= shift
; // slack == average_read_length
153 char_count
+= reader
.Read (buffer
, char_count
, slack
);
155 return pos
< char_count
;
160 if ((pos
>= char_count
) && !ReadBuffer ())
168 if ((pos
>= char_count
) && !ReadBuffer ())
171 return buffer
[pos
++];
175 public class DoubleHash
{
176 const int DEFAULT_INITIAL_BUCKETS
= 100;
178 public DoubleHash () : this (DEFAULT_INITIAL_BUCKETS
) {}
180 public DoubleHash (int size
)
183 buckets
= new Entry
[size
];
197 public Entry (object key1
, object key2
, int hash
, object value, Entry next
)
207 public bool Lookup (object a
, object b
, out object res
)
209 int h
= (a
.GetHashCode () ^ b
.GetHashCode ()) & 0x7FFFFFFF;
211 for (Entry e
= buckets
[h
% count
]; e
!= null; e
= e
.next
) {
212 if (e
.hash
== h
&& e
.key1
.Equals (a
) && e
.key2
.Equals (b
)) {
221 public void Insert (object a
, object b
, object value)
223 // Is it an existing one?
225 int h
= (a
.GetHashCode () ^ b
.GetHashCode ()) & 0x7FFFFFFF;
227 for (Entry e
= buckets
[h
% count
]; e
!= null; e
= e
.next
) {
228 if (e
.hash
== h
&& e
.key1
.Equals (a
) && e
.key2
.Equals (b
))
232 int bucket
= h
% count
;
233 buckets
[bucket
] = new Entry (a
, b
, h
, value, buckets
[bucket
]);
235 // Grow whenever we double in size
236 if (size
++ == count
) {
240 Entry
[] newBuckets
= new Entry
[count
];
241 foreach (Entry root
in buckets
) {
244 int newLoc
= e
.hash
% count
;
246 e
.next
= newBuckets
[newLoc
];
247 newBuckets
[newLoc
] = e
;
252 buckets
= newBuckets
;
257 class PartialMethodDefinitionInfo
: MethodInfo
260 MethodAttributes attrs
;
262 public PartialMethodDefinitionInfo (MethodOrOperator mc
)
265 if ((mc
.ModFlags
& Modifiers
.STATIC
) != 0)
266 attrs
= MethodAttributes
.Static
;
269 public override MethodInfo
GetBaseDefinition ()
271 throw new NotImplementedException ();
274 public override ICustomAttributeProvider ReturnTypeCustomAttributes
276 get { throw new NotImplementedException (); }
279 public override MethodAttributes Attributes
281 get { return attrs; }
284 public override MethodImplAttributes
GetMethodImplementationFlags ()
286 throw new NotImplementedException ();
289 public override ParameterInfo
[] GetParameters ()
291 throw new NotImplementedException ();
294 public override object Invoke (object obj
, BindingFlags invokeAttr
, Binder binder
, object [] parameters
, CultureInfo culture
)
296 throw new NotImplementedException ();
299 public override RuntimeMethodHandle MethodHandle
301 get { throw new NotImplementedException (); }
304 public override Type DeclaringType
306 get { return mc.Parent.TypeBuilder; }
309 public override object [] GetCustomAttributes (Type attributeType
, bool inherit
)
311 throw new NotImplementedException ();
314 public override object [] GetCustomAttributes (bool inherit
)
316 throw new NotImplementedException ();
319 public override Type ReturnType
{
321 return mc
.MemberType
;
325 public override bool IsDefined (Type attributeType
, bool inherit
)
327 throw new NotImplementedException ();
330 public override string Name
332 get { return mc.Name; }
335 public override Type ReflectedType
337 get { throw new NotImplementedException (); }
341 #if NET_4_0 || MS_COMPATIBLE
342 [System
.Diagnostics
.DebuggerDisplay ("Dynamic type")]
344 class DynamicType
: Type
346 public override Assembly Assembly
{
347 get { return UnderlyingSystemType.Assembly; }
350 public override string AssemblyQualifiedName
{
351 get { throw new NotImplementedException (); }
354 public override Type BaseType
{
358 public override string FullName
{
359 get { return UnderlyingSystemType.FullName; }
362 public override Guid GUID
{
363 get { throw new NotImplementedException (); }
366 protected override TypeAttributes
GetAttributeFlagsImpl ()
368 return UnderlyingSystemType
.Attributes
;
371 protected override ConstructorInfo
GetConstructorImpl (BindingFlags bindingAttr
, Binder binder
, CallingConventions callConvention
, Type
[] types
, ParameterModifier
[] modifiers
)
373 throw new NotImplementedException ();
376 public override ConstructorInfo
[] GetConstructors (BindingFlags bindingAttr
)
378 throw new NotImplementedException ();
381 public override Type
GetElementType ()
383 throw new NotImplementedException ();
386 public override EventInfo
GetEvent (string name
, BindingFlags bindingAttr
)
388 throw new NotImplementedException ();
391 public override EventInfo
[] GetEvents (BindingFlags bindingAttr
)
393 throw new NotImplementedException ();
396 public override FieldInfo
GetField (string name
, BindingFlags bindingAttr
)
398 throw new NotImplementedException ();
401 public override FieldInfo
[] GetFields (BindingFlags bindingAttr
)
403 throw new NotImplementedException ();
406 public override Type
GetInterface (string name
, bool ignoreCase
)
408 throw new NotImplementedException ();
411 public override Type
[] GetInterfaces ()
413 return Type
.EmptyTypes
;
416 public override MemberInfo
[] GetMembers (BindingFlags bindingAttr
)
418 throw new NotImplementedException ();
421 protected override MethodInfo
GetMethodImpl (string name
, BindingFlags bindingAttr
, Binder binder
, CallingConventions callConvention
, Type
[] types
, ParameterModifier
[] modifiers
)
423 throw new NotImplementedException ();
426 public override MethodInfo
[] GetMethods (BindingFlags bindingAttr
)
428 throw new NotImplementedException ();
431 public override Type
GetNestedType (string name
, BindingFlags bindingAttr
)
433 throw new NotImplementedException ();
436 public override Type
[] GetNestedTypes (BindingFlags bindingAttr
)
438 throw new NotImplementedException ();
441 public override PropertyInfo
[] GetProperties (BindingFlags bindingAttr
)
443 throw new NotImplementedException ();
446 protected override PropertyInfo
GetPropertyImpl (string name
, BindingFlags bindingAttr
, Binder binder
, Type returnType
, Type
[] types
, ParameterModifier
[] modifiers
)
448 throw new NotImplementedException ();
451 protected override bool HasElementTypeImpl ()
456 public override object InvokeMember (string name
, BindingFlags invokeAttr
, Binder binder
, object target
, object[] args
, ParameterModifier
[] modifiers
, System
.Globalization
.CultureInfo culture
, string[] namedParameters
)
458 throw new NotImplementedException ();
461 protected override bool IsArrayImpl ()
466 protected override bool IsByRefImpl ()
471 protected override bool IsCOMObjectImpl ()
476 protected override bool IsPointerImpl ()
481 protected override bool IsPrimitiveImpl ()
486 public override Module Module
{
487 get { return UnderlyingSystemType.Module; }
490 public override string Namespace
{
491 get { return UnderlyingSystemType.Namespace; }
494 public override Type UnderlyingSystemType
{
495 get { return TypeManager.object_type; }
498 public override object[] GetCustomAttributes (Type attributeType
, bool inherit
)
500 return new object [0];
503 public override object[] GetCustomAttributes (bool inherit
)
505 return new object [0];
508 public override bool IsDefined (Type attributeType
, bool inherit
)
510 throw new NotImplementedException ();
513 public override string Name
{
514 get { return UnderlyingSystemType.Name; }
517 public override string ToString ()
519 return UnderlyingSystemType
.ToString ();
522 public override RuntimeTypeHandle TypeHandle
{
523 get { return UnderlyingSystemType.TypeHandle; }
526 public override Type
MakeByRefType ()
528 // TODO: Wrong, hides dynamic type
529 return UnderlyingSystemType
.MakeByRefType ();
533 #if NET_4_0 || MS_COMPATIBLE
534 [System
.Diagnostics
.DebuggerDisplay ("Dynamic array type")]
536 class DynamicArrayType
: Type
539 Type reflection_type
;
541 public DynamicArrayType (int rank
)
546 public override Assembly Assembly
{
547 get { return UnderlyingSystemType.Assembly; }
550 public override string AssemblyQualifiedName
{
551 get { throw new NotImplementedException (); }
554 public override Type BaseType
{
555 get { return TypeManager.array_type; }
558 public override string FullName
{
559 get { return UnderlyingSystemType.FullName; }
562 public override Guid GUID
{
563 get { throw new NotImplementedException (); }
566 protected override TypeAttributes
GetAttributeFlagsImpl ()
568 return UnderlyingSystemType
.Attributes
;
571 public override int GetArrayRank ()
576 protected override ConstructorInfo
GetConstructorImpl (BindingFlags bindingAttr
, Binder binder
, CallingConventions callConvention
, Type
[] types
, ParameterModifier
[] modifiers
)
578 throw new NotImplementedException ();
581 public override ConstructorInfo
[] GetConstructors (BindingFlags bindingAttr
)
583 throw new NotImplementedException ();
586 public override Type
GetElementType ()
588 return InternalType
.Dynamic
;
591 public override EventInfo
GetEvent (string name
, BindingFlags bindingAttr
)
593 throw new NotImplementedException ();
596 public override EventInfo
[] GetEvents (BindingFlags bindingAttr
)
598 throw new NotImplementedException ();
601 public override FieldInfo
GetField (string name
, BindingFlags bindingAttr
)
603 throw new NotImplementedException ();
606 public override FieldInfo
[] GetFields (BindingFlags bindingAttr
)
608 throw new NotImplementedException ();
611 public override Type
GetInterface (string name
, bool ignoreCase
)
613 throw new NotImplementedException ();
616 public override Type
[] GetInterfaces ()
618 return Type
.EmptyTypes
;
621 public override MemberInfo
[] GetMembers (BindingFlags bindingAttr
)
623 throw new NotImplementedException ();
626 protected override MethodInfo
GetMethodImpl (string name
, BindingFlags bindingAttr
, Binder binder
, CallingConventions callConvention
, Type
[] types
, ParameterModifier
[] modifiers
)
628 throw new NotImplementedException ();
631 public override MethodInfo
[] GetMethods (BindingFlags bindingAttr
)
633 throw new NotImplementedException ();
636 public override Type
GetNestedType (string name
, BindingFlags bindingAttr
)
638 throw new NotImplementedException ();
641 public override Type
[] GetNestedTypes (BindingFlags bindingAttr
)
643 throw new NotImplementedException ();
646 public override PropertyInfo
[] GetProperties (BindingFlags bindingAttr
)
648 throw new NotImplementedException ();
651 protected override PropertyInfo
GetPropertyImpl (string name
, BindingFlags bindingAttr
, Binder binder
, Type returnType
, Type
[] types
, ParameterModifier
[] modifiers
)
653 throw new NotImplementedException ();
656 protected override bool HasElementTypeImpl ()
661 public override object InvokeMember (string name
, BindingFlags invokeAttr
, Binder binder
, object target
, object[] args
, ParameterModifier
[] modifiers
, System
.Globalization
.CultureInfo culture
, string[] namedParameters
)
663 throw new NotImplementedException ();
666 protected override bool IsArrayImpl ()
671 protected override bool IsByRefImpl ()
676 protected override bool IsCOMObjectImpl ()
681 protected override bool IsPointerImpl ()
686 protected override bool IsPrimitiveImpl ()
691 public override Module Module
{
692 get { return UnderlyingSystemType.Module; }
695 public override string Namespace
{
696 get { return UnderlyingSystemType.Namespace; }
699 public override Type UnderlyingSystemType
{
701 if (reflection_type
== null) {
702 reflection_type
= rank
== 1 ?
703 TypeManager
.object_type
.MakeArrayType () :
704 TypeManager
.object_type
.MakeArrayType (rank
);
707 return reflection_type
;
711 public override object[] GetCustomAttributes (Type attributeType
, bool inherit
)
713 return new object [0];
716 public override object[] GetCustomAttributes (bool inherit
)
718 return new object [0];
721 public override bool IsDefined (Type attributeType
, bool inherit
)
723 throw new NotImplementedException ();
726 public override string Name
{
727 get { return UnderlyingSystemType.Name; }
730 public override string ToString ()
732 return UnderlyingSystemType
.ToString ();
735 public override RuntimeTypeHandle TypeHandle
{
736 get { return UnderlyingSystemType.TypeHandle; }
740 public class UnixUtils
{
741 [System
.Runtime
.InteropServices
.DllImport ("libc", EntryPoint
="isatty")]
742 extern static int _isatty (int fd
);
744 public static bool isatty (int fd
)
747 return _isatty (fd
) == 1;
755 /// An exception used to terminate the compiler resolution phase and provide completions
758 /// This is thrown when we want to return the completions or
759 /// terminate the completion process by AST nodes used in
760 /// the completion process.
762 public class CompletionResult
: Exception
{
766 public CompletionResult (string base_text
, string [] res
)
768 if (base_text
== null)
769 throw new ArgumentNullException ("base_text");
770 this.base_text
= base_text
;
776 public string [] Result
{
782 public string BaseText
{