Free cookie consent management tool by TermsFeed Policy Generator

source: branches/CodeEditor/HeuristicLab.ExtLibs/HeuristicLab.NRefactory/5.5.0/NRefactory.CSharp-5.5.0/Parser/mcs/support.cs @ 11700

Last change on this file since 11700 was 11700, checked in by jkarder, 10 years ago

#2077: created branch and added first version

File size: 8.4 KB
Line 
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//   Marek Safar (marek.safar@gmail.com)
8//
9// Copyright 2001 Ximian, Inc (http://www.ximian.com)
10// Copyright 2003-2009 Novell, Inc
11// Copyright 2011 Xamarin Inc
12//
13
14using System;
15using System.Linq;
16using System.IO;
17using System.Text;
18using System.Collections.Generic;
19
20namespace Mono.CSharp {
21
22  sealed class ReferenceEquality<T> : IEqualityComparer<T> where T : class
23  {
24    public static readonly IEqualityComparer<T> Default = new ReferenceEquality<T> ();
25
26    private ReferenceEquality ()
27    {
28    }
29
30    public bool Equals (T x, T y)
31    {
32      return ReferenceEquals (x, y);
33    }
34
35    public int GetHashCode (T obj)
36    {
37      return System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode (obj);
38    }
39  }
40#if !NET_4_0 && !MOBILE_DYNAMIC
41  public class Tuple<T1, T2> : IEquatable<Tuple<T1, T2>>
42  {
43    public Tuple (T1 item1, T2 item2)
44    {
45      Item1 = item1;
46      Item2 = item2;
47    }
48
49    public T1 Item1 { get; private set; }
50    public T2 Item2 { get; private set; }
51
52    public override int GetHashCode ()
53    {
54      return ((object)Item1 ?? 0) .GetHashCode () ^ ((object)Item2 ?? 0).GetHashCode ();
55    }
56
57    #region IEquatable<Tuple<T1,T2>> Members
58
59    public bool Equals (Tuple<T1, T2> other)
60    {
61      return EqualityComparer<T1>.Default.Equals (Item1, other.Item1) &&
62        EqualityComparer<T2>.Default.Equals (Item2, other.Item2);
63    }
64
65    #endregion
66  }
67
68  public class Tuple<T1, T2, T3> : IEquatable<Tuple<T1, T2, T3>>
69  {
70    public Tuple (T1 item1, T2 item2, T3 item3)
71    {
72      Item1 = item1;
73      Item2 = item2;
74      Item3 = item3;
75    }
76
77    public T1 Item1 { get; private set; }
78    public T2 Item2 { get; private set; }
79    public T3 Item3 { get; private set; }
80
81    public override int GetHashCode ()
82    {
83      return Item1.GetHashCode () ^ Item2.GetHashCode () ^ Item3.GetHashCode ();
84    }
85
86    #region IEquatable<Tuple<T1,T2>> Members
87
88    public bool Equals (Tuple<T1, T2, T3> other)
89    {
90      return EqualityComparer<T1>.Default.Equals (Item1, other.Item1) &&
91        EqualityComparer<T2>.Default.Equals (Item2, other.Item2) &&
92        EqualityComparer<T3>.Default.Equals (Item3, other.Item3);
93    }
94
95    #endregion
96  }
97
98  static class Tuple
99  {
100    public static Tuple<T1, T2> Create<T1, T2> (T1 item1, T2 item2)
101    {
102      return new Tuple<T1, T2> (item1, item2);
103    }
104
105    public static Tuple<T1, T2, T3> Create<T1, T2, T3> (T1 item1, T2 item2, T3 item3)
106    {
107      return new Tuple<T1, T2, T3> (item1, item2, item3);
108    }
109  }
110#endif
111
112  static class ArrayComparer
113  {
114    public static bool IsEqual<T> (T[] array1, T[] array2)
115    {
116      if (array1 == null || array2 == null)
117        return array1 == array2;
118
119      var eq = EqualityComparer<T>.Default;
120
121      for (int i = 0; i < array1.Length; ++i) {
122        if (!eq.Equals (array1[i], array2[i])) {
123          return false;
124        }
125      }
126
127      return true;
128    }
129  }
130#if !FULL_AST
131  /// <summary>
132  ///   This is an arbitrarily seekable StreamReader wrapper.
133  ///
134  ///   It uses a self-tuning buffer to cache the seekable data,
135  ///   but if the seek is too far, it may read the underly
136  ///   stream all over from the beginning.
137  /// </summary>
138  public class SeekableStreamReader : IDisposable
139  {
140    public const int DefaultReadAheadSize =
141      4096 / 2;
142
143    StreamReader reader;
144    Stream stream;
145
146    char[] buffer;
147    int read_ahead_length;  // the length of read buffer
148    int buffer_start;       // in chars
149    int char_count;         // count of filled characters in buffer[]
150    int pos;                // index into buffer[]
151
152    public SeekableStreamReader (Stream stream, Encoding encoding, char[] sharedBuffer = null)
153    {
154      this.stream = stream;
155      this.buffer = sharedBuffer;
156
157      InitializeStream (DefaultReadAheadSize);
158      reader = new StreamReader (stream, encoding, true);
159    }
160
161    public void Dispose ()
162    {
163      // Needed to release stream reader buffers
164      reader.Dispose ();
165    }
166
167    void InitializeStream (int read_length_inc)
168    {
169      read_ahead_length += read_length_inc;
170
171      int required_buffer_size = read_ahead_length * 2;
172
173      if (buffer == null || buffer.Length < required_buffer_size)
174        buffer = new char [required_buffer_size];
175
176      stream.Position = 0;
177      buffer_start = char_count = pos = 0;
178    }
179
180    /// <remarks>
181    ///   This value corresponds to the current position in a stream of characters.
182    ///   The StreamReader hides its manipulation of the underlying byte stream and all
183    ///   character set/decoding issues.  Thus, we cannot use this position to guess at
184    ///   the corresponding position in the underlying byte stream even though there is
185    ///   a correlation between them.
186    /// </remarks>
187    public int Position {
188      get {
189        return buffer_start + pos;
190      }
191
192      set {
193        //
194        // If the lookahead was too small, re-read from the beginning. Increase the buffer size while we're at it
195        // This should never happen until we are parsing some weird source code
196        //
197        if (value < buffer_start) {
198          InitializeStream (read_ahead_length);
199
200          //
201          // Discard buffer data after underlying stream changed position
202          // Cannot use handy reader.DiscardBufferedData () because it for
203          // some strange reason resets encoding as well
204          //
205          reader = new StreamReader (stream, reader.CurrentEncoding, true);
206        }
207
208        while (value > buffer_start + char_count) {
209          pos = char_count;
210          if (!ReadBuffer ())
211            throw new InternalErrorException ("Seek beyond end of file: " + (buffer_start + char_count - value));
212        }
213
214        pos = value - buffer_start;
215      }
216    }
217
218    bool ReadBuffer ()
219    {
220      int slack = buffer.Length - char_count;
221
222      //
223      // read_ahead_length is only half of the buffer to deal with
224      // reads ahead and moves back without re-reading whole buffer
225      //
226      if (slack <= read_ahead_length) {
227        //
228        // shift the buffer to make room for read_ahead_length number of characters
229        //
230        int shift = read_ahead_length - slack;
231        Array.Copy (buffer, shift, buffer, 0, char_count - shift);
232
233        // Update all counters
234        pos -= shift;
235        char_count -= shift;
236        buffer_start += shift;
237        slack += shift;
238      }
239
240      char_count += reader.Read (buffer, char_count, slack);
241
242      return pos < char_count;
243    }
244   
245    public char GetChar (int position)
246    {
247      if (buffer_start <= position && position < buffer.Length)
248        return buffer[position];
249      return '\0';
250    }
251   
252    public char[] ReadChars (int fromPosition, int toPosition)
253    {
254      char[] chars = new char[toPosition - fromPosition];
255      if (buffer_start <= fromPosition && toPosition <= buffer_start + buffer.Length) {
256        Array.Copy (buffer, fromPosition - buffer_start, chars, 0, chars.Length);
257      } else {
258        throw new NotImplementedException ();
259      }
260
261      return chars;
262    }
263
264    public int Peek ()
265    {
266      if ((pos >= char_count) && !ReadBuffer ())
267        return -1;
268
269      return buffer [pos];
270    }
271
272    public int Read ()
273    {
274      if ((pos >= char_count) && !ReadBuffer ())
275        return -1;
276
277      return buffer [pos++];
278    }
279  }
280#endif
281
282  public class UnixUtils {
283    [System.Runtime.InteropServices.DllImport ("libc", EntryPoint="isatty")]
284    extern static int _isatty (int fd);
285     
286    public static bool isatty (int fd)
287    {
288      try {
289        return _isatty (fd) == 1;
290      } catch {
291        return false;
292      }
293    }
294  }
295
296  /// <summary>
297  ///   An exception used to terminate the compiler resolution phase and provide completions
298  /// </summary>
299  /// <remarks>
300  ///   This is thrown when we want to return the completions or
301  ///   terminate the completion process by AST nodes used in
302  ///   the completion process.
303  /// </remarks>
304  public class CompletionResult : Exception {
305    string [] result;
306    string base_text;
307   
308    public CompletionResult (string base_text, string [] res)
309    {
310      if (base_text == null)
311        throw new ArgumentNullException ("base_text");
312      this.base_text = base_text;
313
314      result = res;
315      Array.Sort (result);
316    }
317
318    public string [] Result {
319      get {
320        return result;
321      }
322    }
323
324    public string BaseText {
325      get {
326        return base_text;
327      }
328    }
329  }
330
331  struct TypeNameParser
332  {
333    internal static string Escape(string name)
334    {
335      if (name == null) {
336        return null;
337      }
338      StringBuilder sb = null;
339      for (int pos = 0; pos < name.Length; pos++) {
340        char c = name[pos];
341        switch (c) {
342          case '\\':
343          case '+':
344          case ',':
345          case '[':
346          case ']':
347          case '*':
348          case '&':
349            if (sb == null) {
350              sb = new StringBuilder(name, 0, pos, name.Length + 3);
351            }
352            sb.Append("\\").Append(c);
353            break;
354          default:
355            if (sb != null) {
356              sb.Append(c);
357            }
358            break;
359        }
360      }
361      return sb != null ? sb.ToString() : name;
362    }
363  }
364}
Note: See TracBrowser for help on using the repository browser.