/SHFB/Source/MRefBuilder/CCI/Nodes.cs
C# | 12670 lines | 11248 code | 573 blank | 849 comment | 3031 complexity | 0ba47bd13f8400a94c762348c4ab196d MD5 | raw file
Possible License(s): CC-BY-SA-3.0
Large files files are truncated, but you can click here to view the full file
- // Copyright Š Microsoft Corporation.
- // This source file is subject to the Microsoft Permissive License.
- // See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
- // All other rights reserved.
-
- // Change history:
- // 02/03/2012 - EFW - Fixed Method.ImplicitlyImplementedInterfaceMethods so that it recognizes interface
- // member matches when the return type is generic.
- // 03/28/2012 - EFW - Fixed TypeNode.Attributes so that it won't get stuck in an endless loop if a type's
- // attribute references the type being parsed.
- // 04/04/2012 - EFW - Fixed TypeNode.NestedTypes so that it won't get stuck in an endless loop when a type
- // contains a nested type that itself implements a nested type from within the containing type.
- // 11/30/2012 - EFW - Added updates based on changes submitted by ComponentOne to fix crashes caused by
- // obfuscated member names.
- // 11/21/2013 - EFW - Cleared out the conditional statements and unused code and updated based on changes to
- // ListTemplate.cs.
- // 03/14/2014 - EFW - Fixed bug in TypeNode.GetMatchingMethod() reported by SHarwell.
-
- using System.Collections;
- using System.Collections.Generic;
- using System.Globalization;
- using System.Compiler.Metadata;
- using System.Diagnostics;
- using System.IO;
- using System.Text;
- using System.Xml;
-
- using BindingFlags = System.Reflection.BindingFlags;
-
- namespace System.Compiler
- {
- /// <summary>
- /// This interface can be used to link an arbitrary source text provider into an IR tree via a DocumentText instance.
- /// </summary>
- public interface ISourceText
- {
- /// <summary>
- /// The number of characters in the source text.
- /// A "character" corresponds to a System.Char which is actually a Unicode UTF16 code point to be precise.
- /// </summary>
- int Length { get; }
- /// <summary>
- /// Retrieves a substring from this instance. The substring starts with the character at the specified index and has a specified length.
- /// </summary>
- string Substring(int startIndex, int length);
- /// <summary>
- /// Retrieves the character at the given position. The first character is at position zero.
- /// </summary>
- char this[int position] { get; }
- /// <summary>
- /// Indicates that the text has been fully scanned and further references to the text are expected to be infrequent.
- /// The underlying object can now choose to clear cached information if it comes under resource pressure.
- /// </summary>
- void MakeCollectible();
- }
-
- public unsafe interface ISourceTextBuffer : ISourceText
- {
- /// <summary>
- /// Returns null unless the implementer is based on an ASCII buffer that stays alive as long at the implementer itself.
- /// An implementer that returns a non-null value is merely a wrapper to keep the buffer alive. No further methods will
- /// be called on the interface in this case.
- /// </summary>
- byte* Buffer { get; }
- }
-
- /// <summary>
- /// This class provides a uniform interface to program sources provided in the form of Unicode strings,
- /// unsafe pointers to ASCII buffers (as obtained from a memory mapped file, for instance) as well as
- /// arbitrary source text providers that implement the ISourceText interface.
- /// </summary>
- public sealed unsafe class DocumentText
- {
- /// <summary>
- /// If this is not null it is used to obtain 8-bit ASCII characters.
- /// </summary>
- public byte* AsciiStringPtr;
- /// <summary>
- /// If this is not null it represents a Unicode string encoded as UTF16.
- /// </summary>
- public string Source;
- /// <summary>
- /// If this is not null the object implement ISourceText provides some way to get at individual characters and substrings.
- /// </summary>
- public ISourceText TextProvider;
- /// <summary>
- /// The number of characters in the source document.
- /// A "character" corresponds to a System.Char which is actually a Unicode UTF16 code point to be precise.
- /// </summary>
- public int Length;
- public DocumentText(string source)
- {
- if(source == null) { Debug.Assert(false); return; }
- this.Source = source;
- this.Length = source.Length;
- }
- public DocumentText(ISourceText textProvider)
- {
- if(textProvider == null) { Debug.Assert(false); return; }
- this.TextProvider = textProvider;
- this.Length = textProvider.Length;
- }
- public unsafe DocumentText(ISourceTextBuffer textProvider)
- {
- if(textProvider == null) { Debug.Assert(false); return; }
- this.TextProvider = textProvider;
- this.AsciiStringPtr = textProvider.Buffer;
- this.Length = textProvider.Length;
- }
- /// <summary>
- /// Compare this.Substring(offset, length) for equality with str.
- /// Call this only if str.Length is known to be equal to length.
- /// </summary>
- public bool Equals(string str, int position, int length)
- { //TODO: (int position, int length, string str)
- if(str == null) { Debug.Assert(false); return false; }
- if(str.Length != length) { Debug.Assert(false); return false; }
- if(position < 0 || position + length > this.Length) { Debug.Assert(false); return false; }
- unsafe
- {
- byte* p = this.AsciiStringPtr;
- if(p != null)
- {
- for(int i = position, j = 0; j < length; i++, j++)
- if(((char)*(p + i)) != str[j])
- return false;
- return true;
- }
- }
- string source = this.Source;
- if(source != null)
- {
- for(int i = position, j = 0; j < length; i++, j++)
- if(source[i] != str[j])
- return false;
- return true;
- }
- ISourceText myProvider = this.TextProvider;
- if(myProvider == null) { Debug.Assert(false); return false; }
- for(int i = position, j = 0; j < length; i++, j++)
- if(myProvider[i] != str[j])
- return false;
- return true;
- }
- /// <summary>
- /// Compares the substring of the specified length starting at offset, with the substring in DocumentText starting at textOffset.
- /// </summary>
- /// <param name="offset">The index of the first character of the substring of this DocumentText.</param>
- /// <param name="text">The Document text with the substring being compared to.</param>
- /// <param name="textOffset">The index of the first character of the substring of the DocumentText being compared to.</param>
- /// <param name="length">The number of characters in the substring being compared.</param>
- /// <returns></returns>
- public bool Equals(int offset, DocumentText text, int textOffset, int length)
- { //TODO: (int position, int length, DocumentText text, int textPosition)
- if(offset < 0 || length < 0 || offset + length > this.Length) { Debug.Assert(false); return false; }
- if(textOffset < 0 || text == null || textOffset + length > text.Length) { Debug.Assert(false); return false; }
- unsafe
- {
- byte* p = this.AsciiStringPtr;
- if(p != null)
- {
- unsafe
- {
- byte* q = text.AsciiStringPtr;
- if(q != null)
- {
- for(int i = offset, j = textOffset, n = offset + length; i < n; i++, j++)
- if(*(p + i) != *(q + j))
- return false;
- return true;
- }
- }
- string textSource = text.Source;
- if(textSource != null)
- {
- for(int i = offset, j = textOffset, n = offset + length; i < n; i++, j++)
- if(((char)*(p + i)) != textSource[j])
- return false;
- return true;
- }
- ISourceText textProvider = text.TextProvider;
- if(textProvider == null) { Debug.Assert(false); return false; }
- for(int i = offset, j = textOffset, n = offset + length; i < n; i++, j++)
- if(((char)*(p + i)) != textProvider[j])
- return false;
- return true;
- }
- }
- string source = this.Source;
- if(source != null)
- {
- unsafe
- {
- byte* q = text.AsciiStringPtr;
- if(q != null)
- {
- for(int i = offset, j = textOffset, n = offset + length; i < n; i++, j++)
- if(source[i] != (char)*(q + j))
- return false;
- return true;
- }
- }
- string textSource = text.Source;
- if(textSource != null)
- {
- for(int i = offset, j = textOffset, n = offset + length; i < n; i++, j++)
- if(source[i] != textSource[j])
- return false;
- return true;
- }
- ISourceText textProvider = text.TextProvider;
- if(textProvider == null) { Debug.Assert(false); return false; }
- for(int i = offset, j = textOffset, n = offset + length; i < n; i++, j++)
- if(source[i] != textProvider[j])
- return false;
- return true;
- }
- {
- ISourceText myProvider = this.TextProvider;
- if(myProvider == null) { Debug.Assert(false); return false; }
- unsafe
- {
- byte* q = text.AsciiStringPtr;
- if(q != null)
- {
- for(int i = offset, j = textOffset, n = offset + length; i < n; i++, j++)
- if(myProvider[i] != (char)*(q + j))
- return false;
- return true;
- }
- }
- string textSource = text.Source;
- if(textSource != null)
- {
- for(int i = offset, j = textOffset, n = offset + length; i < n; i++, j++)
- if(myProvider[i] != textSource[j])
- return false;
- return true;
- }
- ISourceText textProvider = text.TextProvider;
- if(textProvider == null) { Debug.Assert(false); return false; }
- for(int i = offset, j = textOffset, n = offset + length; i < n; i++, j++)
- if(myProvider[i] != textProvider[j])
- return false;
- return true;
- }
- }
- /// <summary>
- /// Retrieves a substring from this instance. The substring starts at a specified character position and has a specified length.
- /// </summary>
- public string/*!*/ Substring(int position, int length)
- {
- if(position < 0 || length < 0 || position + length > this.Length + 1) { Debug.Assert(false); return ""; }
- if(position + length > this.Length)
- length = this.Length - position; //Allow virtual EOF character to be included in length
- if(this.AsciiStringPtr != null)
- {
- unsafe
- {
- return new String((sbyte*)this.AsciiStringPtr, position, length, System.Text.Encoding.ASCII);
- }
- }
- else if(this.Source != null)
- return this.Source.Substring(position, length);
- else if(this.TextProvider != null)
- return this.TextProvider.Substring(position, length);
- else
- {
- Debug.Assert(false);
- return "";
- }
- }
- /// <summary>
- /// Retrieves the character at the given position. The first character is at position zero.
- /// </summary>
- public char this[int position]
- {
- get
- {
- if(position < 0 || position >= this.Length) { Debug.Assert(false); return (char)0; }
- if(this.AsciiStringPtr != null)
- {
- unsafe
- {
- unchecked
- {
- return (char)*(this.AsciiStringPtr + position);
- }
- }
- }
- else if(this.Source != null)
- return this.Source[position];
- else if(this.TextProvider != null)
- return this.TextProvider[position];
- else
- {
- Debug.Assert(false);
- return (char)0;
- }
- }
- }
- }
-
- /// <summary>
- /// A source document from which an Abstract Syntax Tree has been derived.
- /// </summary>
- public class Document
- {
- /// <summary>
- /// A Guid that identifies the kind of document to applications such as a debugger. Typically System.Diagnostics.SymbolStore.SymDocumentType.Text.
- /// </summary>
- public System.Guid DocumentType;
- /// <summary>
- /// A Guid that identifies the programming language used in the source document. Typically used by a debugger to locate language specific logic.
- /// </summary>
- public System.Guid Language;
- /// <summary>
- /// A Guid that identifies the compiler vendor programming language used in the source document. Typically used by a debugger to locate vendor specific logic.
- /// </summary>
- public System.Guid LanguageVendor;
- /// <summary>
- /// The line number corresponding to the first character in Text. Typically 1 but can be changed by C# preprocessor directives.
- /// </summary>
- public int LineNumber;
- /// <summary>
- /// Indicates that the document contains machine generated source code that should not show up in tools such as debuggers.
- /// Can be set by C# preprocessor directives.
- /// </summary>
- public bool Hidden;
- /// <summary>
- /// The name of the document. Typically a file name. Can be a full or relative file path, or a URI or some other kind of identifier.
- /// </summary>
- public string/*!*/ Name;
- /// <summary>
- /// Contains the source text.
- /// </summary>
- public DocumentText Text;
- public Document()
- {
- this.Name = "";
- //^ base();
- }
- public Document(string/*!*/ name, int lineNumber, string text, System.Guid documentType, System.Guid language, System.Guid languageVendor)
- : this(name, lineNumber, new DocumentText(text), documentType, language, languageVendor)
- {
- }
- public Document(string/*!*/ name, int lineNumber, DocumentText text, System.Guid documentType, System.Guid language, System.Guid languageVendor)
- {
- this.DocumentType = documentType;
- this.Language = language;
- this.LanguageVendor = languageVendor;
- this.LineNumber = lineNumber;
- this.Name = name;
- this.Text = text;
- //^ base();
- }
-
- /// <summary>
- /// Maps the given zero based character position to the number of the source line containing the same character.
- /// Line number counting starts from the value of LineNumber.
- /// </summary>
- public virtual int GetLine(int position)
- {
- int line = 0;
- int column = 0;
- this.GetPosition(position, out line, out column);
- return line + this.LineNumber;
- }
- /// <summary>
- /// Maps the given zero based character position in the entire text to the position of the same character in a source line.
- /// Counting within the source line starts at 1.
- /// </summary>
- public virtual int GetColumn(int position)
- {
- int line = 0;
- int column = 0;
- this.GetPosition(position, out line, out column);
- return column + 1;
- }
-
- /// <summary>
- /// Given a startLine, startColum, endLine and endColumn, this returns the corresponding startPos and endPos. In other words it
- /// converts a range expression in line and columns to a range expressed as a start and end character position.
- /// </summary>
- /// <param name="startLine">The number of the line containing the first character. The number of the first line equals this.LineNumber.</param>
- /// <param name="startColumn">The position of the first character relative to the start of the line. Counting from 1.</param>
- /// <param name="endLine">The number of the line contain the character that immediate follows the last character of the range.</param>
- /// <param name="endColumn">The position, in the last line, of the character that immediately follows the last character of the range.</param>
- /// <param name="startPos">The position in the entire text of the first character of the range, counting from 0.</param>
- /// <param name="endPos">The position in the entire text of the character following the last character of the range.</param>
- public virtual void GetOffsets(int startLine, int startColumn, int endLine, int endColumn, out int startPos, out int endPos)
- {
- lock(this)
- {
- if(this.lineOffsets == null)
- this.ComputeLineOffsets();
- //^ assert this.lineOffsets != null;
- startPos = this.lineOffsets[startLine - this.LineNumber] + startColumn - 1;
- endPos = this.lineOffsets[endLine - this.LineNumber] + endColumn - 1;
- }
- }
-
- /// <summary>
- /// Retrieves a substring from the text of this Document. The substring starts at a specified character position and has a specified length.
- /// </summary>
- public virtual string Substring(int position, int length)
- {
- if(this.Text == null)
- return null;
- return this.Text.Substring(position, length);
- }
-
- /// <summary>
- /// Counts the number of end of line marker sequences in the given text.
- /// </summary>
- protected int GetLineCount(string/*!*/ text)
- {
- int n = text == null ? 0 : text.Length;
- int count = 0;
- for(int i = 0; i < n; i++)
- {
- switch(text[i])
- {
- case '\r':
- if(i + 1 < n && text[i + 1] == '\n')
- i++;
- count++;
- break;
- case '\n':
- case (char)0x2028:
- case (char)0x2029:
- count++;
- break;
- }
- }
- return count;
- }
- /// <summary>An array of offsets, with offset at index i corresponding to the position of the first character of line i, (counting lines from 0).</summary>
- private int[] lineOffsets;
- /// <summary>The number of lines in Text.</summary>
- private int lines;
-
- /// <summary>
- /// Returns the index in this.lineOffsets array such that this.lineOffsets[index] is less than or equal to offset
- /// and offset is less than lineOffsets[index+1]
- /// </summary>
- private int Search(int offset)
- {
- tryAgain:
- int[] lineOffsets = this.lineOffsets;
- int lines = this.lines;
- if(lineOffsets == null) { Debug.Assert(false); return -1; }
- if(offset < 0) { Debug.Assert(false); return -1; }
- int mid = 0;
- int low = 0;
- int high = lines - 1;
- while(low < high)
- {
- mid = (low + high) / 2;
- if(lineOffsets[mid] <= offset)
- {
- if(offset < lineOffsets[mid + 1])
- return mid;
- else
- low = mid + 1;
- }
- else
- high = mid;
- }
- Debug.Assert(lines == this.lines);
- Debug.Assert(lineOffsets[low] <= offset);
- Debug.Assert(offset < lineOffsets[low + 1]);
- if(lineOffsets != this.lineOffsets)
- goto tryAgain;
- return low;
- }
-
- /// <summary>
- /// Maps the given zero based character position in the entire text to a (line, column) pair corresponding to the same position.
- /// Counting within the source line starts at 0. Counting source lines start at 0.
- /// </summary>
- private void GetPosition(int offset, out int line, out int column)
- {
- line = 0;
- column = 0;
- if(offset < 0 || this.Text == null || offset > this.Text.Length) { Debug.Assert(false); return; }
- lock(this)
- {
- if(this.lineOffsets == null)
- this.ComputeLineOffsets();
- if(this.lineOffsets == null) { Debug.Assert(false); return; }
- int[] lineOffsets = this.lineOffsets;
- int index = this.Search(offset);
- Debug.Assert(lineOffsets == this.lineOffsets);
- if(index < 0 || index >= this.lineOffsets.Length) { Debug.Assert(false); return; }
- Debug.Assert(this.lineOffsets[index] <= offset && offset < this.lineOffsets[index + 1]);
- line = index;
- column = offset - this.lineOffsets[index];
- }
- }
- /// <summary>
- /// Adds the given offset to the this.lineOffsets table as the offset corresponding to the start of line this.lines+1.
- /// </summary>
- private void AddOffset(int offset)
- {
- if(this.lineOffsets == null || this.lines < 0) { Debug.Assert(false); return; }
- if(this.lines >= this.lineOffsets.Length)
- {
- int n = this.lineOffsets.Length;
- if(n <= 0)
- n = 16;
- int[] newLineOffsets = new int[n * 2];
- Array.Copy(this.lineOffsets, newLineOffsets, this.lineOffsets.Length);
- this.lineOffsets = newLineOffsets;
- }
- this.lineOffsets[this.lines++] = offset;
- }
- public virtual void InsertOrDeleteLines(int offset, int lineCount)
- {
- if(lineCount == 0)
- return;
- if(offset < 0 || this.Text == null || offset > this.Text.Length) { Debug.Assert(false); return; }
- lock(this)
- {
- if(this.lineOffsets == null)
- if(this.lineOffsets == null)
- this.ComputeLineOffsets();
- if(lineCount < 0)
- this.DeleteLines(offset, -lineCount);
- else
- this.InsertLines(offset, lineCount);
- }
- }
- private void DeleteLines(int offset, int lineCount)
- //^ requires offset >= 0 && this.Text != null && offset < this.Text.Length && lineCount > 0 && this.lineOffsets != null;
- {
- Debug.Assert(offset >= 0 && this.Text != null && offset < this.Text.Length && lineCount > 0 && this.lineOffsets != null);
- int index = this.Search(offset);
- if(index < 0 || index >= this.lines) { Debug.Assert(false); return; }
- for(int i = index + 1; i + lineCount < this.lines; i++)
- {
- this.lineOffsets[i] = this.lineOffsets[i + lineCount];
- }
- this.lines -= lineCount;
- if(this.lines <= index) { Debug.Assert(false); this.lines = index + 1; }
- }
- private void InsertLines(int offset, int lineCount)
- //^ requires offset >= 0 && this.Text != null && offset < this.Text.Length && lineCount > 0 && this.lineOffsets != null;
- {
- Debug.Assert(offset >= 0 && this.Text != null && offset < this.Text.Length && lineCount > 0 && this.lineOffsets != null);
- int index = this.Search(offset);
- if(index < 0 || index >= this.lines) { Debug.Assert(false); return; }
- int n = this.lineOffsets[this.lines - 1];
- for(int i = 0; i < lineCount; i++)
- this.AddOffset(++n);
- for(int i = lineCount; i > 0; i--)
- {
- this.lineOffsets[index + i + 1] = this.lineOffsets[index + 1];
- }
- }
- /// <summary>
- /// Populates this.lineOffsets with an array of offsets, with offset at index i corresponding to the position of the first
- /// character of line i, (counting lines from 0).
- /// </summary>
- private void ComputeLineOffsets()
- //ensures this.lineOffsets != null;
- {
- if(this.Text == null) { Debug.Assert(false); return; }
- int n = this.Text.Length;
- this.lineOffsets = new int[n / 10 + 1];
- this.lines = 0;
- this.AddOffset(0);
- for(int i = 0; i < n; i++)
- {
- switch(this.Text[i])
- {
- case '\r':
- if(i + 1 < n && this.Text[i + 1] == '\n')
- i++;
- this.AddOffset(i + 1);
- break;
- case '\n':
- case (char)0x2028:
- case (char)0x2029:
- this.AddOffset(i + 1);
- break;
- }
- }
- this.AddOffset(n + 1);
- this.AddOffset(n + 2);
- }
-
- /// <summary> Add one to this every time a Document instance gets a unique key.</summary>
- private static int uniqueKeyCounter;
- private int uniqueKey;
- /// <summary>
- /// An integer that uniquely distinguishes this document instance from every other document instance.
- /// This provides an efficient equality test to facilitate hashing.
- /// </summary>
- public int UniqueKey
- {
- get
- {
- if(this.uniqueKey == 0)
- {
- TryAgain:
- int c = Document.uniqueKeyCounter;
- int cp1 = c == int.MaxValue ? 1 : c + 1;
- if(System.Threading.Interlocked.CompareExchange(ref Document.uniqueKeyCounter, cp1, c) != c)
- goto TryAgain;
- this.uniqueKey = cp1;
- }
- return this.uniqueKey;
- }
- }
- }
-
- internal class UnmanagedDocument : Document
- {
- internal UnmanagedDocument(IntPtr ptrToISymUnmanagedDocument)
- {
- //^ base();
- ISymUnmanagedDocument idoc =
- (ISymUnmanagedDocument)System.Runtime.InteropServices.Marshal.GetTypedObjectForIUnknown(ptrToISymUnmanagedDocument, typeof(ISymUnmanagedDocument));
- if(idoc != null)
- {
- try
- {
- idoc.GetDocumentType(out this.DocumentType);
- idoc.GetLanguage(out this.Language);
- idoc.GetLanguageVendor(out this.LanguageVendor);
-
- uint capacity = 1024;
- uint len = 0;
- char[] buffer = new char[capacity];
- while(capacity >= 1024)
- {
- idoc.GetURL(capacity, out len, buffer);
- if(len < capacity)
- break;
- capacity += 1024;
- buffer = new char[capacity];
- }
- if(len > 0)
- this.Name = new String(buffer, 0, (int)len - 1);
- }
- finally
- {
- System.Runtime.InteropServices.Marshal.ReleaseComObject(idoc);
- }
- }
-
- this.LineNumber = -1;
- this.Text = null;
- }
-
- private List<int> lineList = new List<int>();
- private List<int> columnList = new List<int>();
-
- public override int GetLine(int offset)
- {
- return this.lineList[offset];
- }
- public override int GetColumn(int offset)
- {
- return this.columnList[offset];
- }
- public override void GetOffsets(int startLine, int startColumn, int endLine, int endColumn, out int startCol, out int endCol)
- {
- int i = UnmanagedDocument.BinarySearch(this.lineList, startLine);
- List<int> columnList = this.columnList;
- startCol = 0;
- for(int j = i, n = columnList.Count; j < n; j++)
- {
- if(columnList[j] >= startColumn) { startCol = j; break; }
- }
- endCol = 0;
- i = UnmanagedDocument.BinarySearch(this.lineList, endLine);
- for(int j = i, n = columnList.Count; j < n; j++)
- {
- if(columnList[j] >= endColumn) { endCol = j; break; }
- }
- }
-
- private static int BinarySearch(List<int> list, int value)
- {
- int mid = 0;
- int low = 0;
- int high = list.Count - 1;
- while(low < high)
- {
- mid = low + (high - low) / 2;
- if(list[mid] <= value)
- {
- if(list[mid + 1] > value)
- return mid;
- else
- low = mid + 1;
- }
- else
- high = mid;
- }
- return low;
- }
- public override void InsertOrDeleteLines(int offset, int lineCount)
- {
- Debug.Assert(false); //Caller should not be modifying an unmanaged document
- }
-
- internal int GetOffset(uint line, uint column)
- {
- this.lineList.Add((int)line);
- this.columnList.Add((int)column);
- return this.lineList.Count - 1;
- }
- }
-
- /// <summary>
- /// Records a location within a source document that corresponds to an Abstract Syntax Tree node.
- /// </summary>
- public struct SourceContext
- {
- /// <summary>The source document within which the AST node is located. Null if the node is not derived from a source document.</summary>
- public Document Document;
- /// <summary>
- /// The zero based index of the first character beyond the last character in the source document that corresponds to the AST node.
- /// </summary>
- public int EndPos;
- /// <summary>
- /// The zero based index of the first character in the source document that corresponds to the AST node.
- /// </summary>
- public int StartPos;
- public SourceContext(Document document)
- : this(document, 0, document == null ? 0 : (document.Text == null ? 0 : document.Text.Length))
- {
- }
- public SourceContext(Document document, int startPos, int endPos)
- {
- this.Document = document;
- this.StartPos = startPos;
- this.EndPos = endPos;
- }
- public SourceContext(Document/*!*/ document,
- int startLine, int startColumn, int endLine, int endColumn)
- {
- this.Document = document;
- this.Document.GetOffsets(startLine, startColumn, endLine, endColumn, out this.StartPos, out this.EndPos);
- }
- /// <summary>
- /// The number (counting from Document.LineNumber) of the line containing the first character in the source document that corresponds to the AST node.
- /// </summary>
- public int StartLine
- {
- get
- {
- if(this.Document == null)
- return 0;
- return this.Document.GetLine(this.StartPos);
- }
- }
- /// <summary>
- /// The number (counting from one) of the line column containing the first character in the source document that corresponds to the AST node.
- /// </summary>
- public int StartColumn
- {
- get
- {
- if(this.Document == null)
- return 0;
- return this.Document.GetColumn(this.StartPos);
- }
- }
- /// <summary>
- /// The number (counting from Document.LineNumber) of the line containing the first character beyond the last character in the source document that corresponds to the AST node.
- /// </summary>
- public int EndLine
- {
- get
- {
- if(this.Document == null || (this.Document.Text == null && !(this.Document is UnmanagedDocument)))
- return 0;
-
- if(this.Document.Text != null && this.EndPos >= this.Document.Text.Length)
- this.EndPos = this.Document.Text.Length;
-
- return this.Document.GetLine(this.EndPos);
- }
- }
- /// <summary>
- /// The number (counting from one) of the line column containing first character beyond the last character in the source document that corresponds to the AST node.
- /// </summary>
- public int EndColumn
- {
- get
- {
- if(this.Document == null || (this.Document.Text == null && !(this.Document is UnmanagedDocument)))
- return 0;
-
- if(this.Document.Text != null && this.EndPos >= this.Document.Text.Length)
- this.EndPos = this.Document.Text.Length;
-
- return this.Document.GetColumn(this.EndPos);
- }
- }
- /// <summary>
- /// Returns true if the line and column is greater than or equal the position of the first character
- /// and less than or equal to the position of the last character
- /// of the source document that corresponds to the AST node.
- /// </summary>
- /// <param name="line">A line number(counting from Document.LineNumber)</param>
- /// <param name="column">A column number (counting from one)</param>
- /// <returns></returns>
- public bool Encloses(int line, int column)
- {
- if(line < this.StartLine || line > this.EndLine)
- return false;
- if(line == this.StartLine)
- return column >= this.StartColumn && (column <= this.EndColumn || line < this.EndLine);
- if(line == this.EndLine)
- return column <= this.EndColumn;
- return true;
- }
- public bool Encloses(SourceContext sourceContext)
- {
- return this.StartPos <= sourceContext.StartPos && this.EndPos >= sourceContext.EndPos && this.EndPos > sourceContext.StartPos;
- }
- /// <summary>
- /// The substring of the source document that corresponds to the AST node.
- /// </summary>
- public string SourceText
- {
- get
- {
- if(this.Document == null)
- return null;
- return this.Document.Substring(this.StartPos, this.EndPos - this.StartPos);
- }
- }
- }
-
- public sealed class MarshallingInformation
- {
- private string @class;
- private string cookie;
- private int elementSize;
- private NativeType elementType;
- private NativeType nativeType;
- private int numberOfElements;
- private int paramIndex;
- private int size;
- public MarshallingInformation Clone()
- {
- return (MarshallingInformation)base.MemberwiseClone();
- }
- public string Class
- {
- get { return this.@class; }
- set { this.@class = value; }
- }
- public string Cookie
- {
- get { return this.cookie; }
- set { this.cookie = value; }
- }
- public int ElementSize
- {
- get { return this.elementSize; }
- set { this.elementSize = value; }
- }
- public NativeType ElementType
- {
- get { return this.elementType; }
- set { this.elementType = value; }
- }
- public NativeType NativeType
- {
- get { return this.nativeType; }
- set { this.nativeType = value; }
- }
- public int NumberOfElements
- {
- get { return this.numberOfElements; }
- set { this.numberOfElements = value; }
- }
- public int ParamIndex
- {
- get { return this.paramIndex; }
- set { this.paramIndex = value; }
- }
- public int Size
- {
- get { return this.size; }
- set { this.size = value; }
- }
- }
-
- public enum NativeType
- {
- Bool = 0x2, // 4 byte boolean value (true != 0, false == 0)
- I1 = 0x3, // 1 byte signed value
- U1 = 0x4, // 1 byte unsigned value
- I2 = 0x5, // 2 byte signed value
- U2 = 0x6, // 2 byte unsigned value
- I4 = 0x7, // 4 byte signed value
- U4 = 0x8, // 4 byte unsigned value
- I8 = 0x9, // 8 byte signed value
- U8 = 0xa, // 8 byte unsigned value
- R4 = 0xb, // 4 byte floating point
- R8 = 0xc, // 8 byte floating point
- Currency = 0xf, // A currency
- BStr = 0x13, // OLE Unicode BSTR
- LPStr = 0x14, // Ptr to SBCS string
- LPWStr = 0x15, // Ptr to Unicode string
- LPTStr = 0x16, // Ptr to OS preferred (SBCS/Unicode) string
- ByValTStr = 0x17, // OS preferred (SBCS/Unicode) inline string (only valid in structs)
- IUnknown = 0x19, // COM IUnknown pointer.
- IDispatch = 0x1a, // COM IDispatch pointer
- Struct = 0x1b, // Structure
- Interface = 0x1c, // COM interface
- SafeArray = 0x1d, // OLE SafeArray
- ByValArray = 0x1e, // Array of fixed size (only valid in structs)
- SysInt = 0x1f, // Hardware natural sized signed integer
- SysUInt = 0x20,
- VBByRefStr = 0x22,
- AnsiBStr = 0x23, // OLE BSTR containing SBCS characters
- TBStr = 0x24, // Ptr to OS preferred (SBCS/Unicode) BSTR
- VariantBool = 0x25, // OLE defined BOOLEAN (2 bytes, true == -1, false == 0)
- FunctionPtr = 0x26, // Function pointer
- AsAny = 0x28, // Paired with Object type and does runtime marshalling determination
- LPArray = 0x2a, // C style array
- LPStruct = 0x2b, // Pointer to a structure
- CustomMarshaler = 0x2c, // Native type supplied by custom code
- Error = 0x2d,
- NotSpecified = 0x50,
- }
-
- ///0-: Common
- ///1000-: HScript
- ///2000-: EcmaScript
- ///3000-: Zonnon
- ///4000-: Comega
- ///5000-: X++
- ///6000-: Spec#
- ///7000-: Sing#
- ///8000-: Xaml
- ///9000-: C/AL
- ///For your range contact hermanv@microsoft.com
- public enum NodeType
- {
- //Dummy
- Undefined = 0,
-
- //IL instruction node tags
- Add,
- Add_Ovf,
- Add_Ovf_Un,
- And,
- Arglist,
- Box,
- Branch,
- Call,
- Calli,
- Callvirt,
- Castclass,
- Ceq,
- Cgt,
- Cgt_Un,
- Ckfinite,
- Clt,
- Clt_Un,
- Conv_I,
- Conv_I1,
- Conv_I2,
- Conv_I4,
- Conv_I8,
- Conv_Ovf_I,
- Conv_Ovf_I_Un,
- Conv_Ovf_I1,
- Conv_Ovf_I1_Un,
- Conv_Ovf_I2,
- Conv_Ovf_I2_Un,
- Conv_Ovf_I4,
- Conv_Ovf_I4_Un,
- Conv_Ovf_I8,
- Conv_Ovf_I8_Un,
- Conv_Ovf_U,
- Conv_Ovf_U_Un,
- Conv_Ovf_U1,
- Conv_Ovf_U1_Un,
- Conv_Ovf_U2,
- Conv_Ovf_U2_Un,
- Conv_Ovf_U4,
- Conv_Ovf_U4_Un,
- Conv_Ovf_U8,
- Conv_Ovf_U8_Un,
- Conv_R_Un,
- Conv_R4,
- Conv_R8,
- Conv_U,
- Conv_U1,
- Conv_U2,
- Conv_U4,
- Conv_U8,
- Cpblk,
- DebugBreak,
- Div,
- Div_Un,
- Dup,
- EndFilter,
- EndFinally,
- ExceptionHandler,
- Initblk,
- Isinst,
- Jmp,
- Ldftn,
- Ldlen,
- Ldtoken,
- Ldvirtftn,
- Localloc,
- Mkrefany,
- Mul,
- Mul_Ovf,
- Mul_Ovf_Un,
- Neg,
- Nop,
- Not,
- Or,
- Pop,
- ReadOnlyAddressOf,
- Refanytype,
- Refanyval,
- Rem,
- Rem_Un,
- Rethrow,
- Shl,
- Shr,
- Shr_Un,
- Sizeof,
- SkipCheck,
- Sub,
- Sub_Ovf,
- Sub_Ovf_Un,
- SwitchInstruction,
- Throw,
- Unbox,
- UnboxAny,
- Xor,
-
- //AST tags that are relevant to the binary reader
- AddressDereference,
- AddressOf,
- AssignmentStatement,
- Block,
- Catch,
- Construct,
- ConstructArray,
- Eq,
- ExpressionStatement,
- FaultHandler,
- Filter,
- Finally,
- Ge,
- Gt,
- Identifier,
- Indexer,
- Instruction,
- InterfaceExpression,
- Le,
- Literal,
- LogicalNot,
- Lt,
- MemberBinding,
- NamedArgument,
- Namespace,
- Ne,
- Return,
- This,
- Try,
-
- //Metadata node tags
- ArrayType,
- @Assembly,
- AssemblyReference,
- Attribute,
- Class,
- ClassParameter,
- DelegateNode,
- EnumNode,
- Event,
- Field,
- FunctionPointer,
- InstanceInitializer,
- Interface,
- Local,
- Method,
- Module,
- ModuleReference,
- OptionalModifier,
- Parameter,
- Pointer,
- Property,
- Reference,
- RequiredModifier,
- SecurityAttribute,
- StaticInitializer,
- Struct,
- TypeParameter,
-
- // The following NodeType definitions are not required
- // for examining assembly metadata directly from binaries
-
- //Serialization tags used for values that are not leaf nodes.
- Array,
- BlockReference,
- CompilationParameters,
- Document,
- EndOfRecord,
- Expression,
- Guid,
- List,
- MarshallingInformation,
- Member,
- MemberReference,
- MissingBlockReference,
- MissingExpression,
- MissingMemberReference,
- String,
- StringDictionary,
- TypeNode,
- Uri,
- XmlNode,
-
- //Source-based AST node tags
- AddEventHandler,
- AliasDefinition,
- AnonymousNestedFunction,
- ApplyToAll,
- ArglistArgumentExpression,
- ArglistExpression,
- ArrayTypeExpression,
- As,
- Assertion,
- AssignmentExpression,
- Assumption,
- Base,
-
- BlockExpression,
- BoxedTypeExpression,
- ClassExpression,
- CoerceTuple,
- CollectionEnumerator,
- Comma,
- Compilation,
- CompilationUnit,
- CompilationUnitSnippet,
- Conditional,
- ConstructDelegate,
- ConstructFlexArray,
- ConstructIterator,
- ConstructTuple,
- Continue,
- CopyReference,
- CurrentClosure,
- Decrement,
- DefaultValue,
- DoWhile,
- Exit,
- ExplicitCoercion,
- ExpressionSnippet,
- FieldInitializerBlock,
- Fixed,
- FlexArrayTypeExpression,
- For,
- ForEach,
- FunctionDeclaration,
- FunctionTypeExpression,
- Goto,
- GotoCase,
- If,
- ImplicitThis,
- Increment,
- InvariantTypeExpression,
- Is,
- LabeledStatement,
- LocalDeclaration,
- LocalDeclarationsStatement,
- Lock,
- LogicalAnd,
- LogicalOr,
- LRExpression,
- MethodCall,
- NameBinding,
- NonEmptyStreamTypeExpression,
- NonNullableTypeExpression,
- NonNullTypeExpression,
- NullableTypeExpression,
- NullCoalesingExpression,
- OutAddress,
- Parentheses,
- PointerTypeExpression,
- PostfixExpression,
- PrefixExpression,
- QualifiedIdentifer,
- RefAddress,
- ReferenceTypeExpression,
- RefTypeExpression,
- RefValueExpression,
- RemoveEventHandler,
- Repeat,
- ResourceUse,
- SetterValue,
- StackAlloc,
- StatementSnippet,
- StreamTypeExpression,
- Switch,
- SwitchCase,
- SwitchCaseBottom,
- TemplateInstance,
- TupleTypeExpression,
- TypeExpression,
- TypeIntersectionExpression,
- TypeMemberSnippet,
- Typeof,
- TypeReference,
- Typeswitch,
- TypeswitchCase,
- TypeUnionExpression,
- UnaryPlus,
- UsedNamespace,
- VariableDeclaration,
- While,
- Yield,
-
- //Extended metadata node tags
- ConstrainedType,
- TupleType,
- TypeAlias,
- TypeIntersection,
- TypeUnion,
-
- //Query node tags
- Composition,
- QueryAggregate,
- QueryAlias,
- QueryAll,
- QueryAny,
- QueryAxis,
- QueryCommit,
- QueryContext,
- QueryDelete,
- QueryDifference,
- QueryDistinct,
- QueryExists,
- QueryFilter,
- QueryGeneratedType,
- QueryGroupBy,
- QueryInsert,
- QueryIntersection,
- QueryIterator,
- QueryJoin,
- QueryLimit,
- QueryOrderBy,
- QueryOrderItem,
- QueryPosition,
- QueryProject,
- QueryQuantifiedExpression,
- QueryRollback,
- QuerySelect,
- QuerySingleton,
- QueryTransact,
- QueryTypeFilter,
- QueryUnion,
- QueryUpdate,
- QueryYielder,
-
- //Contract node tags
- Acquire,
- Comprehension,
- ComprehensionBinding,
- Ensures,
- EnsuresExceptional,
- EnsuresNormal,
- Iff,
- Implies,
- Invariant,
- LogicalEqual,
- LogicalImply,
- Maplet,
- MethodContract,
- Modelfield,
- ModelfieldContract,
- OldExpression,
- Range,
- Read,
- Requires,
- RequiresOtherwise,
- RequiresPlain,
- TypeContract,
- Write,
-
- //Node tags for explicit modifiers in front-end
- OptionalModifierTypeExpression,
- RequiredModifierTypeExpression,
-
- //Temporary node tags
- Count,
- Exists,
- ExistsUnique,
- Forall,
- Max,
- Min,
- Product,
- Sum,
- Quantifier,
- }
-
- [Flags]
- public enum AssemblyFlags
- {
- None = 0x0000,
- PublicKey = 0x0001,
- Library = 0x0002,
- Platform = 0x0004,
- NowPlatform = 0x0006,
- SideBySideCompatible = 0x0000,
- NonSideBySideCompatible = 0x0010,
- NonSideBySideProcess = 0x0020,
- NonSideBySideMachine = 0x0030,
- CompatibilityMask = 0x00F0,
- Retargetable = 0x0100,
- DisableJITcompileOptimizer = 0x4000,
- EnableJITcompileTracking = 0x8000
- }
-
- public enum AssemblyHashAlgorithm
- {
- None = 0x0000,
- MD5 = 0x8003,
- SHA1 = 0x8004
- }
-
- [Flags]
- public enum CallingConventionFlags
- {
- Default = 0x0,
- C = 0x1,
- StandardCall = 0x2,
- ThisCall = 0x3,
- FastCall = 0x4,
- VarArg = 0x5,
- ArgumentConvention = 0x7,
- Generic = 0x10,
- HasThis = 0x20,
- …
Large files files are truncated, but you can click here to view the full file