Removed more obsolete defines
[mono.git] / mcs / mcs / support.cs
1 //
2 // support.cs: Support routines to work around the fact that System.Reflection.Emit
3 // can not introspect types that are being constructed
4 //
5 // Author:
6 //   Miguel de Icaza (miguel@ximian.com)
7 //
8 // Copyright 2001 Ximian, Inc (http://www.ximian.com)
9 // Copyright 2003-2008 Novell, Inc
10 //
11
12 using System;
13 using System.IO;
14 using System.Text;
15 using System.Reflection;
16 using System.Collections;
17 using System.Reflection.Emit;
18 using System.Globalization;
19
20 namespace Mono.CSharp {
21
22         class PtrHashtable : Hashtable {
23                 sealed class PtrComparer : IComparer, IEqualityComparer
24                 {
25                         private PtrComparer () {}
26
27                         public static PtrComparer Instance = new PtrComparer ();
28
29                         public int Compare (object x, object y)
30                         {
31                                 if (x == y)
32                                         return 0;
33                                 else
34                                         return 1;
35                         }
36
37                         bool IEqualityComparer.Equals (object x, object y)
38                         {
39                                 return x == y;
40                         }
41                         
42                         int IEqualityComparer.GetHashCode (object obj)
43                         {
44                                 return obj.GetHashCode ();
45                         }
46                 }
47
48                 public PtrHashtable () : base (PtrComparer.Instance) {}
49
50 #if MS_COMPATIBLE
51                 //
52                 // Workaround System.InvalidOperationException for enums
53                 //
54                 protected override int GetHash (object key)
55                 {
56                         TypeBuilder tb = key as TypeBuilder;
57                         if (tb != null && tb.BaseType == TypeManager.enum_type && tb.BaseType != null)
58                                 key = tb.BaseType;
59
60                         return base.GetHash (key);
61                 }
62 #endif
63         }
64
65         /*
66          * Hashtable whose keys are character arrays with the same length
67          */
68         class CharArrayHashtable : Hashtable {
69                 sealed class ArrComparer : IComparer {
70                         private int len;
71
72                         public ArrComparer (int len) {
73                                 this.len = len;
74                         }
75
76                         public int Compare (object x, object y)
77                         {
78                                 char[] a = (char[])x;
79                                 char[] b = (char[])y;
80
81                                 for (int i = 0; i < len; ++i)
82                                         if (a [i] != b [i])
83                                                 return 1;
84                                 return 0;
85                         }
86                 }
87
88                 private int len;
89
90                 protected override int GetHash (Object key)
91                 {
92                         char[] arr = (char[])key;
93                         int h = 0;
94
95                         for (int i = 0; i < len; ++i)
96                                 h = (h << 5) - h + arr [i];
97
98                         return h;
99                 }
100
101                 public CharArrayHashtable (int len)
102                 {
103                         this.len = len;
104                         comparer = new ArrComparer (len);
105                 }
106         }
107
108         struct Pair {
109                 public object First;
110                 public object Second;
111
112                 public Pair (object f, object s)
113                 {
114                         First = f;
115                         Second = s;
116                 }
117         }
118
119         public class Accessors {
120                 public Accessor get_or_add;
121                 public Accessor set_or_remove;
122
123                 // was 'set' declared before 'get'?  was 'remove' declared before 'add'?
124                 public bool declared_in_reverse;
125
126                 public Accessors (Accessor get_or_add, Accessor set_or_remove)
127                 {
128                         this.get_or_add = get_or_add;
129                         this.set_or_remove = set_or_remove;
130                 }
131         }
132
133         /// <summary>
134         ///   This is an arbitrarily seekable StreamReader wrapper.
135         ///
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.
139         /// </summary>
140         public class SeekableStreamReader
141         {
142                 const int default_average_read_length = 1024;
143                 const int buffer_read_length_spans = 3;
144
145                 TextReader reader;
146                 Stream stream;
147                 Encoding encoding;
148
149                 char[] buffer;
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[]
154
155                 void ResetStream (int read_length_inc)
156                 {
157                         average_read_length += read_length_inc;
158                         stream.Position = 0;
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;
162                 }
163
164                 public SeekableStreamReader (Stream stream, Encoding encoding)
165                 {
166                         this.stream = stream;
167                         this.encoding = encoding;
168
169                         ResetStream (default_average_read_length);
170                 }
171
172                 /// <remarks>
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.
178                 /// </remarks>
179                 public int Position {
180                         get { return buffer_start + pos; }
181
182                         set {
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);
186
187                                 while (value > buffer_start + char_count) {
188                                         pos = char_count;
189                                         if (!ReadBuffer ())
190                                                 throw new InternalErrorException ("Seek beyond end of file: " + (buffer_start + char_count - value));
191                                 }
192
193                                 pos = value - buffer_start;
194                         }
195                 }
196
197                 private bool ReadBuffer ()
198                 {
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);
204                                 pos -= shift;
205                                 char_count -= shift;
206                                 buffer_start += shift;
207                                 slack += shift;         // slack == average_read_length
208                         }
209
210                         char_count += reader.Read (buffer, char_count, slack);
211
212                         return pos < char_count;
213                 }
214
215                 public int Peek ()
216                 {
217                         if ((pos >= char_count) && !ReadBuffer ())
218                                 return -1;
219
220                         return buffer [pos];
221                 }
222
223                 public int Read ()
224                 {
225                         if ((pos >= char_count) && !ReadBuffer ())
226                                 return -1;
227
228                         return buffer [pos++];
229                 }
230         }
231
232         public class DoubleHash {
233                 const int DEFAULT_INITIAL_BUCKETS = 100;
234
235                 public DoubleHash () : this (DEFAULT_INITIAL_BUCKETS) {}
236
237                 public DoubleHash (int size)
238                 {
239                         count = size;
240                         buckets = new Entry [size];
241                 }
242
243                 int count;
244                 Entry [] buckets;
245                 int size = 0;
246
247                 class Entry {
248                         public object key1;
249                         public object key2;
250                         public int hash;
251                         public object value;
252                         public Entry next;
253
254                         public Entry (object key1, object key2, int hash, object value, Entry next)
255                         {
256                                 this.key1 = key1;
257                                 this.key2 = key2;
258                                 this.hash = hash;
259                                 this.next = next;
260                                 this.value = value;
261                         }
262                 }
263
264                 public bool Lookup (object a, object b, out object res)
265                 {
266                         int h = (a.GetHashCode () ^ b.GetHashCode ()) & 0x7FFFFFFF;
267
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)) {
270                                         res = e.value;
271                                         return true;
272                                 }
273                         }
274                         res = null;
275                         return false;
276                 }
277
278                 public void Insert (object a, object b, object value)
279                 {
280                         // Is it an existing one?
281
282                         int h = (a.GetHashCode () ^ b.GetHashCode ()) & 0x7FFFFFFF;
283
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))
286                                         e.value = value;
287                         }
288
289                         int bucket = h % count;
290                         buckets [bucket] = new Entry (a, b, h, value, buckets [bucket]);
291
292                         // Grow whenever we double in size
293                         if (size++ == count) {
294                                 count <<= 1;
295                                 count ++;
296
297                                 Entry [] newBuckets = new Entry [count];
298                                 foreach (Entry root in buckets) {
299                                         Entry e = root;
300                                         while (e != null) {
301                                                 int newLoc = e.hash % count;
302                                                 Entry n = e.next;
303                                                 e.next = newBuckets [newLoc];
304                                                 newBuckets [newLoc] = e;
305                                                 e = n;
306                                         }
307                                 }
308
309                                 buckets = newBuckets;
310                         }
311                 }
312         }
313
314         class PartialMethodDefinitionInfo : MethodInfo
315         {
316                 MethodOrOperator mc;
317                 MethodAttributes attrs;
318
319                 public PartialMethodDefinitionInfo (MethodOrOperator mc)
320                 {
321                         this.mc = mc;
322                         if ((mc.ModFlags & Modifiers.STATIC) != 0)
323                                 attrs = MethodAttributes.Static;
324                 }
325
326                 public override MethodInfo GetBaseDefinition ()
327                 {
328                         throw new NotImplementedException ();
329                 }
330
331                 public override ICustomAttributeProvider ReturnTypeCustomAttributes
332                 {
333                         get { throw new NotImplementedException (); }
334                 }
335
336                 public override MethodAttributes Attributes
337                 {
338                         get { return attrs; }
339                 }
340
341                 public override MethodImplAttributes GetMethodImplementationFlags ()
342                 {
343                         throw new NotImplementedException ();
344                 }
345
346                 public override ParameterInfo [] GetParameters ()
347                 {
348                         throw new NotImplementedException ();
349                 }
350
351                 public override object Invoke (object obj, BindingFlags invokeAttr, Binder binder, object [] parameters, CultureInfo culture)
352                 {
353                         throw new NotImplementedException ();
354                 }
355
356                 public override RuntimeMethodHandle MethodHandle
357                 {
358                         get { throw new NotImplementedException (); }
359                 }
360
361                 public override Type DeclaringType
362                 {
363                         get { return mc.Parent.TypeBuilder; }
364                 }
365
366                 public override object [] GetCustomAttributes (Type attributeType, bool inherit)
367                 {
368                         throw new NotImplementedException ();
369                 }
370
371                 public override object [] GetCustomAttributes (bool inherit)
372                 {
373                         throw new NotImplementedException ();
374                 }
375
376                 public override Type ReturnType {
377                         get {
378                                 return mc.MemberType;
379                         }
380                 }
381
382                 public override bool IsDefined (Type attributeType, bool inherit)
383                 {
384                         throw new NotImplementedException ();
385                 }
386
387                 public override string Name
388                 {
389                         get { return mc.Name; }
390                 }
391
392                 public override Type ReflectedType
393                 {
394                         get { throw new NotImplementedException (); }
395                 }
396         }
397
398 #if NET_4_0 || MS_COMPATIBLE
399         [System.Diagnostics.DebuggerDisplay ("Dynamic type")]
400 #endif
401         class DynamicType : Type
402         {
403                 public override Assembly Assembly {
404                         get { return UnderlyingSystemType.Assembly; }
405                 }
406
407                 public override string AssemblyQualifiedName {
408                         get { throw new NotImplementedException (); }
409                 }
410
411                 public override Type BaseType {
412                         get { return null; }
413                 }
414
415                 public override string FullName {
416                         get { return UnderlyingSystemType.FullName; }
417                 }
418
419                 public override Guid GUID {
420                         get { throw new NotImplementedException (); }
421                 }
422
423                 protected override TypeAttributes GetAttributeFlagsImpl ()
424                 {
425                         return UnderlyingSystemType.Attributes;
426                 }
427
428                 protected override ConstructorInfo GetConstructorImpl (BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
429                 {
430                         throw new NotImplementedException ();
431                 }
432
433                 public override ConstructorInfo[] GetConstructors (BindingFlags bindingAttr)
434                 {
435                         throw new NotImplementedException ();
436                 }
437
438                 public override Type GetElementType ()
439                 {
440                         throw new NotImplementedException ();
441                 }
442
443                 public override EventInfo GetEvent (string name, BindingFlags bindingAttr)
444                 {
445                         throw new NotImplementedException ();
446                 }
447
448                 public override EventInfo[] GetEvents (BindingFlags bindingAttr)
449                 {
450                         throw new NotImplementedException ();
451                 }
452
453                 public override FieldInfo GetField (string name, BindingFlags bindingAttr)
454                 {
455                         throw new NotImplementedException ();
456                 }
457
458                 public override FieldInfo[] GetFields (BindingFlags bindingAttr)
459                 {
460                         throw new NotImplementedException ();
461                 }
462
463                 public override Type GetInterface (string name, bool ignoreCase)
464                 {
465                         throw new NotImplementedException ();
466                 }
467
468                 public override Type[] GetInterfaces ()
469                 {
470                         return Type.EmptyTypes;
471                 }
472
473                 public override MemberInfo[] GetMembers (BindingFlags bindingAttr)
474                 {
475                         throw new NotImplementedException ();
476                 }
477
478                 protected override MethodInfo GetMethodImpl (string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
479                 {
480                         throw new NotImplementedException ();
481                 }
482
483                 public override MethodInfo[] GetMethods (BindingFlags bindingAttr)
484                 {
485                         throw new NotImplementedException ();
486                 }
487
488                 public override Type GetNestedType (string name, BindingFlags bindingAttr)
489                 {
490                         throw new NotImplementedException ();
491                 }
492
493                 public override Type[] GetNestedTypes (BindingFlags bindingAttr)
494                 {
495                         throw new NotImplementedException ();
496                 }
497
498                 public override PropertyInfo[] GetProperties (BindingFlags bindingAttr)
499                 {
500                         throw new NotImplementedException ();
501                 }
502
503                 protected override PropertyInfo GetPropertyImpl (string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers)
504                 {
505                         throw new NotImplementedException ();
506                 }
507
508                 protected override bool HasElementTypeImpl ()
509                 {
510                         throw new NotImplementedException ();
511                 }
512
513                 public override object InvokeMember (string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, ParameterModifier[] modifiers, System.Globalization.CultureInfo culture, string[] namedParameters)
514                 {
515                         throw new NotImplementedException ();
516                 }
517
518                 protected override bool IsArrayImpl ()
519                 {
520                         return false;
521                 }
522
523                 protected override bool IsByRefImpl ()
524                 {
525                         return false;
526                 }
527
528                 protected override bool IsCOMObjectImpl ()
529                 {
530                         return false;
531                 }
532
533                 protected override bool IsPointerImpl ()
534                 {
535                         return false;
536                 }
537
538                 protected override bool IsPrimitiveImpl ()
539                 {
540                         return false;
541                 }
542
543                 public override Module Module {
544                         get { return UnderlyingSystemType.Module; }
545                 }
546
547                 public override string Namespace {
548                         get { throw new NotImplementedException (); }
549                 }
550
551                 public override Type UnderlyingSystemType {
552                         get { return TypeManager.object_type; }
553                 }
554
555                 public override object[] GetCustomAttributes (Type attributeType, bool inherit)
556                 {
557                         return new object [0];
558                 }
559
560                 public override object[] GetCustomAttributes (bool inherit)
561                 {
562                         return new object [0];
563                 }
564
565                 public override bool IsDefined (Type attributeType, bool inherit)
566                 {
567                         throw new NotImplementedException ();
568                 }
569
570                 public override string Name {
571                         get { return UnderlyingSystemType.Name; }
572                 }
573
574                 public override string ToString ()
575                 {
576                         return UnderlyingSystemType.ToString ();
577                 }
578
579                 public override RuntimeTypeHandle TypeHandle {
580                         get { return UnderlyingSystemType.TypeHandle; }
581                 }
582         }
583
584         public class UnixUtils {
585                 [System.Runtime.InteropServices.DllImport ("libc", EntryPoint="isatty")]
586                 extern static int _isatty (int fd);
587                         
588                 public static bool isatty (int fd)
589                 {
590                         try {
591                                 return _isatty (fd) == 1;
592                         } catch {
593                                 return false;
594                         }
595                 }
596         }
597
598         /// <summary>
599         ///   An exception used to terminate the compiler resolution phase and provide completions
600         /// </summary>
601         /// <remarks>
602         ///   This is thrown when we want to return the completions or
603         ///   terminate the completion process by AST nodes used in
604         ///   the completion process.
605         /// </remarks>
606         public class CompletionResult : Exception {
607                 string [] result;
608                 string base_text;
609                 
610                 public CompletionResult (string base_text, string [] res)
611                 {
612                         if (base_text == null)
613                                 throw new ArgumentNullException ("base_text");
614                         this.base_text = base_text;
615
616                         result = res;
617                         Array.Sort (result);
618                 }
619
620                 public string [] Result {
621                         get {
622                                 return result;
623                         }
624                 }
625
626                 public string BaseText {
627                         get {
628                                 return base_text;
629                         }
630                 }
631         }
632 }