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 sealed 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 ReferenceEquals (x, y);
36 public int GetHashCode (T obj)
38 return System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode (obj);
42 public class Tuple<T1, T2> : IEquatable<Tuple<T1, T2>>
44 public Tuple (T1 item1, T2 item2)
50 public T1 Item1 { get; private set; }
51 public T2 Item2 { get; private set; }
53 public override int GetHashCode ()
55 return Item1.GetHashCode () ^ Item2.GetHashCode ();
58 #region IEquatable<Tuple<T1,T2>> Members
60 public bool Equals (Tuple<T1, T2> other)
62 return EqualityComparer<T1>.Default.Equals (Item1, other.Item1) &&
63 EqualityComparer<T2>.Default.Equals (Item2, other.Item2);
71 public static Tuple<T1, T2> Create<T1, T2> (T1 item1, T2 item2)
73 return new Tuple<T1, T2> (item1, item2);
78 /// This is an arbitrarily seekable StreamReader wrapper.
80 /// It uses a self-tuning buffer to cache the seekable data,
81 /// but if the seek is too far, it may read the underly
82 /// stream all over from the beginning.
84 public class SeekableStreamReader : IDisposable
86 const int buffer_read_length_spans = 3;
92 int average_read_length;
93 int buffer_start; // in chars
94 int char_count; // count buffer[] valid characters
95 int pos; // index into buffer[]
97 public SeekableStreamReader (Stream stream, Encoding encoding)
101 const int default_average_read_length = 1024;
102 InitializeStream (default_average_read_length);
103 reader = new StreamReader (stream, encoding, true);
106 public void Dispose ()
108 // Needed to release stream reader buffers
112 void InitializeStream (int read_length_inc)
114 average_read_length += read_length_inc;
116 int required_buffer_size = average_read_length * buffer_read_length_spans;
117 if (buffer == null || buffer.Length < required_buffer_size)
118 buffer = new char [required_buffer_size];
121 buffer_start = char_count = pos = 0;
125 /// This value corresponds to the current position in a stream of characters.
126 /// The StreamReader hides its manipulation of the underlying byte stream and all
127 /// character set/decoding issues. Thus, we cannot use this position to guess at
128 /// the corresponding position in the underlying byte stream even though there is
129 /// a correlation between them.
131 public int Position {
132 get { return buffer_start + pos; }
135 // If the lookahead was too small, re-read from the beginning. Increase the buffer size while we're at it
136 if (value < buffer_start)
137 InitializeStream (average_read_length / 2);
139 while (value > buffer_start + char_count) {
142 throw new InternalErrorException ("Seek beyond end of file: " + (buffer_start + char_count - value));
145 pos = value - buffer_start;
149 private bool ReadBuffer ()
151 int slack = buffer.Length - char_count;
152 if (slack <= average_read_length / 2) {
153 // shift the buffer to make room for average_read_length number of characters
154 int shift = average_read_length - slack;
155 Array.Copy (buffer, shift, buffer, 0, char_count - shift);
158 buffer_start += shift;
159 slack += shift; // slack == average_read_length
162 char_count += reader.Read (buffer, char_count, slack);
164 return pos < char_count;
169 if ((pos >= char_count) && !ReadBuffer ())
177 if ((pos >= char_count) && !ReadBuffer ())
180 return buffer [pos++];
184 public class UnixUtils {
185 [System.Runtime.InteropServices.DllImport ("libc", EntryPoint="isatty")]
186 extern static int _isatty (int fd);
188 public static bool isatty (int fd)
191 return _isatty (fd) == 1;
199 /// An exception used to terminate the compiler resolution phase and provide completions
202 /// This is thrown when we want to return the completions or
203 /// terminate the completion process by AST nodes used in
204 /// the completion process.
206 public class CompletionResult : Exception {
210 public CompletionResult (string base_text, string [] res)
212 if (base_text == null)
213 throw new ArgumentNullException ("base_text");
214 this.base_text = base_text;
220 public string [] Result {
226 public string BaseText {