diff --git a/src/Libraries/NRefactory/.gitattributes b/src/Libraries/NRefactory/.gitattributes
new file mode 100644
index 0000000000..1a15330249
--- /dev/null
+++ b/src/Libraries/NRefactory/.gitattributes
@@ -0,0 +1,2 @@
+*.sln -crlf
+*.csproj -crlf
\ No newline at end of file
diff --git a/src/Libraries/NRefactory/.gitignore b/src/Libraries/NRefactory/.gitignore
new file mode 100644
index 0000000000..a5807eb16d
--- /dev/null
+++ b/src/Libraries/NRefactory/.gitignore
@@ -0,0 +1,2 @@
+/lib/*.dll
+/ICSharpCode.NRefactory.Tests/PartCover/*
\ No newline at end of file
diff --git a/src/Libraries/NRefactory/ICSharpCode.Editor/ICSharpCode.Editor.csproj b/src/Libraries/NRefactory/ICSharpCode.Editor/ICSharpCode.Editor.csproj
new file mode 100644
index 0000000000..f3baf10f7b
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.Editor/ICSharpCode.Editor.csproj
@@ -0,0 +1,72 @@
+
+
+
+ {F054A788-B591-4561-A8BA-AE745BBEB817}
+ Debug
+ x86
+ Library
+ ICSharpCode.Editor
+ ICSharpCode.Editor
+ v4.0
+ Client
+ Properties
+ False
+ False
+ OnBuildSuccess
+ bin\Debug\ICSharpCode.Editor.xml
+ False
+ False
+ 4
+ false
+ False
+
+
+ x86
+ False
+ Auto
+ 4194304
+ 4096
+
+
+ bin\Debug\
+ true
+ Full
+ False
+ True
+ DEBUG;TRACE
+ Project
+
+
+ bin\Release\
+ False
+ None
+ True
+ False
+ TRACE
+
+
+
+
+ 3.5
+
+
+
+ 3.5
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Libraries/NRefactory/ICSharpCode.Editor/IDocument.cs b/src/Libraries/NRefactory/ICSharpCode.Editor/IDocument.cs
new file mode 100644
index 0000000000..925eaee669
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.Editor/IDocument.cs
@@ -0,0 +1,141 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT license (for details please see \doc\license.txt)
+
+using System;
+
+namespace ICSharpCode.Editor
+{
+ ///
+ /// A document representing a source code file for refactoring.
+ /// Line and column counting starts at 1.
+ /// Offset counting starts at 0.
+ ///
+ public interface IDocument : ITextSource, IServiceProvider
+ {
+ ///
+ /// Gets/Sets the text of the whole document..
+ ///
+ new string Text { get; set; } // hides TextBuffer.Text to add the setter
+
+ ///
+ /// Is raised when the Text property changes.
+ ///
+ event EventHandler TextChanged;
+
+ ///
+ /// Gets the total number of lines in the document.
+ ///
+ int TotalNumberOfLines { get; }
+
+ ///
+ /// Gets the document line with the specified number.
+ ///
+ /// The number of the line to retrieve. The first line has number 1.
+ IDocumentLine GetLine(int lineNumber);
+
+ ///
+ /// Gets the document line that contains the specified offset.
+ ///
+ IDocumentLine GetLineByOffset(int offset);
+
+ ///
+ /// Gets the offset from a text location.
+ ///
+ ///
+ int GetOffset(int line, int column);
+
+ ///
+ /// Gets the offset from a text location.
+ ///
+ ///
+ int GetOffset(TextLocation location);
+
+ ///
+ /// Gets the location from an offset.
+ ///
+ ///
+ TextLocation GetLocation(int offset);
+
+ ///
+ /// Inserts text.
+ ///
+ /// The offset at which the text is inserted.
+ /// The new text.
+ ///
+ /// Anchors positioned exactly at the insertion offset will move according to their movement type.
+ /// For AnchorMovementType.Default, they will move behind the inserted text.
+ /// The caret will also move behind the inserted text.
+ ///
+ void Insert(int offset, string text);
+
+ ///
+ /// Inserts text.
+ ///
+ /// The offset at which the text is inserted.
+ /// The new text.
+ ///
+ /// Anchors positioned exactly at the insertion offset will move according to the anchor's movement type.
+ /// For AnchorMovementType.Default, they will move according to the movement type specified by this parameter.
+ /// The caret will also move according to the parameter.
+ ///
+ void Insert(int offset, string text, AnchorMovementType defaultAnchorMovementType);
+
+ ///
+ /// Removes text.
+ ///
+ /// Starting offset of the text to be removed.
+ /// Length of the text to be removed.
+ void Remove(int offset, int length);
+
+ ///
+ /// Replaces text.
+ ///
+ /// The starting offset of the text to be replaced.
+ /// The length of the text to be replaced.
+ /// The new text.
+ void Replace(int offset, int length, string newText);
+
+ ///
+ /// Make the document combine the following actions into a single
+ /// action for undo purposes.
+ ///
+ void StartUndoableAction();
+
+ ///
+ /// Ends the undoable action started with .
+ ///
+ void EndUndoableAction();
+
+ ///
+ /// Creates an undo group. Dispose the returned value to close the undo group.
+ ///
+ /// An object that closes the undo group when Dispose() is called.
+ IDisposable OpenUndoGroup();
+
+ ///
+ /// Creates a new at the specified offset.
+ ///
+ ///
+ ITextAnchor CreateAnchor(int offset);
+
+ ///
+ /// This event is called directly before a change is applied to the document.
+ ///
+ ///
+ /// It is invalid to modify the document within this event handler.
+ /// Aborting the change (by throwing an exception) is likely to cause corruption of data structures
+ /// that listen to the Changing and Changed events.
+ ///
+ event EventHandler Changing;
+
+ ///
+ /// This event is called directly after a change is applied to the document.
+ ///
+ ///
+ /// It is invalid to modify the document within this event handler.
+ /// Aborting the event handler (by throwing an exception) is likely to cause corruption of data structures
+ /// that listen to the Changing and Changed events.
+ ///
+ event EventHandler Changed;
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.Editor/IDocumentLine.cs b/src/Libraries/NRefactory/ICSharpCode.Editor/IDocumentLine.cs
new file mode 100644
index 0000000000..982a8cd2be
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.Editor/IDocumentLine.cs
@@ -0,0 +1,30 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT license (for details please see \doc\license.txt)
+
+using System;
+
+namespace ICSharpCode.Editor
+{
+ ///
+ /// A line inside a .
+ ///
+ public interface IDocumentLine : ISegment
+ {
+ ///
+ /// Gets the length of this line, including the line delimiter.
+ ///
+ int TotalLength { get; }
+
+ ///
+ /// Gets the length of the line terminator.
+ /// Returns 1 or 2; or 0 at the end of the document.
+ ///
+ int DelimiterLength { get; }
+
+ ///
+ /// Gets the number of this line.
+ /// The first line has the number 1.
+ ///
+ int LineNumber { get; }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.Editor/ISegment.cs b/src/Libraries/NRefactory/ICSharpCode.Editor/ISegment.cs
new file mode 100644
index 0000000000..bf8ac3c089
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.Editor/ISegment.cs
@@ -0,0 +1,55 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT license (for details please see \doc\license.txt)
+
+using System;
+
+namespace ICSharpCode.Editor
+{
+ ///
+ /// An (Offset,Length)-pair.
+ ///
+ public interface ISegment
+ {
+ ///
+ /// Gets the start offset of the segment.
+ ///
+ int Offset { get; }
+
+ ///
+ /// Gets the length of the segment.
+ ///
+ /// Must not be negative.
+ int Length { get; }
+
+ ///
+ /// Gets the end offset of the segment.
+ ///
+ /// EndOffset = Offset + Length;
+ int EndOffset { get; }
+ }
+
+ ///
+ /// Extension methods for .
+ ///
+ public static class ISegmentExtensions
+ {
+ ///
+ /// Gets whether the segment contains the offset.
+ ///
+ ///
+ /// True, if offset is between segment.Start and segment.End (inclusive); otherwise, false.
+ ///
+ public static bool Contains (this ISegment segment, int offset)
+ {
+ return segment.Offset <= offset && offset <= segment.EndOffset;
+ }
+
+ ///
+ /// True, if the segment contains the specified segment, false otherwise.
+ ///
+ public static bool Contains (this ISegment thisSegment, ISegment segment)
+ {
+ return segment != null && thisSegment.Offset <= segment.Offset && segment.EndOffset <= thisSegment.EndOffset;
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.Editor/ITextAnchor.cs b/src/Libraries/NRefactory/ICSharpCode.Editor/ITextAnchor.cs
new file mode 100644
index 0000000000..dfc95c9e74
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.Editor/ITextAnchor.cs
@@ -0,0 +1,102 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT license (for details please see \doc\license.txt)
+
+using System;
+
+namespace ICSharpCode.Editor
+{
+ ///
+ /// The TextAnchor class references an offset (a position between two characters).
+ /// It automatically updates the offset when text is inserted/removed in front of the anchor.
+ ///
+ ///
+ /// Use the property to get the offset from a text anchor.
+ /// Use the method to create an anchor from an offset.
+ ///
+ ///
+ /// The document will automatically update all text anchors; and because it uses weak references to do so,
+ /// the garbage collector can simply collect the anchor object when you don't need it anymore.
+ ///
+ /// Moreover, the document is able to efficiently update a large number of anchors without having to look
+ /// at each anchor object individually. Updating the offsets of all anchors usually only takes time logarithmic
+ /// to the number of anchors. Retrieving the property also runs in O(lg N).
+ ///
+ ///
+ /// Usage:
+ /// TextAnchor anchor = document.CreateAnchor(offset);
+ /// ChangeMyDocument();
+ /// int newOffset = anchor.Offset;
+ ///
+ ///
+ public interface ITextAnchor
+ {
+ ///
+ /// Gets the text location of this anchor.
+ ///
+ /// Thrown when trying to get the Offset from a deleted anchor.
+ TextLocation Location { get; }
+
+ ///
+ /// Gets the offset of the text anchor.
+ ///
+ /// Thrown when trying to get the Offset from a deleted anchor.
+ int Offset { get; }
+
+ ///
+ /// Controls how the anchor moves.
+ ///
+ AnchorMovementType MovementType { get; set; }
+
+ ///
+ /// Specifies whether the anchor survives deletion of the text containing it.
+ /// false: The anchor is deleted when the a selection that includes the anchor is deleted.
+ /// true: The anchor is not deleted.
+ ///
+ bool SurviveDeletion { get; set; }
+
+ ///
+ /// Gets whether the anchor was deleted.
+ ///
+ bool IsDeleted { get; }
+
+ ///
+ /// Occurs after the anchor was deleted.
+ ///
+ event EventHandler Deleted;
+
+ ///
+ /// Gets the line number of the anchor.
+ ///
+ /// Thrown when trying to get the Offset from a deleted anchor.
+ int Line { get; }
+
+ ///
+ /// Gets the column number of this anchor.
+ ///
+ /// Thrown when trying to get the Offset from a deleted anchor.
+ int Column { get; }
+ }
+
+ ///
+ /// Defines how a text anchor moves.
+ ///
+ public enum AnchorMovementType
+ {
+ ///
+ /// When text is inserted at the anchor position, the type of the insertion
+ /// determines where the caret moves to. For normal insertions, the anchor will stay
+ /// behind the inserted text.
+ ///
+ Default,
+ ///
+ /// Behaves like a start marker - when text is inserted at the anchor position, the anchor will stay
+ /// before the inserted text.
+ ///
+ BeforeInsertion,
+ ///
+ /// Behave like an end marker - when text is insered at the anchor position, the anchor will move
+ /// after the inserted text.
+ ///
+ AfterInsertion
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.Editor/ITextEditor.cs b/src/Libraries/NRefactory/ICSharpCode.Editor/ITextEditor.cs
new file mode 100644
index 0000000000..6d15eb7699
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.Editor/ITextEditor.cs
@@ -0,0 +1,100 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT license (for details please see \doc\license.txt)
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace ICSharpCode.Editor
+{
+ ///
+ /// Interface for text editors.
+ ///
+ public interface ITextEditor : IServiceProvider
+ {
+ ///
+ /// Gets the document that is being edited.
+ ///
+ IDocument Document { get; }
+
+ ///
+ /// Gets an object that represents the caret inside this text editor.
+ ///
+ ITextEditorCaret Caret { get; }
+
+ ///
+ /// Sets the caret to the specified line/column and brings the caret into view.
+ ///
+ void JumpTo(int line, int column);
+
+ ///
+ /// Gets the start offset of the selection.
+ ///
+ int SelectionStart { get; }
+
+ ///
+ /// Gets the length of the selection.
+ ///
+ int SelectionLength { get; }
+
+ ///
+ /// Gets/Sets the selected text.
+ ///
+ string SelectedText { get; set; }
+
+ ///
+ /// Sets the selection.
+ ///
+ /// Start offset of the selection
+ /// Length of the selection
+ void Select(int selectionStart, int selectionLength);
+
+ ///
+ /// Shows the specified linked elements, and allows the user to edit them.
+ ///
+ ///
+ /// Returns true when the user has finished editing the elements and pressed Return;
+ /// or false when editing is aborted for any reason.
+ ///
+ ///
+ /// The user can also edit other parts of the document (or other documents) while in link mode.
+ /// In case of success (true return value), this method will update the offsets of the linked elements
+ /// to reflect the changes done by the user.
+ /// If the text editor does not support link mode, it will immediately return false.
+ ///
+// Task ShowLinkedElements(IEnumerable linkedElements);
+ }
+
+ ///
+ /// Represents the caret in a text editor.
+ ///
+ public interface ITextEditorCaret
+ {
+ ///
+ /// Gets/Sets the caret offset;
+ ///
+ int Offset { get; set; }
+
+ ///
+ /// Gets/Sets the caret line number.
+ /// Line numbers are counted starting from 1.
+ ///
+ int Line { get; set; }
+
+ ///
+ /// Gets/Sets the caret column number.
+ /// Column numbers are counted starting from 1.
+ ///
+ int Column { get; set; }
+
+ ///
+ /// Gets/sets the caret location.
+ ///
+ TextLocation Location { get; set; }
+
+ ///
+ /// Is raised whenever the location of the caret has changed.
+ ///
+ event EventHandler LocationChanged;
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.Editor/ITextSource.cs b/src/Libraries/NRefactory/ICSharpCode.Editor/ITextSource.cs
new file mode 100644
index 0000000000..d5c6f9e9f3
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.Editor/ITextSource.cs
@@ -0,0 +1,147 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT license (for details please see \doc\license.txt)
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+
+namespace ICSharpCode.Editor
+{
+ ///
+ /// A read-only view on a (potentially mutable) text source.
+ /// The IDocument interfaces derives from this interface.
+ ///
+ public interface ITextSource
+ {
+ ///
+ /// Gets a version identifier for this text source.
+ /// Returns null for unversioned text sources.
+ ///
+ ITextSourceVersion Version { get; }
+
+ ///
+ /// Creates an immutable snapshot of this text source.
+ /// Unlike all other methods in this interface, this method is thread-safe.
+ ///
+ ITextSource CreateSnapshot();
+
+ ///
+ /// Creates an immutable snapshot of a part of this text source.
+ /// Unlike all other methods in this interface, this method is thread-safe.
+ ///
+ ITextSource CreateSnapshot(int offset, int length);
+
+ ///
+ /// Creates a new TextReader to read from this text source.
+ ///
+ TextReader CreateReader();
+
+ ///
+ /// Creates a new TextReader to read from this text source.
+ ///
+ TextReader CreateReader(int offset, int length);
+
+ ///
+ /// Gets the total text length.
+ ///
+ /// The length of the text, in characters.
+ /// This is the same as Text.Length, but is more efficient because
+ /// it doesn't require creating a String object.
+ int TextLength { get; }
+
+ ///
+ /// Gets the whole text as string.
+ ///
+ string Text { get; }
+
+ ///
+ /// Gets a character at the specified position in the document.
+ ///
+ /// The index of the character to get.
+ /// Offset is outside the valid range (0 to TextLength-1).
+ /// The character at the specified position.
+ /// This is the same as Text[offset], but is more efficient because
+ /// it doesn't require creating a String object.
+ char GetCharAt(int offset);
+
+ ///
+ /// Retrieves the text for a portion of the document.
+ ///
+ /// offset or length is outside the valid range.
+ /// This is the same as Text.Substring, but is more efficient because
+ /// it doesn't require creating a String object for the whole document.
+ string GetText(int offset, int length);
+
+ ///
+ /// Retrieves the text for a portion of the document.
+ ///
+ /// offset or length is outside the valid range.
+ string GetText(ISegment segment);
+
+ ///
+ /// Gets the index of the first occurrence of any character in the specified array.
+ ///
+ /// Characters to search for
+ /// Start index of the search.
+ /// Length of the area to search.
+ /// The first index where any character was found; or -1 if no occurrence was found.
+ int IndexOfAny(char[] anyOf, int startIndex, int count);
+
+ /* What about:
+ void Insert (int offset, string value);
+ void Remove (int offset, int count);
+ void Remove (ISegment segment);
+
+ void Replace (int offset, int count, string value);
+
+ Or more search operations:
+
+ IEnumerable SearchForward (string pattern, int startIndex);
+ IEnumerable SearchForwardIgnoreCase (string pattern, int startIndex);
+
+ IEnumerable SearchBackward (string pattern, int startIndex);
+ IEnumerable SearchBackwardIgnoreCase (string pattern, int startIndex);
+ */
+ }
+
+ ///
+ /// Represents a version identifier for a text source.
+ ///
+ ///
+ /// Verions can be used to efficiently detect whether a document has changed and needs reparsing;
+ /// or even to implement incremental parsers.
+ /// It is a separate class from ITextBuffer to allow the GC to collect the text buffer while
+ /// the version checkpoint is still in use.
+ ///
+ public interface ITextSourceVersion
+ {
+ ///
+ /// Gets whether this checkpoint belongs to the same document as the other checkpoint.
+ ///
+ bool BelongsToSameDocumentAs(ITextSourceVersion other);
+
+ ///
+ /// Compares the age of this checkpoint to the other checkpoint.
+ ///
+ /// This method is thread-safe.
+ /// Raised if 'other' belongs to a different document than this version.
+ /// -1 if this version is older than .
+ /// 0 if this version instance represents the same version as .
+ /// 1 if this version is newer than .
+ int CompareAge(ITextSourceVersion other);
+
+ ///
+ /// Gets the changes from this checkpoint to the other checkpoint.
+ /// If 'other' is older than this checkpoint, reverse changes are calculated.
+ ///
+ /// This method is thread-safe.
+ /// Raised if 'other' belongs to a different document than this checkpoint.
+ IEnumerable GetChangesTo(ITextSourceVersion other);
+
+ ///
+ /// Calculates where the offset has moved in the other buffer version.
+ ///
+ /// Raised if 'other' belongs to a different document than this checkpoint.
+ int MoveOffsetTo(ITextSourceVersion other, int oldOffset, AnchorMovementType movement);
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.Editor/LinkedElement.cs b/src/Libraries/NRefactory/ICSharpCode.Editor/LinkedElement.cs
new file mode 100644
index 0000000000..104e53e8a2
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.Editor/LinkedElement.cs
@@ -0,0 +1,68 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT license (for details please see \doc\license.txt)
+
+using System;
+
+namespace ICSharpCode.Editor
+{
+// I'm not sure if we need this.
+// How about a method in the context - this method could wrap the internal representation.
+// public void StartTextLinkMode (int linkLength, IEnumerable offsets)
+// and maybe then variations taking more than one link element ?
+
+// ///
+// /// Represents an element in the text editor that is either editable, or bound to another editable element.
+// /// Used with
+// ///
+// public class LinkedElement
+// {
+// LinkedElement boundTo;
+//
+// ///
+// /// Gets/Sets the start offset of this linked element.
+// ///
+// public int StartOffset { get; set; }
+//
+// ///
+// /// Gets/Sets the end offset of this linked element.
+// ///
+// public int EndOffset { get; set; }
+//
+// ///
+// /// Gets the linked element to which this element is bound.
+// ///
+// public LinkedElement BoundTo {
+// get { return boundTo; }
+// }
+//
+// ///
+// /// Gets whether this element is editable. Returns true if this element is not bound.
+// ///
+// public bool IsEditable {
+// get { return boundTo == null; }
+// }
+//
+// ///
+// /// Creates a new editable element.
+// ///
+// public LinkedElement(int startOffset, int endOffset)
+// {
+// this.StartOffset = startOffset;
+// this.EndOffset = endOffset;
+// }
+//
+// ///
+// /// Creates a new element that is bound to .
+// ///
+// public LinkedElement(int startOffset, int endOffset, LinkedElement boundTo)
+// {
+// if (boundTo == null)
+// throw new ArgumentNullException("boundTo");
+// this.StartOffset = startOffset;
+// this.EndOffset = endOffset;
+// while (boundTo.boundTo != null)
+// boundTo = boundTo.boundTo;
+// this.boundTo = boundTo;
+// }
+// }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.Editor/Properties/AssemblyInfo.cs b/src/Libraries/NRefactory/ICSharpCode.Editor/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..7d06f87441
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.Editor/Properties/AssemblyInfo.cs
@@ -0,0 +1,31 @@
+#region Using directives
+
+using System;
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+#endregion
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("ICSharpCode.Editor")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("ICSharpCode.Editor")]
+[assembly: AssemblyCopyright("Copyright 2011")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// This sets the default COM visibility of types in the assembly to invisible.
+// If you need to expose a type to COM, use [ComVisible(true)] on that type.
+[assembly: ComVisible(false)]
+
+// The assembly version has following format :
+//
+// Major.Minor.Build.Revision
+//
+// You can specify all the values or you can use the default the Revision and
+// Build Numbers by using the '*' as shown below:
+[assembly: AssemblyVersion("1.0.*")]
diff --git a/src/Libraries/NRefactory/ICSharpCode.Editor/ReadOnlyDocument.cs b/src/Libraries/NRefactory/ICSharpCode.Editor/ReadOnlyDocument.cs
new file mode 100644
index 0000000000..d175cea82a
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.Editor/ReadOnlyDocument.cs
@@ -0,0 +1,321 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT license (for details please see \doc\license.txt)
+
+using System;
+using System.Collections.Generic;
+
+namespace ICSharpCode.Editor
+{
+ ///
+ /// Read-only implementation of .
+ ///
+ public sealed class ReadOnlyDocument : IDocument
+ {
+ readonly ITextSource textSource;
+ int[] lines;
+
+ static readonly char[] newline = { '\r', '\n' };
+
+ ///
+ /// Creates a new ReadOnlyDocument from the given text source.
+ ///
+ public ReadOnlyDocument(ITextSource textSource)
+ {
+ if (textSource == null)
+ throw new ArgumentNullException("textSource");
+ // ensure that underlying buffer is immutable
+ this.textSource = textSource.CreateSnapshot();
+ List lines = new List();
+ lines.Add(0);
+ int offset = 0;
+ int textLength = textSource.TextLength;
+ while ((offset = textSource.IndexOfAny(newline, offset, textLength - offset)) >= 0) {
+ offset++;
+ if (textSource.GetCharAt(offset - 1) == '\r' && offset < textLength && textSource.GetCharAt(offset) == '\n') {
+ offset++;
+ }
+ lines.Add(offset);
+ }
+ this.lines = lines.ToArray();
+ }
+
+ ///
+ /// Creates a new ReadOnlyDocument from the given string.
+ ///
+ public ReadOnlyDocument(string text)
+ : this(new StringTextSource(text))
+ {
+ }
+
+ ///
+ public IDocumentLine GetLine(int lineNumber)
+ {
+ if (lineNumber < 1 || lineNumber > lines.Length)
+ throw new ArgumentOutOfRangeException("lineNumber", lineNumber, "Value must be between 1 and " + lines.Length);
+ return new ReadOnlyDocumentLine(this, lineNumber);
+ }
+
+ sealed class ReadOnlyDocumentLine : IDocumentLine
+ {
+ readonly ReadOnlyDocument doc;
+ readonly int lineNumber;
+ readonly int offset, endOffset;
+
+ public ReadOnlyDocumentLine(ReadOnlyDocument doc, int lineNumber)
+ {
+ this.doc = doc;
+ this.lineNumber = lineNumber;
+ this.offset = doc.GetStartOffset(lineNumber);
+ this.endOffset = doc.GetEndOffset(lineNumber);
+ }
+
+ public int Offset {
+ get { return offset; }
+ }
+
+ public int Length {
+ get { return endOffset - offset; }
+ }
+
+ public int EndOffset {
+ get { return endOffset; }
+ }
+
+ public int TotalLength {
+ get {
+ return doc.GetTotalEndOffset(lineNumber) - offset;
+ }
+ }
+
+ public int DelimiterLength {
+ get {
+ return doc.GetTotalEndOffset(lineNumber) - endOffset;
+ }
+ }
+
+ public int LineNumber {
+ get { return lineNumber; }
+ }
+ }
+
+ int GetStartOffset(int lineNumber)
+ {
+ return lines[lineNumber-1];
+ }
+
+ int GetTotalEndOffset(int lineNumber)
+ {
+ return lineNumber < lines.Length ? lines[lineNumber] : textSource.TextLength;
+ }
+
+ int GetEndOffset(int lineNumber)
+ {
+ if (lineNumber == lines.Length)
+ return textSource.TextLength;
+ int off = lines[lineNumber] - 1;
+ if (off > 0 && textSource.GetCharAt(off - 1) == '\r' && textSource.GetCharAt(off) == '\n')
+ off--;
+ return off;
+ }
+
+ ///
+ public IDocumentLine GetLineByOffset(int offset)
+ {
+ return GetLine(GetLineNumberForOffset(offset));
+ }
+
+ int GetLineNumberForOffset(int offset)
+ {
+ int r = Array.BinarySearch(lines, offset);
+ return r < 0 ? ~r : r + 1;
+ }
+
+ ///
+ public int GetOffset(int line, int column)
+ {
+ if (line < 1 || line > lines.Length)
+ throw new ArgumentOutOfRangeException("line", line, "Value must be between 1 and " + lines.Length);
+ int lineStart = GetStartOffset(line);
+ if (column <= 0)
+ return lineStart;
+ int lineEnd = GetEndOffset(line);
+ if (column >= lineEnd - lineStart)
+ return lineEnd;
+ return lineStart + column - 1;
+ }
+
+ ///
+ public int GetOffset(TextLocation location)
+ {
+ return GetOffset(location.Line, location.Column);
+ }
+
+ ///
+ public TextLocation GetLocation(int offset)
+ {
+ if (offset < 0 || offset > textSource.TextLength)
+ throw new ArgumentOutOfRangeException("offset", offset, "Value must be between 0 and " + textSource.TextLength);
+ int line = GetLineNumberForOffset(offset);
+ return new TextLocation(offset-GetStartOffset(line)+1, line);
+ }
+
+ ///
+ public string Text {
+ get { return textSource.Text; }
+ set {
+ throw new NotSupportedException();
+ }
+ }
+
+ ///
+ public int TotalNumberOfLines {
+ get { return lines.Length; }
+ }
+
+ ITextSourceVersion ITextSource.Version {
+ get { return null; }
+ }
+
+ ///
+ public int TextLength {
+ get { return textSource.TextLength; }
+ }
+
+ event EventHandler IDocument.Changing { add {} remove {} }
+
+ event EventHandler IDocument.Changed { add {} remove {} }
+
+ event EventHandler IDocument.TextChanged { add {} remove {} }
+
+ void IDocument.Insert(int offset, string text)
+ {
+ throw new NotSupportedException();
+ }
+
+ void IDocument.Insert(int offset, string text, AnchorMovementType defaultAnchorMovementType)
+ {
+ throw new NotSupportedException();
+ }
+
+ void IDocument.Remove(int offset, int length)
+ {
+ throw new NotSupportedException();
+ }
+
+ void IDocument.Replace(int offset, int length, string newText)
+ {
+ throw new NotSupportedException();
+ }
+
+ void IDocument.StartUndoableAction()
+ {
+ }
+
+ void IDocument.EndUndoableAction()
+ {
+ }
+
+ IDisposable IDocument.OpenUndoGroup()
+ {
+ return null;
+ }
+
+ ///
+ public ITextAnchor CreateAnchor(int offset)
+ {
+ return new ReadOnlyDocumentTextAnchor(GetLocation(offset), offset);
+ }
+
+ sealed class ReadOnlyDocumentTextAnchor : ITextAnchor
+ {
+ readonly TextLocation location;
+ readonly int offset;
+
+ public ReadOnlyDocumentTextAnchor(TextLocation location, int offset)
+ {
+ this.location = location;
+ this.offset = offset;
+ }
+
+ public event EventHandler Deleted { add {} remove {} }
+
+ public TextLocation Location {
+ get { return location; }
+ }
+
+ public int Offset {
+ get { return offset; }
+ }
+
+ public AnchorMovementType MovementType { get; set; }
+
+ public bool SurviveDeletion { get; set; }
+
+ public bool IsDeleted {
+ get { return false; }
+ }
+
+ public int Line {
+ get { return location.Line; }
+ }
+
+ public int Column {
+ get { return location.Column; }
+ }
+ }
+
+ ///
+ public ITextSource CreateSnapshot()
+ {
+ return textSource; // textBuffer is immutable
+ }
+
+ ///
+ public ITextSource CreateSnapshot(int offset, int length)
+ {
+ return textSource.CreateSnapshot(offset, length);
+ }
+
+ ///
+ public System.IO.TextReader CreateReader()
+ {
+ return textSource.CreateReader();
+ }
+
+ ///
+ public System.IO.TextReader CreateReader(int offset, int length)
+ {
+ return textSource.CreateReader(offset, length);
+ }
+
+ ///
+ public char GetCharAt(int offset)
+ {
+ return textSource.GetCharAt(offset);
+ }
+
+ ///
+ public string GetText(int offset, int length)
+ {
+ return textSource.GetText(offset, length);
+ }
+
+ ///
+ public string GetText(ISegment segment)
+ {
+ return textSource.GetText(segment);
+ }
+
+ ///
+ public int IndexOfAny(char[] anyOf, int startIndex, int count)
+ {
+ return textSource.IndexOfAny(anyOf, startIndex, count);
+ }
+
+ ///
+ public object GetService(Type serviceType)
+ {
+ return null;
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.Editor/StringTextSource.cs b/src/Libraries/NRefactory/ICSharpCode.Editor/StringTextSource.cs
new file mode 100644
index 0000000000..1d5d3386ff
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.Editor/StringTextSource.cs
@@ -0,0 +1,91 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT license (for details please see \doc\license.txt)
+
+using System;
+using System.IO;
+
+namespace ICSharpCode.Editor
+{
+ ///
+ /// Implements the ITextSource interface using a string.
+ ///
+ [Serializable]
+ public class StringTextSource : ITextSource
+ {
+ readonly string text;
+
+ ///
+ /// Creates a new StringTextSource with the given text.
+ ///
+ public StringTextSource(string text)
+ {
+ if (text == null)
+ throw new ArgumentNullException("text");
+ this.text = text;
+ }
+
+ ITextSourceVersion ITextSource.Version {
+ get { return null; }
+ }
+
+ ///
+ public int TextLength {
+ get { return text.Length; }
+ }
+
+ ///
+ public string Text {
+ get { return text; }
+ }
+
+ ///
+ public ITextSource CreateSnapshot()
+ {
+ return this; // StringTextBuffer is immutable
+ }
+
+ ///
+ public ITextSource CreateSnapshot(int offset, int length)
+ {
+ return new StringTextSource(text.Substring(offset, length));
+ }
+
+ ///
+ public TextReader CreateReader()
+ {
+ return new StringReader(text);
+ }
+
+ ///
+ public TextReader CreateReader(int offset, int length)
+ {
+ return new StringReader(text.Substring(offset, length));
+ }
+
+ ///
+ public char GetCharAt(int offset)
+ {
+ return text[offset];
+ }
+
+ ///
+ public string GetText(int offset, int length)
+ {
+ return text.Substring(offset, length);
+ }
+
+ ///
+ public string GetText(ISegment segment)
+ {
+ if (segment == null)
+ throw new ArgumentNullException("segment");
+ return text.Substring(segment.Offset, segment.Length);
+ }
+
+ ///
+ public int IndexOfAny(char[] anyOf, int startIndex, int count)
+ {
+ return text.IndexOfAny(anyOf, startIndex, count);
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.Editor/TextChangeEventArgs.cs b/src/Libraries/NRefactory/ICSharpCode.Editor/TextChangeEventArgs.cs
new file mode 100644
index 0000000000..385f5104a2
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.Editor/TextChangeEventArgs.cs
@@ -0,0 +1,64 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT license (for details please see \doc\license.txt)
+
+using System;
+
+namespace ICSharpCode.Editor
+{
+ ///
+ /// Describes a change of the document text.
+ /// This class is thread-safe.
+ ///
+ [Serializable]
+ public class TextChangeEventArgs : EventArgs
+ {
+ readonly int offset;
+ readonly string removedText;
+ readonly string insertedText;
+
+ ///
+ /// The offset at which the change occurs.
+ ///
+ public int Offset {
+ get { return offset; }
+ }
+
+ ///
+ /// The text that was inserted.
+ ///
+ public string RemovedText {
+ get { return removedText; }
+ }
+
+ ///
+ /// The number of characters removed.
+ ///
+ public int RemovalLength {
+ get { return removedText.Length; }
+ }
+
+ ///
+ /// The text that was inserted.
+ ///
+ public string InsertedText {
+ get { return insertedText; }
+ }
+
+ ///
+ /// The number of characters inserted.
+ ///
+ public int InsertionLength {
+ get { return insertedText.Length; }
+ }
+
+ ///
+ /// Creates a new TextChangeEventArgs object.
+ ///
+ public TextChangeEventArgs(int offset, string removedText, string insertedText)
+ {
+ this.offset = offset;
+ this.removedText = removedText ?? string.Empty;
+ this.insertedText = insertedText ?? string.Empty;
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.Editor/TextLocation.cs b/src/Libraries/NRefactory/ICSharpCode.Editor/TextLocation.cs
new file mode 100644
index 0000000000..12bfe354e3
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.Editor/TextLocation.cs
@@ -0,0 +1,173 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT license (for details please see \doc\license.txt)
+
+using System;
+using System.Globalization;
+
+namespace ICSharpCode.Editor
+{
+ ///
+ /// A line/column position.
+ /// Text editor lines/columns are counted started from one.
+ ///
+ ///
+ /// The document provides the methods and
+ /// to convert between offsets and TextLocations.
+ ///
+ [Serializable]
+ public struct TextLocation : IComparable, IEquatable
+ {
+ ///
+ /// Represents no text location (0, 0).
+ ///
+ public static readonly TextLocation Empty = new TextLocation(0, 0);
+
+ ///
+ /// Constant of the minimum line.
+ ///
+ public const int MinLine = 1;
+
+ ///
+ /// Constant of the minimum column.
+ ///
+ public const int MinColumn = 1;
+
+ ///
+ /// Creates a TextLocation instance.
+ ///
+ public TextLocation(int line, int column)
+ {
+ this.line = line;
+ this.column = column;
+ }
+
+ int column, line;
+
+ ///
+ /// Gets the line number.
+ ///
+ public int Line {
+ get { return line; }
+ }
+
+ ///
+ /// Gets the column number.
+ ///
+ public int Column {
+ get { return column; }
+ }
+
+ ///
+ /// Gets whether the TextLocation instance is empty.
+ ///
+ public bool IsEmpty {
+ get {
+ return column < MinLine && line < MinColumn;
+ }
+ }
+
+ ///
+ /// Gets a string representation for debugging purposes.
+ ///
+ public override string ToString()
+ {
+ return string.Format(CultureInfo.InvariantCulture, "(Line {1}, Col {0})", this.column, this.line);
+ }
+
+ ///
+ /// Gets a hash code.
+ ///
+ public override int GetHashCode()
+ {
+ return unchecked (191 * column.GetHashCode() ^ line.GetHashCode());
+ }
+
+ ///
+ /// Equality test.
+ ///
+ public override bool Equals(object obj)
+ {
+ if (!(obj is TextLocation)) return false;
+ return (TextLocation)obj == this;
+ }
+
+ ///
+ /// Equality test.
+ ///
+ public bool Equals(TextLocation other)
+ {
+ return this == other;
+ }
+
+ ///
+ /// Equality test.
+ ///
+ public static bool operator ==(TextLocation left, TextLocation right)
+ {
+ return left.column == right.column && left.line == right.line;
+ }
+
+ ///
+ /// Inequality test.
+ ///
+ public static bool operator !=(TextLocation left, TextLocation right)
+ {
+ return left.column != right.column || left.line != right.line;
+ }
+
+ ///
+ /// Compares two text locations.
+ ///
+ public static bool operator <(TextLocation left, TextLocation right)
+ {
+ if (left.line < right.line)
+ return true;
+ else if (left.line == right.line)
+ return left.column < right.column;
+ else
+ return false;
+ }
+
+ ///
+ /// Compares two text locations.
+ ///
+ public static bool operator >(TextLocation left, TextLocation right)
+ {
+ if (left.line > right.line)
+ return true;
+ else if (left.line == right.line)
+ return left.column > right.column;
+ else
+ return false;
+ }
+
+ ///
+ /// Compares two text locations.
+ ///
+ public static bool operator <=(TextLocation left, TextLocation right)
+ {
+ return !(left > right);
+ }
+
+ ///
+ /// Compares two text locations.
+ ///
+ public static bool operator >=(TextLocation left, TextLocation right)
+ {
+ return !(left < right);
+ }
+
+ ///
+ /// Compares two text locations.
+ ///
+ public int CompareTo(TextLocation other)
+ {
+ if (this == other)
+ return 0;
+ if (this < other)
+ return -1;
+ else
+ return 1;
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/.gitignore b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/.gitignore
new file mode 100644
index 0000000000..9ce745d95d
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/.gitignore
@@ -0,0 +1,3 @@
+
+bin/
+obj/
\ No newline at end of file
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/CSDemo.Designer.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/CSDemo.Designer.cs
new file mode 100644
index 0000000000..998cee6feb
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/CSDemo.Designer.cs
@@ -0,0 +1,151 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+namespace ICSharpCode.NRefactory.Demo
+{
+ partial class CSDemo
+ {
+ ///
+ /// Designer variable used to keep track of non-visual components.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Disposes resources used by the control.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing) {
+ if (components != null) {
+ components.Dispose();
+ }
+ }
+ base.Dispose(disposing);
+ }
+
+ ///
+ /// This method is required for Windows Forms designer support.
+ /// Do not change the method contents inside the source code editor. The Forms designer might
+ /// not be able to load this method if it was changed manually.
+ ///
+ private void InitializeComponent()
+ {
+ this.splitContainer1 = new System.Windows.Forms.SplitContainer();
+ this.csharpCodeTextBox = new System.Windows.Forms.TextBox();
+ this.resolveButton = new System.Windows.Forms.Button();
+ this.csharpTreeView = new System.Windows.Forms.TreeView();
+ this.csharpGenerateCodeButton = new System.Windows.Forms.Button();
+ this.csharpParseButton = new System.Windows.Forms.Button();
+ ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
+ this.splitContainer1.Panel1.SuspendLayout();
+ this.splitContainer1.Panel2.SuspendLayout();
+ this.splitContainer1.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // splitContainer1
+ //
+ this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.splitContainer1.Location = new System.Drawing.Point(0, 0);
+ this.splitContainer1.Name = "splitContainer1";
+ this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal;
+ //
+ // splitContainer1.Panel1
+ //
+ this.splitContainer1.Panel1.Controls.Add(this.csharpCodeTextBox);
+ //
+ // splitContainer1.Panel2
+ //
+ this.splitContainer1.Panel2.Controls.Add(this.resolveButton);
+ this.splitContainer1.Panel2.Controls.Add(this.csharpTreeView);
+ this.splitContainer1.Panel2.Controls.Add(this.csharpGenerateCodeButton);
+ this.splitContainer1.Panel2.Controls.Add(this.csharpParseButton);
+ this.splitContainer1.Size = new System.Drawing.Size(475, 406);
+ this.splitContainer1.SplitterDistance = 178;
+ this.splitContainer1.TabIndex = 1;
+ //
+ // csharpCodeTextBox
+ //
+ this.csharpCodeTextBox.AcceptsReturn = true;
+ this.csharpCodeTextBox.AcceptsTab = true;
+ this.csharpCodeTextBox.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.csharpCodeTextBox.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.csharpCodeTextBox.HideSelection = false;
+ this.csharpCodeTextBox.Location = new System.Drawing.Point(0, 0);
+ this.csharpCodeTextBox.Multiline = true;
+ this.csharpCodeTextBox.Name = "csharpCodeTextBox";
+ this.csharpCodeTextBox.ScrollBars = System.Windows.Forms.ScrollBars.Both;
+ this.csharpCodeTextBox.Size = new System.Drawing.Size(475, 178);
+ this.csharpCodeTextBox.TabIndex = 0;
+ this.csharpCodeTextBox.Text = "using System;\r\nclass Test\r\n{\r\n public void Main(string[] args)\r\n {\r\n " +
+ " Console.WriteLine(\"Hello, World\");\r\n }\r\n}";
+ this.csharpCodeTextBox.WordWrap = false;
+ this.csharpCodeTextBox.TextChanged += new System.EventHandler(this.CsharpCodeTextBoxTextChanged);
+ //
+ // resolveButton
+ //
+ this.resolveButton.Anchor = System.Windows.Forms.AnchorStyles.Top;
+ this.resolveButton.Location = new System.Drawing.Point(187, 3);
+ this.resolveButton.Name = "resolveButton";
+ this.resolveButton.Size = new System.Drawing.Size(100, 23);
+ this.resolveButton.TabIndex = 3;
+ this.resolveButton.Text = "Resolve";
+ this.resolveButton.UseVisualStyleBackColor = true;
+ this.resolveButton.Click += new System.EventHandler(this.ResolveButtonClick);
+ //
+ // csharpTreeView
+ //
+ this.csharpTreeView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.csharpTreeView.HideSelection = false;
+ this.csharpTreeView.Location = new System.Drawing.Point(3, 32);
+ this.csharpTreeView.Name = "csharpTreeView";
+ this.csharpTreeView.Size = new System.Drawing.Size(467, 189);
+ this.csharpTreeView.TabIndex = 2;
+ this.csharpTreeView.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.CSharpTreeViewAfterSelect);
+ //
+ // csharpGenerateCodeButton
+ //
+ this.csharpGenerateCodeButton.Anchor = System.Windows.Forms.AnchorStyles.Top;
+ this.csharpGenerateCodeButton.Location = new System.Drawing.Point(293, 2);
+ this.csharpGenerateCodeButton.Name = "csharpGenerateCodeButton";
+ this.csharpGenerateCodeButton.Size = new System.Drawing.Size(100, 23);
+ this.csharpGenerateCodeButton.TabIndex = 1;
+ this.csharpGenerateCodeButton.Text = "Generate";
+ this.csharpGenerateCodeButton.UseVisualStyleBackColor = true;
+ this.csharpGenerateCodeButton.Click += new System.EventHandler(this.CSharpGenerateCodeButtonClick);
+ //
+ // csharpParseButton
+ //
+ this.csharpParseButton.Anchor = System.Windows.Forms.AnchorStyles.Top;
+ this.csharpParseButton.Location = new System.Drawing.Point(81, 3);
+ this.csharpParseButton.Name = "csharpParseButton";
+ this.csharpParseButton.Size = new System.Drawing.Size(100, 23);
+ this.csharpParseButton.TabIndex = 0;
+ this.csharpParseButton.Text = "Parse";
+ this.csharpParseButton.UseVisualStyleBackColor = true;
+ this.csharpParseButton.Click += new System.EventHandler(this.CSharpParseButtonClick);
+ //
+ // CSDemo
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.Controls.Add(this.splitContainer1);
+ this.Name = "CSDemo";
+ this.Size = new System.Drawing.Size(475, 406);
+ this.splitContainer1.Panel1.ResumeLayout(false);
+ this.splitContainer1.Panel1.PerformLayout();
+ this.splitContainer1.Panel2.ResumeLayout(false);
+ ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit();
+ this.splitContainer1.ResumeLayout(false);
+ this.ResumeLayout(false);
+ }
+ private System.Windows.Forms.Button csharpParseButton;
+ private System.Windows.Forms.Button csharpGenerateCodeButton;
+ private System.Windows.Forms.TreeView csharpTreeView;
+ private System.Windows.Forms.Button resolveButton;
+ private System.Windows.Forms.TextBox csharpCodeTextBox;
+ private System.Windows.Forms.SplitContainer splitContainer1;
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/CSDemo.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/CSDemo.cs
new file mode 100644
index 0000000000..f589e33252
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/CSDemo.cs
@@ -0,0 +1,232 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.Drawing;
+using System.IO;
+using System.Reflection;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+using ICSharpCode.NRefactory.CSharp;
+using ICSharpCode.NRefactory.CSharp.Resolver;
+using ICSharpCode.NRefactory.TypeSystem;
+using ICSharpCode.NRefactory.TypeSystem.Implementation;
+
+namespace ICSharpCode.NRefactory.Demo
+{
+ ///
+ /// Description of CSDemo.
+ ///
+ public partial class CSDemo : UserControl
+ {
+ public CSDemo()
+ {
+ //
+ // The InitializeComponent() call is required for Windows Forms designer support.
+ //
+ InitializeComponent();
+
+ if (LicenseManager.UsageMode != LicenseUsageMode.Designtime) {
+ csharpCodeTextBox.SelectAll();
+ CSharpParseButtonClick(null, null);
+ resolveButton.UseWaitCursor = true;
+ ThreadPool.QueueUserWorkItem(
+ delegate {
+ builtInLibs.Value.ToString();
+ BeginInvoke(new Action(delegate { resolveButton.UseWaitCursor = false; }));
+ });
+ }
+ }
+
+ CompilationUnit compilationUnit;
+
+ void CSharpParseButtonClick(object sender, EventArgs e)
+ {
+ CSharpParser parser = new CSharpParser();
+ compilationUnit = parser.Parse(new StringReader(csharpCodeTextBox.Text));
+ csharpTreeView.Nodes.Clear();
+ foreach (var element in compilationUnit.Children) {
+ csharpTreeView.Nodes.Add(MakeTreeNode(element));
+ }
+ SelectCurrentNode(csharpTreeView.Nodes);
+ resolveButton.Enabled = true;
+ }
+
+ TreeNode MakeTreeNode(AstNode node)
+ {
+ TreeNode t = new TreeNode(GetNodeTitle(node));
+ t.Tag = node;
+ foreach (AstNode child in node.Children) {
+ t.Nodes.Add(MakeTreeNode(child));
+ }
+ return t;
+ }
+
+ string GetNodeTitle(AstNode node)
+ {
+ StringBuilder b = new StringBuilder();
+ b.Append(node.Role.ToString());
+ b.Append(": ");
+ b.Append(node.GetType().Name);
+ bool hasProperties = false;
+ foreach (PropertyInfo p in node.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)) {
+ if (p.Name == "NodeType" || p.Name == "IsNull")
+ continue;
+ if (p.PropertyType == typeof(string) || p.PropertyType.IsEnum || p.PropertyType == typeof(bool)) {
+ if (!hasProperties) {
+ hasProperties = true;
+ b.Append(" (");
+ } else {
+ b.Append(", ");
+ }
+ b.Append(p.Name);
+ b.Append(" = ");
+ try {
+ object val = p.GetValue(node, null);
+ b.Append(val != null ? val.ToString() : "**null**");
+ } catch (TargetInvocationException ex) {
+ b.Append("**" + ex.InnerException.GetType().Name + "**");
+ }
+ }
+ }
+ if (hasProperties)
+ b.Append(")");
+ return b.ToString();
+ }
+
+ bool SelectCurrentNode(TreeNodeCollection c)
+ {
+ int selectionStart = csharpCodeTextBox.SelectionStart;
+ int selectionEnd = selectionStart + csharpCodeTextBox.SelectionLength;
+ foreach (TreeNode t in c) {
+ AstNode node = t.Tag as AstNode;
+ if (node != null
+ && selectionStart >= GetOffset(csharpCodeTextBox, node.StartLocation)
+ && selectionEnd <= GetOffset(csharpCodeTextBox, node.EndLocation))
+ {
+ if (selectionStart == selectionEnd
+ && (selectionStart == GetOffset(csharpCodeTextBox, node.StartLocation)
+ || selectionStart == GetOffset(csharpCodeTextBox, node.EndLocation)))
+ {
+ // caret is on border of this node; don't expand
+ csharpTreeView.SelectedNode = t;
+ } else {
+ t.Expand();
+ if (!SelectCurrentNode(t.Nodes))
+ csharpTreeView.SelectedNode = t;
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+
+ void CSharpGenerateCodeButtonClick(object sender, EventArgs e)
+ {
+ StringWriter w = new StringWriter();
+ OutputVisitor output = new OutputVisitor(w, new CSharpFormattingOptions());
+ compilationUnit.AcceptVisitor(output, null);
+ csharpCodeTextBox.Text = w.ToString();
+ }
+
+ int GetOffset(TextBox textBox, AstLocation location)
+ {
+ return textBox.GetFirstCharIndexFromLine(location.Line - 1) + location.Column - 1;
+ }
+
+ void CSharpTreeViewAfterSelect(object sender, TreeViewEventArgs e)
+ {
+ AstNode node = e.Node.Tag as AstNode;
+ if (node != null) {
+ int startOffset = GetOffset(csharpCodeTextBox, node.StartLocation);
+ int endOffset = GetOffset(csharpCodeTextBox, node.EndLocation);
+ csharpCodeTextBox.Select(startOffset, endOffset - startOffset);
+ }
+ }
+
+ Lazy> builtInLibs = new Lazy>(
+ delegate {
+ Assembly[] assemblies = {
+ typeof(object).Assembly, // mscorlib
+ typeof(Uri).Assembly, // System.dll
+ typeof(System.Linq.Enumerable).Assembly, // System.Core.dll
+// typeof(System.Xml.XmlDocument).Assembly, // System.Xml.dll
+// typeof(System.Drawing.Bitmap).Assembly, // System.Drawing.dll
+// typeof(Form).Assembly, // System.Windows.Forms.dll
+ typeof(ICSharpCode.NRefactory.TypeSystem.IProjectContent).Assembly,
+ };
+ IProjectContent[] projectContents = new IProjectContent[assemblies.Length];
+ Stopwatch total = Stopwatch.StartNew();
+ Parallel.For(
+ 0, assemblies.Length,
+ delegate (int i) {
+ Stopwatch w = Stopwatch.StartNew();
+ CecilLoader loader = new CecilLoader();
+ projectContents[i] = loader.LoadAssemblyFile(assemblies[i].Location);
+ Debug.WriteLine(Path.GetFileName(assemblies[i].Location) + ": " + w.Elapsed);
+ });
+ Debug.WriteLine("Total: " + total.Elapsed);
+ return projectContents;
+ });
+
+ void ResolveButtonClick(object sender, EventArgs e)
+ {
+ SimpleProjectContent project = new SimpleProjectContent();
+ TypeSystemConvertVisitor convertVisitor = new TypeSystemConvertVisitor(project, "dummy.cs");
+ compilationUnit.AcceptVisitor(convertVisitor, null);
+ project.UpdateProjectContent(null, convertVisitor.ParsedFile);
+
+ List projects = new List();
+ projects.Add(project);
+ projects.AddRange(builtInLibs.Value);
+
+ using (var context = new CompositeTypeResolveContext(projects).Synchronize()) {
+ CSharpResolver resolver = new CSharpResolver(context);
+
+ IResolveVisitorNavigator navigator = null;
+ if (csharpTreeView.SelectedNode != null) {
+ navigator = new NodeListResolveVisitorNavigator(new[] { (AstNode)csharpTreeView.SelectedNode.Tag });
+ }
+ ResolveVisitor visitor = new ResolveVisitor(resolver, convertVisitor.ParsedFile, navigator);
+ visitor.Scan(compilationUnit);
+ csharpTreeView.BeginUpdate();
+ ShowResolveResultsInTree(csharpTreeView.Nodes, visitor);
+ csharpTreeView.EndUpdate();
+ }
+ }
+
+ void ShowResolveResultsInTree(TreeNodeCollection c, ResolveVisitor v)
+ {
+ foreach (TreeNode t in c) {
+ AstNode node = t.Tag as AstNode;
+ if (node != null) {
+ ResolveResult rr = v.GetResolveResult(node);
+ if (rr != null)
+ t.Text = GetNodeTitle(node) + " " + rr.ToString();
+ else
+ t.Text = GetNodeTitle(node);
+ }
+ ShowResolveResultsInTree(t.Nodes, v);
+ }
+ }
+
+ void CSharpCodeTextBoxKeyDown(object sender, KeyEventArgs e)
+ {
+ if (e.Control && e.KeyCode == Keys.A) {
+ e.Handled = true;
+ csharpCodeTextBox.SelectAll();
+ }
+ }
+
+ void CsharpCodeTextBoxTextChanged(object sender, EventArgs e)
+ {
+ resolveButton.Enabled = false;
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/CSDemo.resx b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/CSDemo.resx
new file mode 100644
index 0000000000..1af7de150c
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/CSDemo.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/ICSharpCode.NRefactory.Demo.csproj b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/ICSharpCode.NRefactory.Demo.csproj
new file mode 100644
index 0000000000..841474f597
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/ICSharpCode.NRefactory.Demo.csproj
@@ -0,0 +1,82 @@
+
+
+
+ {9C19E629-C93E-4ACB-9A4B-13072B5AEF9D}
+ Debug
+ x86
+ WinExe
+ ICSharpCode.NRefactory.Demo
+ ICSharpCode.NRefactory.Demo
+ v4.0
+ Client
+ Properties
+
+
+ x86
+
+
+ bin\Debug\
+ True
+ Full
+ False
+ True
+ DEBUG;TRACE
+
+
+ bin\Release\
+ False
+ None
+ True
+ False
+ TRACE
+
+
+
+
+ 3.5
+
+
+
+
+
+
+
+
+ CSDemo.cs
+
+
+ Form
+
+
+ MainForm.cs
+
+
+
+
+
+ VBDemo.cs
+
+
+
+
+ {7B82B671-419F-45F4-B778-D9286F996EFA}
+ ICSharpCode.NRefactory.VB
+
+
+ {3B2A5653-EC97-4001-BB9B-D90F1AF2C371}
+ ICSharpCode.NRefactory
+
+
+
+
+ CSDemo.cs
+
+
+ MainForm.cs
+
+
+ VBDemo.cs
+
+
+
+
\ No newline at end of file
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/MainForm.Designer.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/MainForm.Designer.cs
new file mode 100644
index 0000000000..12c38ffb62
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/MainForm.Designer.cs
@@ -0,0 +1,125 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+namespace ICSharpCode.NRefactory.Demo
+{
+ partial class MainForm
+ {
+ ///
+ /// Designer variable used to keep track of non-visual components.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Disposes resources used by the form.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing) {
+ if (components != null) {
+ components.Dispose();
+ }
+ }
+ base.Dispose(disposing);
+ }
+
+ ///
+ /// This method is required for Windows Forms designer support.
+ /// Do not change the method contents inside the source code editor. The Forms designer might
+ /// not be able to load this method if it was changed manually.
+ ///
+ private void InitializeComponent()
+ {
+ this.miniToolStrip = new System.Windows.Forms.ToolStrip();
+ this.tabPage1 = new System.Windows.Forms.TabPage();
+ this.csDemo1 = new ICSharpCode.NRefactory.Demo.CSDemo();
+ this.tabControl1 = new System.Windows.Forms.TabControl();
+ this.tabPage2 = new System.Windows.Forms.TabPage();
+ this.vbDemo1 = new ICSharpCode.NRefactory.Demo.VBDemo();
+ this.tabPage1.SuspendLayout();
+ this.tabControl1.SuspendLayout();
+ this.tabPage2.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // miniToolStrip
+ //
+ this.miniToolStrip.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+ this.miniToolStrip.AutoSize = false;
+ this.miniToolStrip.CanOverflow = false;
+ this.miniToolStrip.Dock = System.Windows.Forms.DockStyle.None;
+ this.miniToolStrip.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden;
+ this.miniToolStrip.Location = new System.Drawing.Point(13, 3);
+ this.miniToolStrip.Name = "miniToolStrip";
+ this.miniToolStrip.Size = new System.Drawing.Size(16, 25);
+ this.miniToolStrip.TabIndex = 3;
+ //
+ // tabPage1
+ //
+ this.tabPage1.Controls.Add(this.csDemo1);
+ this.tabPage1.Location = new System.Drawing.Point(4, 22);
+ this.tabPage1.Name = "tabPage1";
+ this.tabPage1.Padding = new System.Windows.Forms.Padding(3);
+ this.tabPage1.Size = new System.Drawing.Size(507, 458);
+ this.tabPage1.TabIndex = 0;
+ this.tabPage1.Text = "C#";
+ this.tabPage1.UseVisualStyleBackColor = true;
+ //
+ // csDemo1
+ //
+ this.csDemo1.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.csDemo1.Location = new System.Drawing.Point(3, 3);
+ this.csDemo1.Name = "csDemo1";
+ this.csDemo1.Size = new System.Drawing.Size(501, 452);
+ this.csDemo1.TabIndex = 0;
+ //
+ // tabControl1
+ //
+ this.tabControl1.Controls.Add(this.tabPage1);
+ this.tabControl1.Controls.Add(this.tabPage2);
+ this.tabControl1.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.tabControl1.Location = new System.Drawing.Point(0, 0);
+ this.tabControl1.Name = "tabControl1";
+ this.tabControl1.SelectedIndex = 0;
+ this.tabControl1.Size = new System.Drawing.Size(515, 484);
+ this.tabControl1.TabIndex = 0;
+ //
+ // tabPage2
+ //
+ this.tabPage2.Controls.Add(this.vbDemo1);
+ this.tabPage2.Location = new System.Drawing.Point(4, 22);
+ this.tabPage2.Name = "tabPage2";
+ this.tabPage2.Padding = new System.Windows.Forms.Padding(3);
+ this.tabPage2.Size = new System.Drawing.Size(507, 458);
+ this.tabPage2.TabIndex = 1;
+ this.tabPage2.Text = "VB";
+ this.tabPage2.UseVisualStyleBackColor = true;
+ //
+ // vbDemo1
+ //
+ this.vbDemo1.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.vbDemo1.Location = new System.Drawing.Point(3, 3);
+ this.vbDemo1.Name = "vbDemo1";
+ this.vbDemo1.Size = new System.Drawing.Size(501, 452);
+ this.vbDemo1.TabIndex = 0;
+ //
+ // MainForm
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(515, 484);
+ this.Controls.Add(this.tabControl1);
+ this.Name = "MainForm";
+ this.Text = "NRefactory Demo";
+ this.tabPage1.ResumeLayout(false);
+ this.tabControl1.ResumeLayout(false);
+ this.tabPage2.ResumeLayout(false);
+ this.ResumeLayout(false);
+ }
+ private ICSharpCode.NRefactory.Demo.VBDemo vbDemo1;
+ private System.Windows.Forms.TabPage tabPage2;
+ private ICSharpCode.NRefactory.Demo.CSDemo csDemo1;
+ private System.Windows.Forms.ToolStrip miniToolStrip;
+ private System.Windows.Forms.TabPage tabPage1;
+ private System.Windows.Forms.TabControl tabControl1;
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/MainForm.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/MainForm.cs
new file mode 100644
index 0000000000..9633a00f12
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/MainForm.cs
@@ -0,0 +1,34 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Drawing;
+using System.IO;
+using System.Reflection;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using ICSharpCode.NRefactory.CSharp;
+using ICSharpCode.NRefactory.CSharp.Resolver;
+using ICSharpCode.NRefactory.TypeSystem;
+using ICSharpCode.NRefactory.TypeSystem.Implementation;
+
+namespace ICSharpCode.NRefactory.Demo
+{
+ ///
+ /// Description of MainForm.
+ ///
+ public partial class MainForm : Form
+ {
+ public MainForm()
+ {
+ //
+ // The InitializeComponent() call is required for Windows Forms designer support.
+ //
+ InitializeComponent();
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/MainForm.resx b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/MainForm.resx
new file mode 100644
index 0000000000..38d0f5c169
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/MainForm.resx
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ 17, 17
+
+
\ No newline at end of file
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/Program.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/Program.cs
new file mode 100644
index 0000000000..7c176b1aa4
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/Program.cs
@@ -0,0 +1,25 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using System.Windows.Forms;
+
+namespace ICSharpCode.NRefactory.Demo
+{
+ ///
+ /// Class with program entry point.
+ ///
+ internal sealed class Program
+ {
+ ///
+ /// Program entry point.
+ ///
+ [STAThread]
+ private static void Main(string[] args)
+ {
+ Application.EnableVisualStyles();
+ Application.SetCompatibleTextRenderingDefault(false);
+ Application.Run(new MainForm());
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/Properties/AssemblyInfo.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..2027632f74
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/Properties/AssemblyInfo.cs
@@ -0,0 +1,31 @@
+#region Using directives
+
+using System;
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+#endregion
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("ICSharpCode.NRefactory.Demo")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("ICSharpCode.NRefactory.Demo")]
+[assembly: AssemblyCopyright("Copyright 2010")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// This sets the default COM visibility of types in the assembly to invisible.
+// If you need to expose a type to COM, use [ComVisible(true)] on that type.
+[assembly: ComVisible(false)]
+
+// The assembly version has following format :
+//
+// Major.Minor.Build.Revision
+//
+// You can specify all the values or you can use the default the Revision and
+// Build Numbers by using the '*' as shown below:
+[assembly: AssemblyVersion("1.0.*")]
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/VBAstView.Designer.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/VBAstView.Designer.cs
new file mode 100644
index 0000000000..9cdb323344
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/VBAstView.Designer.cs
@@ -0,0 +1,59 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+namespace ICSharpCode.NRefactory.Demo
+{
+ partial class VBAstView : System.Windows.Forms.UserControl
+ {
+ ///
+ /// Designer variable used to keep track of non-visual components.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Disposes resources used by the control.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing) {
+ if (components != null) {
+ components.Dispose();
+ }
+ }
+ base.Dispose(disposing);
+ }
+
+ ///
+ /// This method is required for Windows Forms designer support.
+ /// Do not change the method contents inside the source code editor. The Forms designer might
+ /// not be able to load this method if it was changed manually.
+ ///
+ private void InitializeComponent()
+ {
+ this.tree = new System.Windows.Forms.TreeView();
+ this.SuspendLayout();
+ //
+ // tree
+ //
+ this.tree.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.tree.HideSelection = false;
+ this.tree.Location = new System.Drawing.Point(0, 0);
+ this.tree.Name = "tree";
+ this.tree.ShowRootLines = false;
+ this.tree.Size = new System.Drawing.Size(186, 182);
+ this.tree.TabIndex = 0;
+ this.tree.KeyDown += new System.Windows.Forms.KeyEventHandler(this.TreeKeyDown);
+ //
+ // AstView
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.Controls.Add(this.tree);
+ this.Name = "AstView";
+ this.Size = new System.Drawing.Size(186, 182);
+ this.ResumeLayout(false);
+ }
+ private System.Windows.Forms.TreeView tree;
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/VBAstView.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/VBAstView.cs
new file mode 100644
index 0000000000..a6e6f58aa5
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/VBAstView.cs
@@ -0,0 +1,225 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using System.Collections;
+using System.Windows.Forms;
+using System.Reflection;
+
+using ICSharpCode.NRefactory.VB.Ast;
+using ICSharpCode.NRefactory.VB;
+
+namespace ICSharpCode.NRefactory.Demo
+{
+ public partial class VBAstView
+ {
+ CompilationUnit unit;
+
+ public CompilationUnit Unit {
+ get {
+ return unit;
+ }
+ set {
+ if (value != null) {
+ unit = value;
+ UpdateTree();
+ }
+ }
+ }
+
+ void UpdateTree()
+ {
+ tree.Nodes.Clear();
+ tree.Nodes.Add(new CollectionNode("CompilationUnit", unit.Children));
+ tree.SelectedNode = tree.Nodes[0];
+ }
+
+ public VBAstView()
+ {
+ InitializeComponent();
+ }
+
+// public void DeleteSelectedNode()
+// {
+// if (tree.SelectedNode is ElementNode) {
+// INode element = (tree.SelectedNode as ElementNode).element;
+// if (tree.SelectedNode.Parent is CollectionNode) {
+// if (MessageBox.Show("Remove selected node from parent collection?", "Remove node", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
+// == DialogResult.Yes)
+// {
+// IList col = (tree.SelectedNode.Parent as CollectionNode).collection;
+// col.Remove(element);
+// (tree.SelectedNode.Parent as CollectionNode).Update();
+// }
+// } else if (tree.SelectedNode.Parent is ElementNode) {
+// if (MessageBox.Show("Set selected property to null?", "Remove node", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
+// == DialogResult.Yes)
+// {
+// // get parent element
+// element = (tree.SelectedNode.Parent as ElementNode).element;
+// string propertyName = (string)tree.SelectedNode.Tag;
+// element.GetType().GetProperty(propertyName).SetValue(element, null, null);
+// (tree.SelectedNode.Parent as ElementNode).Update();
+// }
+// }
+// } else if (tree.SelectedNode is CollectionNode) {
+// if (MessageBox.Show("Remove all elements from selected collection?", "Clear collection", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
+// == DialogResult.Yes)
+// {
+// IList col = (tree.SelectedNode as CollectionNode).collection;
+// col.Clear();
+// (tree.SelectedNode as CollectionNode).Update();
+// }
+// }
+// }
+//
+// public void EditSelectedNode()
+// {
+// TreeNode node = tree.SelectedNode;
+// while (!(node is ElementNode)) {
+// if (node == null) {
+// return;
+// }
+// node = node.Parent;
+// }
+// INode element = ((ElementNode)node).element;
+// using (VBEditDialog dlg = new VBEditDialog(element)) {
+// dlg.ShowDialog();
+// }
+// ((ElementNode)node).Update();
+// }
+//
+// public void ApplyTransformation(IAstVisitor visitor)
+// {
+// if (tree.SelectedNode == tree.Nodes[0]) {
+// unit.AcceptVisitor(visitor, null);
+// UpdateTree();
+// } else {
+// string name = visitor.GetType().Name;
+// ElementNode elementNode = tree.SelectedNode as ElementNode;
+// CollectionNode collectionNode = tree.SelectedNode as CollectionNode;
+// if (elementNode != null) {
+// if (MessageBox.Show(("Apply " + name + " to selected element '" + elementNode.Text + "'?"),
+// "Apply transformation", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
+// == DialogResult.Yes)
+// {
+// elementNode.element.AcceptVisitor(visitor, null);
+// elementNode.Update();
+// }
+// } else if (collectionNode != null) {
+// if (MessageBox.Show(("Apply " + name + " to all elements in selected collection '" + collectionNode.Text + "'?"),
+// "Apply transformation", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
+// == DialogResult.Yes)
+// {
+// foreach (TreeNode subNode in collectionNode.Nodes) {
+// if (subNode is ElementNode) {
+// (subNode as ElementNode).element.AcceptVisitor(visitor, null);
+// }
+// }
+// collectionNode.Update();
+// }
+// }
+// }
+// }
+//
+ static TreeNode CreateNode(object child)
+ {
+ if (child == null) {
+ return new TreeNode("*null reference*");
+ } else if (child is INode) {
+ return new ElementNode(child as INode);
+ } else {
+ return new TreeNode(child.ToString());
+ }
+ }
+
+ class CollectionNode : TreeNode
+ {
+ internal IList collection;
+ string baseName;
+
+ public CollectionNode(string text, IList children) : base(text)
+ {
+ this.baseName = text;
+ this.collection = children;
+ Update();
+ }
+
+ public void Update()
+ {
+ if (collection.Count == 0) {
+ Text = baseName + " (empty collection)";
+ } else if (collection.Count == 1) {
+ Text = baseName + " (collection with 1 element)";
+ } else {
+ Text = baseName + " (collection with " + collection.Count + " elements)";
+ }
+ Nodes.Clear();
+ foreach (object child in collection) {
+ Nodes.Add(CreateNode(child));
+ }
+ Expand();
+ }
+ }
+
+ class ElementNode : TreeNode
+ {
+ internal AstNode element;
+
+ public ElementNode(AstNode node)
+ {
+ this.element = node;
+ Update();
+ }
+
+ public void Update()
+ {
+ Nodes.Clear();
+ Type type = element.GetType();
+ Text = type.Name;
+ if (Tag != null) { // HACK: after editing property element
+ Text = Tag.ToString() + " = " + Text;
+ }
+ if (!(element is INullable && (element as INullable).IsNull)) {
+ AddProperties(type, element);
+ if (element.Children.Count > 0) {
+ Nodes.Add(new CollectionNode("Children", element.Children));
+ }
+ }
+ }
+
+ void AddProperties(Type type, AstNode node)
+ {
+ if (type == typeof(AbstractNode))
+ return;
+ foreach (PropertyInfo pi in type.GetProperties(BindingFlags.Instance | BindingFlags.Public)) {
+ if (pi.DeclaringType != type) // don't add derived properties
+ continue;
+ if (pi.Name == "IsNull")
+ continue;
+ object value = pi.GetValue(node, null);
+ if (value is IList) {
+ Nodes.Add(new CollectionNode(pi.Name, (IList)value));
+ } else if (value is string) {
+ Text += " " + pi.Name + "='" + value + "'";
+ } else {
+ TreeNode treeNode = CreateNode(value);
+ treeNode.Text = pi.Name + " = " + treeNode.Text;
+ treeNode.Tag = pi.Name;
+ Nodes.Add(treeNode);
+ }
+ }
+ AddProperties(type.BaseType, node);
+ }
+ }
+
+ void TreeKeyDown(object sender, KeyEventArgs e)
+ {
+ if (e.KeyData == Keys.Delete) {
+ DeleteSelectedNode();
+ } else if (e.KeyData == Keys.Space || e.KeyData == Keys.Enter) {
+ EditSelectedNode();
+ }
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/VBAstView.resx b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/VBAstView.resx
new file mode 100644
index 0000000000..7080a7d118
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/VBAstView.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/VBDemo.Designer.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/VBDemo.Designer.cs
new file mode 100644
index 0000000000..48641c6694
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/VBDemo.Designer.cs
@@ -0,0 +1,134 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+namespace ICSharpCode.NRefactory.Demo
+{
+ partial class VBDemo
+ {
+ ///
+ /// Designer variable used to keep track of non-visual components.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Disposes resources used by the control.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing) {
+ if (components != null) {
+ components.Dispose();
+ }
+ }
+ base.Dispose(disposing);
+ }
+
+ ///
+ /// This method is required for Windows Forms designer support.
+ /// Do not change the method contents inside the source code editor. The Forms designer might
+ /// not be able to load this method if it was changed manually.
+ ///
+ private void InitializeComponent()
+ {
+ this.splitContainer1 = new System.Windows.Forms.SplitContainer();
+ this.codeView = new System.Windows.Forms.TextBox();
+ this.generateCodeButton = new System.Windows.Forms.Button();
+ this.parseButton = new System.Windows.Forms.Button();
+ this.treeView = new System.Windows.Forms.TreeView();
+ ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
+ this.splitContainer1.Panel1.SuspendLayout();
+ this.splitContainer1.Panel2.SuspendLayout();
+ this.splitContainer1.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // splitContainer1
+ //
+ this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.splitContainer1.Location = new System.Drawing.Point(0, 0);
+ this.splitContainer1.Name = "splitContainer1";
+ this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal;
+ //
+ // splitContainer1.Panel1
+ //
+ this.splitContainer1.Panel1.Controls.Add(this.codeView);
+ //
+ // splitContainer1.Panel2
+ //
+ this.splitContainer1.Panel2.Controls.Add(this.generateCodeButton);
+ this.splitContainer1.Panel2.Controls.Add(this.parseButton);
+ this.splitContainer1.Panel2.Controls.Add(this.treeView);
+ this.splitContainer1.Size = new System.Drawing.Size(462, 391);
+ this.splitContainer1.SplitterDistance = 173;
+ this.splitContainer1.TabIndex = 1;
+ //
+ // codeView
+ //
+ this.codeView.AcceptsReturn = true;
+ this.codeView.AcceptsTab = true;
+ this.codeView.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.codeView.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.codeView.HideSelection = false;
+ this.codeView.Location = new System.Drawing.Point(0, 0);
+ this.codeView.Multiline = true;
+ this.codeView.Name = "codeView";
+ this.codeView.ScrollBars = System.Windows.Forms.ScrollBars.Both;
+ this.codeView.Size = new System.Drawing.Size(462, 173);
+ this.codeView.TabIndex = 0;
+ this.codeView.Text = "Option Explicit";
+ this.codeView.WordWrap = false;
+ //
+ // generateCodeButton
+ //
+ this.generateCodeButton.Anchor = System.Windows.Forms.AnchorStyles.Top;
+ this.generateCodeButton.Location = new System.Drawing.Point(225, 2);
+ this.generateCodeButton.Name = "generateCodeButton";
+ this.generateCodeButton.Size = new System.Drawing.Size(100, 23);
+ this.generateCodeButton.TabIndex = 1;
+ this.generateCodeButton.Text = "Generate";
+ this.generateCodeButton.UseVisualStyleBackColor = true;
+ this.generateCodeButton.Click += new System.EventHandler(this.CSharpGenerateCodeButtonClick);
+ //
+ // parseButton
+ //
+ this.parseButton.Anchor = System.Windows.Forms.AnchorStyles.Top;
+ this.parseButton.Location = new System.Drawing.Point(119, 2);
+ this.parseButton.Name = "parseButton";
+ this.parseButton.Size = new System.Drawing.Size(100, 23);
+ this.parseButton.TabIndex = 0;
+ this.parseButton.Text = "Parse";
+ this.parseButton.UseVisualStyleBackColor = true;
+ this.parseButton.Click += new System.EventHandler(this.CSharpParseButtonClick);
+ //
+ // treeView
+ //
+ this.treeView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.treeView.Location = new System.Drawing.Point(3, 31);
+ this.treeView.Name = "treeView";
+ this.treeView.Size = new System.Drawing.Size(459, 180);
+ this.treeView.TabIndex = 0;
+ this.treeView.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.CSharpTreeViewAfterSelect);
+ //
+ // VBDemo
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.Controls.Add(this.splitContainer1);
+ this.Name = "VBDemo";
+ this.Size = new System.Drawing.Size(462, 391);
+ this.splitContainer1.Panel1.ResumeLayout(false);
+ this.splitContainer1.Panel1.PerformLayout();
+ this.splitContainer1.Panel2.ResumeLayout(false);
+ ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit();
+ this.splitContainer1.ResumeLayout(false);
+ this.ResumeLayout(false);
+ }
+ private System.Windows.Forms.TextBox codeView;
+ private System.Windows.Forms.TreeView treeView;
+ private System.Windows.Forms.Button generateCodeButton;
+ private System.Windows.Forms.Button parseButton;
+ private System.Windows.Forms.SplitContainer splitContainer1;
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/VBDemo.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/VBDemo.cs
new file mode 100644
index 0000000000..beb3308c15
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/VBDemo.cs
@@ -0,0 +1,140 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Windows.Forms;
+
+using ICSharpCode.NRefactory.VB;
+using ICSharpCode.NRefactory.VB.Ast;
+using ICSharpCode.NRefactory.VB.Parser;
+
+namespace ICSharpCode.NRefactory.Demo
+{
+ ///
+ /// Description of VBDemo.
+ ///
+ public partial class VBDemo : UserControl
+ {
+ public VBDemo()
+ {
+ //
+ // The InitializeComponent() call is required for Windows Forms designer support.
+ //
+ InitializeComponent();
+ }
+
+ CompilationUnit compilationUnit;
+
+ void CSharpParseButtonClick(object sender, EventArgs e)
+ {
+ var parser = new VBParser();
+ compilationUnit = parser.Parse(new StringReader(codeView.Text));
+ if (parser.HasErrors)
+ MessageBox.Show(parser.Errors.ErrorOutput);
+ treeView.Nodes.Clear();
+ foreach (var element in compilationUnit.Children) {
+ treeView.Nodes.Add(MakeTreeNode(element));
+ }
+ SelectCurrentNode(treeView.Nodes);
+ }
+
+ TreeNode MakeTreeNode(AstNode node)
+ {
+ TreeNode t = new TreeNode(GetNodeTitle(node));
+ t.Tag = node;
+ foreach (AstNode child in node.Children) {
+ t.Nodes.Add(MakeTreeNode(child));
+ }
+ return t;
+ }
+
+ string GetNodeTitle(AstNode node)
+ {
+ StringBuilder b = new StringBuilder();
+ b.Append(node.Role.ToString());
+ b.Append(": ");
+ b.Append(node.GetType().Name);
+ bool hasProperties = false;
+ foreach (PropertyInfo p in node.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)) {
+ if (p.Name == "NodeType" || p.Name == "IsNull")
+ continue;
+ if (p.PropertyType == typeof(string) || p.PropertyType.IsEnum || p.PropertyType == typeof(bool)) {
+ if (!hasProperties) {
+ hasProperties = true;
+ b.Append(" (");
+ } else {
+ b.Append(", ");
+ }
+ b.Append(p.Name);
+ b.Append(" = ");
+ try {
+ object val = p.GetValue(node, null);
+ b.Append(val != null ? val.ToString() : "**null**");
+ } catch (TargetInvocationException ex) {
+ b.Append("**" + ex.InnerException.GetType().Name + "**");
+ }
+ }
+ }
+ if (hasProperties)
+ b.Append(")");
+ return b.ToString();
+ }
+
+ bool SelectCurrentNode(TreeNodeCollection c)
+ {
+ int selectionStart = codeView.SelectionStart;
+ int selectionEnd = selectionStart + codeView.SelectionLength;
+ foreach (TreeNode t in c) {
+ AstNode node = t.Tag as AstNode;
+ if (node != null
+ && selectionStart >= GetOffset(codeView, node.StartLocation)
+ && selectionEnd <= GetOffset(codeView, node.EndLocation))
+ {
+ if (selectionStart == selectionEnd
+ && (selectionStart == GetOffset(codeView, node.StartLocation)
+ || selectionStart == GetOffset(codeView, node.EndLocation)))
+ {
+ // caret is on border of this node; don't expand
+ treeView.SelectedNode = t;
+ } else {
+ t.Expand();
+ if (!SelectCurrentNode(t.Nodes))
+ treeView.SelectedNode = t;
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+
+ void CSharpGenerateCodeButtonClick(object sender, EventArgs e)
+ {
+ StringWriter w = new StringWriter();
+ OutputVisitor output = new OutputVisitor(w, new VBFormattingOptions());
+ compilationUnit.AcceptVisitor(output, null);
+ codeView.Text = w.ToString();
+ }
+
+ int GetOffset(TextBox textBox, AstLocation location)
+ {
+ return textBox.GetFirstCharIndexFromLine(location.Line - 1) + location.Column - 1;
+ }
+
+ void CSharpTreeViewAfterSelect(object sender, TreeViewEventArgs e)
+ {
+ AstNode node = e.Node.Tag as AstNode;
+ if (node != null) {
+ int startOffset = GetOffset(codeView, node.StartLocation);
+ int endOffset = GetOffset(codeView, node.EndLocation);
+ codeView.Select(startOffset, endOffset - startOffset);
+ }
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/VBDemo.resx b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/VBDemo.resx
new file mode 100644
index 0000000000..1af7de150c
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/VBDemo.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/VBEditDialog.Designer.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/VBEditDialog.Designer.cs
new file mode 100644
index 0000000000..6d4254497d
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/VBEditDialog.Designer.cs
@@ -0,0 +1,88 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+namespace ICSharpCode.NRefactory.Demo
+{
+ partial class VBEditDialog : System.Windows.Forms.Form
+ {
+ ///
+ /// Designer variable used to keep track of non-visual components.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Disposes resources used by the form.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing) {
+ if (components != null) {
+ components.Dispose();
+ }
+ }
+ base.Dispose(disposing);
+ }
+
+ ///
+ /// This method is required for Windows Forms designer support.
+ /// Do not change the method contents inside the source code editor. The Forms designer might
+ /// not be able to load this method if it was changed manually.
+ ///
+ private void InitializeComponent()
+ {
+ this.propertyGrid = new System.Windows.Forms.PropertyGrid();
+ this.panel1 = new System.Windows.Forms.Panel();
+ this.okButton = new System.Windows.Forms.Button();
+ this.panel1.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // propertyGrid
+ //
+ this.propertyGrid.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.propertyGrid.HelpVisible = false;
+ this.propertyGrid.Location = new System.Drawing.Point(0, 0);
+ this.propertyGrid.Name = "propertyGrid";
+ this.propertyGrid.PropertySort = System.Windows.Forms.PropertySort.Alphabetical;
+ this.propertyGrid.Size = new System.Drawing.Size(477, 436);
+ this.propertyGrid.TabIndex = 0;
+ this.propertyGrid.ToolbarVisible = false;
+ //
+ // panel1
+ //
+ this.panel1.Controls.Add(this.okButton);
+ this.panel1.Dock = System.Windows.Forms.DockStyle.Bottom;
+ this.panel1.Location = new System.Drawing.Point(0, 436);
+ this.panel1.Name = "panel1";
+ this.panel1.Size = new System.Drawing.Size(477, 38);
+ this.panel1.TabIndex = 1;
+ //
+ // okButton
+ //
+ this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+ this.okButton.DialogResult = System.Windows.Forms.DialogResult.OK;
+ this.okButton.Location = new System.Drawing.Point(390, 6);
+ this.okButton.Name = "okButton";
+ this.okButton.Size = new System.Drawing.Size(75, 23);
+ this.okButton.TabIndex = 0;
+ this.okButton.Text = "OK";
+ this.okButton.UseVisualStyleBackColor = true;
+ //
+ // EditDialog
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.CancelButton = this.okButton;
+ this.ClientSize = new System.Drawing.Size(477, 474);
+ this.Controls.Add(this.propertyGrid);
+ this.Controls.Add(this.panel1);
+ this.Name = "EditDialog";
+ this.Text = "EditDialog";
+ this.panel1.ResumeLayout(false);
+ this.ResumeLayout(false);
+ }
+ private System.Windows.Forms.PropertyGrid propertyGrid;
+ private System.Windows.Forms.Button okButton;
+ private System.Windows.Forms.Panel panel1;
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/VBEditDialog.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/VBEditDialog.cs
new file mode 100644
index 0000000000..031ab9971b
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/VBEditDialog.cs
@@ -0,0 +1,18 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using System.Drawing;
+using System.Windows.Forms;
+
+namespace ICSharpCode.NRefactory.Demo
+{
+ public partial class VBEditDialog
+ {
+ public VBEditDialog(object element)
+ {
+ InitializeComponent();
+ propertyGrid.SelectedObject = element;
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/VBEditDialog.resx b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/VBEditDialog.resx
new file mode 100644
index 0000000000..7080a7d118
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Demo/VBEditDialog.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/.gitignore b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/.gitignore
new file mode 100644
index 0000000000..9ce745d95d
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/.gitignore
@@ -0,0 +1,3 @@
+
+bin/
+obj/
\ No newline at end of file
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Analysis/DefiniteAssignmentTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Analysis/DefiniteAssignmentTests.cs
new file mode 100644
index 0000000000..10373b84ca
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Analysis/DefiniteAssignmentTests.cs
@@ -0,0 +1,201 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using System.Linq;
+using ICSharpCode.NRefactory.TypeSystem;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Analysis
+{
+ [TestFixture]
+ public class DefiniteAssignmentTests
+ {
+ [Test]
+ public void TryFinally()
+ {
+ BlockStatement block = new BlockStatement {
+ new TryCatchStatement {
+ TryBlock = new BlockStatement {
+ new GotoStatement("LABEL"),
+ new AssignmentExpression(new IdentifierExpression("i"), new PrimitiveExpression(1))
+ },
+ CatchClauses = {
+ new CatchClause {
+ Body = new BlockStatement {
+ new AssignmentExpression(new IdentifierExpression("i"), new PrimitiveExpression(3))
+ }
+ }
+ },
+ FinallyBlock = new BlockStatement {
+ new AssignmentExpression(new IdentifierExpression("j"), new PrimitiveExpression(5))
+ }
+ },
+ new LabelStatement { Label = "LABEL" },
+ new EmptyStatement()
+ };
+ TryCatchStatement tryCatchStatement = (TryCatchStatement)block.Statements.First();
+ Statement stmt1 = tryCatchStatement.TryBlock.Statements.ElementAt(1);
+ Statement stmt3 = tryCatchStatement.CatchClauses.Single().Body.Statements.Single();
+ Statement stmt5 = tryCatchStatement.FinallyBlock.Statements.Single();
+ LabelStatement label = (LabelStatement)block.Statements.ElementAt(1);
+
+ DefiniteAssignmentAnalysis da = new DefiniteAssignmentAnalysis(block, CecilLoaderTests.Mscorlib);
+ da.Analyze("i");
+ Assert.AreEqual(0, da.UnassignedVariableUses.Count);
+ Assert.AreEqual(DefiniteAssignmentStatus.PotentiallyAssigned, da.GetStatusBefore(tryCatchStatement));
+ Assert.AreEqual(DefiniteAssignmentStatus.CodeUnreachable, da.GetStatusBefore(stmt1));
+ Assert.AreEqual(DefiniteAssignmentStatus.CodeUnreachable, da.GetStatusAfter(stmt1));
+ Assert.AreEqual(DefiniteAssignmentStatus.PotentiallyAssigned, da.GetStatusBefore(stmt3));
+ Assert.AreEqual(DefiniteAssignmentStatus.DefinitelyAssigned, da.GetStatusAfter(stmt3));
+ Assert.AreEqual(DefiniteAssignmentStatus.PotentiallyAssigned, da.GetStatusBefore(stmt5));
+ Assert.AreEqual(DefiniteAssignmentStatus.PotentiallyAssigned, da.GetStatusAfter(stmt5));
+ Assert.AreEqual(DefiniteAssignmentStatus.DefinitelyAssigned, da.GetStatusAfter(tryCatchStatement));
+ Assert.AreEqual(DefiniteAssignmentStatus.DefinitelyAssigned, da.GetStatusBefore(label));
+ Assert.AreEqual(DefiniteAssignmentStatus.PotentiallyAssigned, da.GetStatusAfter(label));
+
+ da.Analyze("j");
+ Assert.AreEqual(0, da.UnassignedVariableUses.Count);
+ Assert.AreEqual(DefiniteAssignmentStatus.PotentiallyAssigned, da.GetStatusBefore(tryCatchStatement));
+ Assert.AreEqual(DefiniteAssignmentStatus.CodeUnreachable, da.GetStatusBefore(stmt1));
+ Assert.AreEqual(DefiniteAssignmentStatus.CodeUnreachable, da.GetStatusAfter(stmt1));
+ Assert.AreEqual(DefiniteAssignmentStatus.PotentiallyAssigned, da.GetStatusBefore(stmt3));
+ Assert.AreEqual(DefiniteAssignmentStatus.PotentiallyAssigned, da.GetStatusAfter(stmt3));
+ Assert.AreEqual(DefiniteAssignmentStatus.PotentiallyAssigned, da.GetStatusBefore(stmt5));
+ Assert.AreEqual(DefiniteAssignmentStatus.DefinitelyAssigned, da.GetStatusAfter(stmt5));
+ Assert.AreEqual(DefiniteAssignmentStatus.DefinitelyAssigned, da.GetStatusAfter(tryCatchStatement));
+ Assert.AreEqual(DefiniteAssignmentStatus.DefinitelyAssigned, da.GetStatusBefore(label));
+ Assert.AreEqual(DefiniteAssignmentStatus.DefinitelyAssigned, da.GetStatusAfter(label));
+ }
+
+ [Test]
+ public void ConditionalAnd()
+ {
+ IfElseStatement ifStmt = new IfElseStatement {
+ Condition = new BinaryOperatorExpression {
+ Left = new BinaryOperatorExpression(new IdentifierExpression("x"), BinaryOperatorType.GreaterThan, new PrimitiveExpression(0)),
+ Operator = BinaryOperatorType.ConditionalAnd,
+ Right = new BinaryOperatorExpression {
+ Left = new ParenthesizedExpression {
+ Expression = new AssignmentExpression {
+ Left = new IdentifierExpression("i"),
+ Operator = AssignmentOperatorType.Assign,
+ Right = new IdentifierExpression("y")
+ }
+ },
+ Operator = BinaryOperatorType.GreaterThanOrEqual,
+ Right = new PrimitiveExpression(0)
+ }
+ },
+ TrueStatement = new BlockStatement(),
+ FalseStatement = new BlockStatement()
+ };
+ DefiniteAssignmentAnalysis da = new DefiniteAssignmentAnalysis(ifStmt, CecilLoaderTests.Mscorlib);
+ da.Analyze("i");
+ Assert.AreEqual(0, da.UnassignedVariableUses.Count);
+ Assert.AreEqual(DefiniteAssignmentStatus.PotentiallyAssigned, da.GetStatusBefore(ifStmt));
+ Assert.AreEqual(DefiniteAssignmentStatus.DefinitelyAssigned, da.GetStatusBefore(ifStmt.TrueStatement));
+ Assert.AreEqual(DefiniteAssignmentStatus.PotentiallyAssigned, da.GetStatusBefore(ifStmt.FalseStatement));
+ Assert.AreEqual(DefiniteAssignmentStatus.PotentiallyAssigned, da.GetStatusAfter(ifStmt));
+ }
+
+ [Test]
+ public void ConditionalOr()
+ {
+ IfElseStatement ifStmt = new IfElseStatement {
+ Condition = new BinaryOperatorExpression {
+ Left = new BinaryOperatorExpression(new IdentifierExpression("x"), BinaryOperatorType.GreaterThan, new PrimitiveExpression(0)),
+ Operator = BinaryOperatorType.ConditionalOr,
+ Right = new BinaryOperatorExpression {
+ Left = new ParenthesizedExpression {
+ Expression = new AssignmentExpression {
+ Left = new IdentifierExpression("i"),
+ Operator = AssignmentOperatorType.Assign,
+ Right = new IdentifierExpression("y")
+ }
+ },
+ Operator = BinaryOperatorType.GreaterThanOrEqual,
+ Right = new PrimitiveExpression(0)
+ }
+ },
+ TrueStatement = new BlockStatement(),
+ FalseStatement = new BlockStatement()
+ };
+ DefiniteAssignmentAnalysis da = new DefiniteAssignmentAnalysis(ifStmt, CecilLoaderTests.Mscorlib);
+ da.Analyze("i");
+ Assert.AreEqual(0, da.UnassignedVariableUses.Count);
+ Assert.AreEqual(DefiniteAssignmentStatus.PotentiallyAssigned, da.GetStatusBefore(ifStmt));
+ Assert.AreEqual(DefiniteAssignmentStatus.PotentiallyAssigned, da.GetStatusBefore(ifStmt.TrueStatement));
+ Assert.AreEqual(DefiniteAssignmentStatus.DefinitelyAssigned, da.GetStatusBefore(ifStmt.FalseStatement));
+ Assert.AreEqual(DefiniteAssignmentStatus.PotentiallyAssigned, da.GetStatusAfter(ifStmt));
+ }
+
+ [Test]
+ public void WhileTrue()
+ {
+ WhileStatement loop = new WhileStatement {
+ Condition = new PrimitiveExpression(true),
+ EmbeddedStatement = new BlockStatement {
+ new AssignmentExpression(new IdentifierExpression("i"), new PrimitiveExpression(0)),
+ new BreakStatement()
+ }
+ };
+ DefiniteAssignmentAnalysis da = new DefiniteAssignmentAnalysis(loop, CecilLoaderTests.Mscorlib);
+ da.Analyze("i");
+ Assert.AreEqual(0, da.UnassignedVariableUses.Count);
+ Assert.AreEqual(DefiniteAssignmentStatus.PotentiallyAssigned, da.GetStatusBefore(loop));
+ Assert.AreEqual(DefiniteAssignmentStatus.PotentiallyAssigned, da.GetStatusBefore(loop.EmbeddedStatement));
+ Assert.AreEqual(DefiniteAssignmentStatus.CodeUnreachable, da.GetStatusAfter(loop.EmbeddedStatement));
+ Assert.AreEqual(DefiniteAssignmentStatus.DefinitelyAssigned, da.GetStatusAfter(loop));
+ }
+
+ [Test]
+ public void ForLoop()
+ {
+ ForStatement loop = new ForStatement {
+ Initializers = {
+ new ExpressionStatement(
+ new AssignmentExpression(new IdentifierExpression("i"), new PrimitiveExpression(0))
+ )
+ },
+ Condition = new BinaryOperatorExpression(new IdentifierExpression("i"), BinaryOperatorType.LessThan, new PrimitiveExpression(1000)),
+ Iterators = {
+ new ExpressionStatement(
+ new AssignmentExpression {
+ Left = new IdentifierExpression("i"),
+ Operator = AssignmentOperatorType.Add,
+ Right = new IdentifierExpression("j")
+ }
+ )
+ },
+ EmbeddedStatement = new ExpressionStatement(
+ new AssignmentExpression(new IdentifierExpression("j"), new IdentifierExpression("i"))
+ )};
+
+ DefiniteAssignmentAnalysis da = new DefiniteAssignmentAnalysis(loop, CecilLoaderTests.Mscorlib);
+ da.Analyze("i");
+ Assert.AreEqual(0, da.UnassignedVariableUses.Count);
+ Assert.AreEqual(DefiniteAssignmentStatus.PotentiallyAssigned, da.GetStatusBefore(loop));
+ Assert.AreEqual(DefiniteAssignmentStatus.PotentiallyAssigned, da.GetStatusBefore(loop.Initializers.Single()));
+ Assert.AreEqual(DefiniteAssignmentStatus.DefinitelyAssigned, da.GetStatusAfter(loop.Initializers.Single()));
+ Assert.AreEqual(DefiniteAssignmentStatus.DefinitelyAssigned, da.GetStatusBeforeLoopCondition(loop));
+ Assert.AreEqual(DefiniteAssignmentStatus.DefinitelyAssigned, da.GetStatusBefore(loop.EmbeddedStatement));
+ Assert.AreEqual(DefiniteAssignmentStatus.DefinitelyAssigned, da.GetStatusAfter(loop.EmbeddedStatement));
+ Assert.AreEqual(DefiniteAssignmentStatus.DefinitelyAssigned, da.GetStatusBefore(loop.Iterators.Single()));
+ Assert.AreEqual(DefiniteAssignmentStatus.DefinitelyAssigned, da.GetStatusAfter(loop.Iterators.Single()));
+ Assert.AreEqual(DefiniteAssignmentStatus.DefinitelyAssigned, da.GetStatusAfter(loop));
+
+ da.Analyze("j");
+ Assert.AreEqual(0, da.UnassignedVariableUses.Count);
+ Assert.AreEqual(DefiniteAssignmentStatus.PotentiallyAssigned, da.GetStatusBefore(loop));
+ Assert.AreEqual(DefiniteAssignmentStatus.PotentiallyAssigned, da.GetStatusBefore(loop.Initializers.Single()));
+ Assert.AreEqual(DefiniteAssignmentStatus.PotentiallyAssigned, da.GetStatusAfter(loop.Initializers.Single()));
+ Assert.AreEqual(DefiniteAssignmentStatus.PotentiallyAssigned, da.GetStatusBeforeLoopCondition(loop));
+ Assert.AreEqual(DefiniteAssignmentStatus.PotentiallyAssigned, da.GetStatusBefore(loop.EmbeddedStatement));
+ Assert.AreEqual(DefiniteAssignmentStatus.DefinitelyAssigned, da.GetStatusAfter(loop.EmbeddedStatement));
+ Assert.AreEqual(DefiniteAssignmentStatus.DefinitelyAssigned, da.GetStatusBefore(loop.Iterators.Single()));
+ Assert.AreEqual(DefiniteAssignmentStatus.DefinitelyAssigned, da.GetStatusAfter(loop.Iterators.Single()));
+ Assert.AreEqual(DefiniteAssignmentStatus.PotentiallyAssigned, da.GetStatusAfter(loop));
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/AstStructureTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/AstStructureTests.cs
new file mode 100644
index 0000000000..183efacdb2
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/AstStructureTests.cs
@@ -0,0 +1,46 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using System.Reflection;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp
+{
+ [TestFixture]
+ public class AstStructureTests
+ {
+ [Test]
+ public void RolesAreStaticReadOnly()
+ {
+ foreach (Type type in typeof(AstNode).Assembly.GetExportedTypes()) {
+ if (type.IsSubclassOf(typeof(AstNode))) {
+ foreach (FieldInfo field in type.GetFields()) {
+ if (field.FieldType.IsSubclassOf(typeof(Role))) {
+ Assert.IsTrue(field.IsPublic);
+ Assert.IsTrue(field.IsStatic);
+ Assert.IsTrue(field.IsInitOnly);
+ Assert.IsTrue(field.Name.EndsWith("Role", StringComparison.Ordinal));
+ Assert.IsNotNull(field.GetValue(null));
+ }
+ }
+ }
+ }
+ }
+
+ [Test]
+ public void AstNodesDoNotDeriveFromEachOther()
+ {
+ // Ast nodes should derive only from abstract classes; not from concrete types.
+ // For example, we want to avoid that an AST consumer doing "if (node is PropertyDeclaration)"
+ // unknowingly also handles IndexerDeclarations.
+ foreach (Type type in typeof(AstNode).Assembly.GetExportedTypes()) {
+ if (type == typeof(CSharpModifierToken)) // CSharpModifierToken is the exception (though I'm not too happy about that)
+ continue;
+ if (type.IsSubclassOf(typeof(AstNode))) {
+ Assert.IsTrue(type.BaseType.IsAbstract, type.FullName);
+ }
+ }
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/InsertParenthesesVisitorTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/InsertParenthesesVisitorTests.cs
new file mode 100644
index 0000000000..b7f6328f3e
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/InsertParenthesesVisitorTests.cs
@@ -0,0 +1,349 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using System.IO;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp
+{
+ [TestFixture]
+ public class InsertParenthesesVisitorTests
+ {
+ CSharpFormattingOptions policy;
+
+ [SetUp]
+ public void SetUp()
+ {
+ policy = new CSharpFormattingOptions();
+ }
+
+ string InsertReadable(Expression expr)
+ {
+ expr = expr.Clone();
+ expr.AcceptVisitor(new InsertParenthesesVisitor { InsertParenthesesForReadability = true }, null);
+ StringWriter w = new StringWriter();
+ w.NewLine = " ";
+ expr.AcceptVisitor(new OutputVisitor(new TextWriterOutputFormatter(w) { IndentationString = "" }, policy), null);
+ return w.ToString();
+ }
+
+ string InsertRequired(Expression expr)
+ {
+ expr = expr.Clone();
+ expr.AcceptVisitor(new InsertParenthesesVisitor { InsertParenthesesForReadability = false }, null);
+ StringWriter w = new StringWriter();
+ w.NewLine = " ";
+ expr.AcceptVisitor(new OutputVisitor(new TextWriterOutputFormatter(w) { IndentationString = "" }, policy), null);
+ return w.ToString();
+ }
+
+ [Test]
+ public void EqualityInAssignment()
+ {
+ Expression expr = new AssignmentExpression(
+ new IdentifierExpression("cond"),
+ new BinaryOperatorExpression(
+ new IdentifierExpression("a"),
+ BinaryOperatorType.Equality,
+ new IdentifierExpression("b")
+ )
+ );
+
+ Assert.AreEqual("cond = a == b", InsertRequired(expr));
+ Assert.AreEqual("cond = (a == b)", InsertReadable(expr));
+ }
+
+ [Test]
+ public void TrickyCast1()
+ {
+ Expression expr = new UnaryOperatorExpression(
+ UnaryOperatorType.Minus, new IdentifierExpression("a")
+ ).CastTo(new PrimitiveType("int"));
+
+ Assert.AreEqual("(int)-a", InsertRequired(expr));
+ Assert.AreEqual("(int)(-a)", InsertReadable(expr));
+ }
+
+ [Test]
+ public void TrickyCast2()
+ {
+ Expression expr = new UnaryOperatorExpression(
+ UnaryOperatorType.Minus, new IdentifierExpression("a")
+ ).CastTo(new SimpleType("MyType"));
+
+ Assert.AreEqual("(MyType)(-a)", InsertRequired(expr));
+ Assert.AreEqual("(MyType)(-a)", InsertReadable(expr));
+ }
+
+ [Test]
+ public void TrickyCast3()
+ {
+ Expression expr = new UnaryOperatorExpression(
+ UnaryOperatorType.Not, new IdentifierExpression("a")
+ ).CastTo(new SimpleType("MyType"));
+
+ Assert.AreEqual("(MyType)!a", InsertRequired(expr));
+ Assert.AreEqual("(MyType)(!a)", InsertReadable(expr));
+ }
+
+ [Test]
+ public void TrickyCast4()
+ {
+ Expression expr = new PrimitiveExpression(int.MinValue).CastTo(new SimpleType("MyType"));
+
+ Assert.AreEqual("(MyType)(-2147483648)", InsertRequired(expr));
+ Assert.AreEqual("(MyType)(-2147483648)", InsertReadable(expr));
+ }
+
+ [Test]
+ public void TrickyCast5()
+ {
+ Expression expr = new PrimitiveExpression(-1.0).CastTo(new SimpleType("MyType"));
+
+ Assert.AreEqual("(MyType)(-1.0)", InsertRequired(expr));
+ Assert.AreEqual("(MyType)(-1.0)", InsertReadable(expr));
+ }
+
+ [Test]
+ public void TrickyCast6()
+ {
+ Expression expr = new PrimitiveExpression(int.MinValue).CastTo(new PrimitiveType("double"));
+
+ Assert.AreEqual("(double)-2147483648", InsertRequired(expr));
+ Assert.AreEqual("(double)-2147483648", InsertReadable(expr));
+ }
+
+ [Test]
+ public void CastAndInvoke()
+ {
+ Expression expr = new IdentifierExpression("a")
+ .CastTo(new PrimitiveType("string"))
+ .Member("Length");
+
+ Assert.AreEqual("((string)a).Length", InsertRequired(expr));
+ Assert.AreEqual("((string)a).Length", InsertReadable(expr));
+ }
+
+ [Test]
+ public void DoubleNegation()
+ {
+ Expression expr = new UnaryOperatorExpression(
+ UnaryOperatorType.Minus,
+ new UnaryOperatorExpression(UnaryOperatorType.Minus, new IdentifierExpression("a"))
+ );
+
+ Assert.AreEqual("- -a", InsertRequired(expr));
+ Assert.AreEqual("-(-a)", InsertReadable(expr));
+ }
+
+ [Test]
+ public void AdditionWithConditional()
+ {
+ Expression expr = new BinaryOperatorExpression {
+ Left = new IdentifierExpression("a"),
+ Operator = BinaryOperatorType.Add,
+ Right = new ConditionalExpression {
+ Condition = new BinaryOperatorExpression {
+ Left = new IdentifierExpression("b"),
+ Operator = BinaryOperatorType.Equality,
+ Right = new PrimitiveExpression(null)
+ },
+ TrueExpression = new IdentifierExpression("c"),
+ FalseExpression = new IdentifierExpression("d")
+ }
+ };
+
+ Assert.AreEqual("a + (b == null ? c : d)", InsertRequired(expr));
+ Assert.AreEqual("a + ((b == null) ? c : d)", InsertReadable(expr));
+ }
+
+ [Test]
+ public void TypeTestInConditional()
+ {
+ Expression expr = new ConditionalExpression {
+ Condition = new IdentifierExpression("a").IsType(
+ new ComposedType {
+ BaseType = new PrimitiveType("int"),
+ HasNullableSpecifier = true
+ }
+ ),
+ TrueExpression = new IdentifierExpression("b"),
+ FalseExpression = new IdentifierExpression("c")
+ };
+
+ Assert.AreEqual("a is int? ? b : c", InsertRequired(expr));
+ Assert.AreEqual("(a is int?) ? b : c", InsertReadable(expr));
+
+ policy.SpaceBeforeConditionalOperatorCondition = false;
+ policy.SpaceAfterConditionalOperatorCondition = false;
+ policy.SpaceBeforeConditionalOperatorSeparator = false;
+ policy.SpaceAfterConditionalOperatorSeparator = false;
+
+ Assert.AreEqual("a is int? ?b:c", InsertRequired(expr));
+ Assert.AreEqual("(a is int?)?b:c", InsertReadable(expr));
+ }
+
+ [Test]
+ public void MethodCallOnQueryExpression()
+ {
+ Expression expr = new QueryExpression {
+ Clauses = {
+ new QueryFromClause {
+ Identifier = "a",
+ Expression = new IdentifierExpression("b")
+ },
+ new QuerySelectClause {
+ Expression = new IdentifierExpression("a").Invoke("c")
+ }
+ }
+ }.Invoke("ToArray");
+
+ Assert.AreEqual("( from a in b select a.c ()).ToArray ()", InsertRequired(expr));
+ Assert.AreEqual("( from a in b select a.c ()).ToArray ()", InsertReadable(expr));
+ }
+
+ [Test]
+ public void SumOfQueries()
+ {
+ QueryExpression query = new QueryExpression {
+ Clauses = {
+ new QueryFromClause {
+ Identifier = "a",
+ Expression = new IdentifierExpression("b")
+ },
+ new QuerySelectClause {
+ Expression = new IdentifierExpression("a")
+ }
+ }
+ };
+ Expression expr = new BinaryOperatorExpression(
+ query,
+ BinaryOperatorType.Add,
+ query.Clone()
+ );
+
+ Assert.AreEqual("( from a in b select a) + " +
+ " from a in b select a", InsertRequired(expr));
+ Assert.AreEqual("( from a in b select a) + " +
+ "( from a in b select a)", InsertReadable(expr));
+ }
+
+ [Test]
+ public void QueryInTypeTest()
+ {
+ Expression expr = new QueryExpression {
+ Clauses = {
+ new QueryFromClause {
+ Identifier = "a",
+ Expression = new IdentifierExpression("b")
+ },
+ new QuerySelectClause {
+ Expression = new IdentifierExpression("a")
+ }
+ }
+ }.IsType(new PrimitiveType("int"));
+
+ Assert.AreEqual("( from a in b select a) is int", InsertRequired(expr));
+ Assert.AreEqual("( from a in b select a) is int", InsertReadable(expr));
+ }
+
+ [Test]
+ public void PrePost()
+ {
+ Expression expr = new UnaryOperatorExpression(
+ UnaryOperatorType.Increment,
+ new UnaryOperatorExpression(
+ UnaryOperatorType.PostIncrement,
+ new IdentifierExpression("a")
+ )
+ );
+
+ Assert.AreEqual("++a++", InsertRequired(expr));
+ Assert.AreEqual("++(a++)", InsertReadable(expr));
+ }
+
+ [Test]
+ public void PostPre()
+ {
+ Expression expr = new UnaryOperatorExpression(
+ UnaryOperatorType.PostIncrement,
+ new UnaryOperatorExpression(
+ UnaryOperatorType.Increment,
+ new IdentifierExpression("a")
+ )
+ );
+
+ Assert.AreEqual("(++a)++", InsertRequired(expr));
+ Assert.AreEqual("(++a)++", InsertReadable(expr));
+ }
+
+ [Test]
+ public void Logical1()
+ {
+ Expression expr = new BinaryOperatorExpression(
+ new BinaryOperatorExpression(
+ new IdentifierExpression("a"),
+ BinaryOperatorType.ConditionalAnd,
+ new IdentifierExpression("b")
+ ),
+ BinaryOperatorType.ConditionalAnd,
+ new IdentifierExpression("c")
+ );
+
+ Assert.AreEqual("a && b && c", InsertRequired(expr));
+ Assert.AreEqual("a && b && c", InsertReadable(expr));
+ }
+
+ [Test]
+ public void Logical2()
+ {
+ Expression expr = new BinaryOperatorExpression(
+ new IdentifierExpression("a"),
+ BinaryOperatorType.ConditionalAnd,
+ new BinaryOperatorExpression(
+ new IdentifierExpression("b"),
+ BinaryOperatorType.ConditionalAnd,
+ new IdentifierExpression("c")
+ )
+ );
+
+ Assert.AreEqual("a && (b && c)", InsertRequired(expr));
+ Assert.AreEqual("a && (b && c)", InsertReadable(expr));
+ }
+
+ [Test]
+ public void Logical3()
+ {
+ Expression expr = new BinaryOperatorExpression(
+ new IdentifierExpression("a"),
+ BinaryOperatorType.ConditionalOr,
+ new BinaryOperatorExpression(
+ new IdentifierExpression("b"),
+ BinaryOperatorType.ConditionalAnd,
+ new IdentifierExpression("c")
+ )
+ );
+
+ Assert.AreEqual("a || b && c", InsertRequired(expr));
+ Assert.AreEqual("a || (b && c)", InsertReadable(expr));
+ }
+
+ [Test]
+ public void Logical4()
+ {
+ Expression expr = new BinaryOperatorExpression(
+ new IdentifierExpression("a"),
+ BinaryOperatorType.ConditionalAnd,
+ new BinaryOperatorExpression(
+ new IdentifierExpression("b"),
+ BinaryOperatorType.ConditionalOr,
+ new IdentifierExpression("c")
+ )
+ );
+
+ Assert.AreEqual("a && (b || c)", InsertRequired(expr));
+ Assert.AreEqual("a && (b || c)", InsertReadable(expr));
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/AliasReferenceExpressionTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/AliasReferenceExpressionTests.cs
new file mode 100644
index 0000000000..a3ec92054f
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/AliasReferenceExpressionTests.cs
@@ -0,0 +1,53 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+
+using System;
+using System.IO;
+using NUnit.Framework;
+using ICSharpCode.NRefactory.PatternMatching;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
+{
+ [TestFixture]
+ public class AliasReferenceExpressionTests
+ {
+ [Test]
+ public void GlobalReferenceExpressionTest()
+ {
+ CSharpParser parser = new CSharpParser();
+ AstType type = parser.ParseTypeReference(new StringReader("global::System"));
+ Assert.IsTrue(
+ new MemberType {
+ Target = new SimpleType("global"),
+ IsDoubleColon = true,
+ MemberName = "System"
+ }.IsMatch(type)
+ );
+ }
+
+ [Test]
+ public void GlobalTypeDeclaration()
+ {
+ VariableDeclarationStatement lvd = ParseUtilCSharp.ParseStatement("global::System.String a;");
+ Assert.IsTrue(
+ new VariableDeclarationStatement {
+ Type = new MemberType {
+ Target = new MemberType {
+ Target = new SimpleType("global"),
+ IsDoubleColon = true,
+ MemberName = "System"
+ },
+ IsDoubleColon = false,
+ MemberName = "String",
+ },
+ Variables = {
+ new VariableInitializer("a")
+ }
+ }.IsMatch(lvd)
+ );
+ }
+
+ // TODO: add tests for aliases other than 'global'
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/AnonymousMethodTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/AnonymousMethodTests.cs
new file mode 100644
index 0000000000..710df07ec1
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/AnonymousMethodTests.cs
@@ -0,0 +1,56 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using System.IO;
+using System.Linq;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
+{
+ [TestFixture]
+ public class AnonymousMethodTests
+ {
+ AnonymousMethodExpression Parse(string expression)
+ {
+ return ParseUtilCSharp.ParseExpression(expression);
+ }
+
+ [Test]
+ public void AnonymousMethodWithoutParameterList()
+ {
+ AnonymousMethodExpression ame = Parse("delegate {}");
+ Assert.AreEqual(0, ame.Parameters.Count());
+ Assert.AreEqual(0, ame.Body.Statements.Count());
+ Assert.IsFalse(ame.HasParameterList);
+ }
+
+ [Test]
+ public void AnonymousMethodAfterCast()
+ {
+ CastExpression c = ParseUtilCSharp.ParseExpression("(ThreadStart)delegate {}");
+ AnonymousMethodExpression ame = (AnonymousMethodExpression)c.Expression;
+ Assert.AreEqual(0, ame.Parameters.Count());
+ Assert.AreEqual(0, ame.Body.Statements.Count());
+ }
+
+ [Test]
+ public void EmptyAnonymousMethod()
+ {
+ AnonymousMethodExpression ame = Parse("delegate() {}");
+ Assert.AreEqual(0, ame.Parameters.Count());
+ Assert.AreEqual(0, ame.Body.Statements.Count());
+ Assert.IsTrue(ame.HasParameterList);
+ }
+
+ [Test]
+ public void SimpleAnonymousMethod()
+ {
+ AnonymousMethodExpression ame = Parse("delegate(int a, int b) { return a + b; }");
+ Assert.IsTrue(ame.HasParameterList);
+ Assert.AreEqual(2, ame.Parameters.Count());
+ Assert.AreEqual(1, ame.Body.Statements.Count());
+ Assert.IsTrue(ame.Body.Statements.First() is ReturnStatement);
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/ArrayObjectCreateExpressionTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/ArrayObjectCreateExpressionTests.cs
new file mode 100644
index 0000000000..a6d3ec0177
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/ArrayObjectCreateExpressionTests.cs
@@ -0,0 +1,56 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
+{
+ [TestFixture]
+ public class ArrayObjectCreateExpressionTests
+ {
+ [Test]
+ public void ArrayCreateExpressionTest1()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "new int[5]",
+ new ArrayCreateExpression {
+ Type = new PrimitiveType("int"),
+ Arguments = { new PrimitiveExpression(5) }
+ });
+ }
+
+ [Test]
+ public void MultidimensionalNestedArray()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "new int[5,2][,,][]",
+ new ArrayCreateExpression {
+ Type = new PrimitiveType("int"),
+ Arguments = { new PrimitiveExpression(5), new PrimitiveExpression(2) },
+ AdditionalArraySpecifiers = {
+ new ArraySpecifier(3),
+ new ArraySpecifier(1)
+ }
+ });
+ }
+
+ [Test]
+ public void ImplicitlyTypedArrayCreateExpression()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "new[] { 1, 10, 100, 1000 }",
+ new ArrayCreateExpression {
+ Initializer = new ArrayInitializerExpression {
+ Elements = {
+ new PrimitiveExpression(1),
+ new PrimitiveExpression(10),
+ new PrimitiveExpression(100),
+ new PrimitiveExpression(1000)
+ }
+ }
+ });
+
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/AssignmentExpressionTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/AssignmentExpressionTests.cs
new file mode 100644
index 0000000000..065b88bba1
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/AssignmentExpressionTests.cs
@@ -0,0 +1,88 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
+{
+ [TestFixture]
+ public class AssignmentExpressionTests
+ {
+ void TestAssignmentExpression(string program, AssignmentOperatorType op)
+ {
+ AssignmentExpression ae = ParseUtilCSharp.ParseExpression(program);
+
+ Assert.AreEqual(op, ae.Operator);
+
+ Assert.IsTrue(ae.Left is IdentifierExpression);
+ Assert.IsTrue(ae.Right is IdentifierExpression);
+ }
+
+ [Test]
+ public void AssignTest()
+ {
+ TestAssignmentExpression("a = b", AssignmentOperatorType.Assign);
+ }
+
+ [Test]
+ public void AddTest()
+ {
+ TestAssignmentExpression("a += b", AssignmentOperatorType.Add);
+ }
+
+ [Test]
+ public void SubtractTest()
+ {
+ TestAssignmentExpression("a -= b", AssignmentOperatorType.Subtract);
+ }
+
+ [Test]
+ public void MultiplyTest()
+ {
+ TestAssignmentExpression("a *= b", AssignmentOperatorType.Multiply);
+ }
+
+ [Test]
+ public void DivideTest()
+ {
+ TestAssignmentExpression("a /= b", AssignmentOperatorType.Divide);
+ }
+
+ [Test]
+ public void ModulusTest()
+ {
+ TestAssignmentExpression("a %= b", AssignmentOperatorType.Modulus);
+ }
+
+ [Test]
+ public void ShiftLeftTest()
+ {
+ TestAssignmentExpression("a <<= b", AssignmentOperatorType.ShiftLeft);
+ }
+
+ [Test]
+ public void ShiftRightTest()
+ {
+ TestAssignmentExpression("a >>= b", AssignmentOperatorType.ShiftRight);
+ }
+
+ [Test]
+ public void BitwiseAndTest()
+ {
+ TestAssignmentExpression("a &= b", AssignmentOperatorType.BitwiseAnd);
+ }
+
+ [Test]
+ public void BitwiseOrTest()
+ {
+ TestAssignmentExpression("a |= b", AssignmentOperatorType.BitwiseOr);
+ }
+
+ [Test]
+ public void ExclusiveOrTest()
+ {
+ TestAssignmentExpression("a ^= b", AssignmentOperatorType.ExclusiveOr);
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/BaseReferenceExpressionTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/BaseReferenceExpressionTests.cs
new file mode 100644
index 0000000000..4bde43b92d
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/BaseReferenceExpressionTests.cs
@@ -0,0 +1,19 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
+{
+ [TestFixture]
+ public class BaseReferenceExpressionTests
+ {
+ [Test]
+ public void BaseReferenceExpressionTest1()
+ {
+ MemberReferenceExpression fre = ParseUtilCSharp.ParseExpression("base.myField");
+ Assert.IsTrue(fre.Target is BaseReferenceExpression);
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/BinaryOperatorExpressionTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/BinaryOperatorExpressionTests.cs
new file mode 100644
index 0000000000..9e133b7637
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/BinaryOperatorExpressionTests.cs
@@ -0,0 +1,227 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
+{
+ [TestFixture]
+ public class BinaryOperatorExpressionTests
+ {
+ #region Precedence Tests
+ void OperatorPrecedenceTest(string strongOperator, BinaryOperatorType strongOperatorType,
+ string weakOperator, BinaryOperatorType weakOperatorType, bool vb)
+ {
+ string program = "a " + weakOperator + " b " + strongOperator + " c";
+ BinaryOperatorExpression boe = ParseUtilCSharp.ParseExpression(program);
+ Assert.AreEqual(weakOperatorType, boe.Operator);
+ Assert.IsTrue(boe.Left is IdentifierExpression);
+ boe = (BinaryOperatorExpression)boe.Right;
+ Assert.AreEqual(strongOperatorType, boe.Operator);
+ Assert.IsTrue(boe.Left is IdentifierExpression);
+ Assert.IsTrue(boe.Right is IdentifierExpression);
+
+ program = "a " + strongOperator + " b " + weakOperator + " c";
+
+ boe = ParseUtilCSharp.ParseExpression(program);
+ Assert.AreEqual(weakOperatorType, boe.Operator);
+ Assert.IsTrue(boe.Right is IdentifierExpression);
+ boe = (BinaryOperatorExpression)boe.Left;
+ Assert.AreEqual(strongOperatorType, boe.Operator);
+ Assert.IsTrue(boe.Left is IdentifierExpression);
+ Assert.IsTrue(boe.Right is IdentifierExpression);
+ }
+
+ void SameOperatorPrecedenceTest(string firstOperator, BinaryOperatorType firstOperatorType,
+ string secondOperator, BinaryOperatorType secondOperatorType, bool vb)
+ {
+ string program = "a " + secondOperator + " b " + firstOperator + " c";
+ BinaryOperatorExpression boe = ParseUtilCSharp.ParseExpression(program);
+ Assert.AreEqual(firstOperatorType, boe.Operator);
+ Assert.IsTrue(boe.Right is IdentifierExpression);
+ boe = (BinaryOperatorExpression)boe.Left;
+ Assert.AreEqual(secondOperatorType, boe.Operator);
+ Assert.IsTrue(boe.Left is IdentifierExpression);
+ Assert.IsTrue(boe.Right is IdentifierExpression);
+
+ program = "a " + firstOperator + " b " + secondOperator + " c";
+ boe = ParseUtilCSharp.ParseExpression(program);
+ Assert.AreEqual(secondOperatorType, boe.Operator);
+ Assert.IsTrue(boe.Right is IdentifierExpression);
+ boe = (BinaryOperatorExpression)boe.Left;
+ Assert.AreEqual(firstOperatorType, boe.Operator);
+ Assert.IsTrue(boe.Left is IdentifierExpression);
+ Assert.IsTrue(boe.Right is IdentifierExpression);
+ }
+
+ [Test]
+ public void OperatorPrecedenceTest()
+ {
+ SameOperatorPrecedenceTest("*", BinaryOperatorType.Multiply, "/", BinaryOperatorType.Divide, false);
+ SameOperatorPrecedenceTest("*", BinaryOperatorType.Multiply, "%", BinaryOperatorType.Modulus, false);
+ OperatorPrecedenceTest("*", BinaryOperatorType.Multiply, "+", BinaryOperatorType.Add, false);
+ SameOperatorPrecedenceTest("-", BinaryOperatorType.Subtract, "+", BinaryOperatorType.Add, false);
+ OperatorPrecedenceTest("+", BinaryOperatorType.Add, "<<", BinaryOperatorType.ShiftLeft, false);
+ SameOperatorPrecedenceTest(">>", BinaryOperatorType.ShiftRight, "<<", BinaryOperatorType.ShiftLeft, false);
+ OperatorPrecedenceTest("<<", BinaryOperatorType.ShiftLeft, "==", BinaryOperatorType.Equality, false);
+ SameOperatorPrecedenceTest("!=", BinaryOperatorType.InEquality, "==", BinaryOperatorType.Equality, false);
+ OperatorPrecedenceTest("==", BinaryOperatorType.Equality, "&", BinaryOperatorType.BitwiseAnd, false);
+ OperatorPrecedenceTest("&", BinaryOperatorType.BitwiseAnd, "^", BinaryOperatorType.ExclusiveOr, false);
+ OperatorPrecedenceTest("^", BinaryOperatorType.ExclusiveOr, "|", BinaryOperatorType.BitwiseOr, false);
+ OperatorPrecedenceTest("|", BinaryOperatorType.BitwiseOr, "&&", BinaryOperatorType.ConditionalAnd, false);
+ OperatorPrecedenceTest("&&", BinaryOperatorType.ConditionalAnd, "||", BinaryOperatorType.ConditionalOr, false);
+ OperatorPrecedenceTest("||", BinaryOperatorType.ConditionalOr, "??", BinaryOperatorType.NullCoalescing, false);
+ }
+ #endregion
+
+ void TestBinaryOperatorExpressionTest(string program, BinaryOperatorType op)
+ {
+ BinaryOperatorExpression boe = ParseUtilCSharp.ParseExpression(program);
+ Assert.AreEqual(op, boe.Operator);
+
+ Assert.IsTrue(boe.Left is IdentifierExpression);
+ Assert.IsTrue(boe.Right is IdentifierExpression);
+
+ }
+
+ [Test]
+ public void SubtractionLeftToRight()
+ {
+ BinaryOperatorExpression boe = ParseUtilCSharp.ParseExpression("a - b - c");
+ Assert.IsTrue(boe.Right is IdentifierExpression);
+ Assert.IsTrue(boe.Left is BinaryOperatorExpression);
+ }
+
+ [Test]
+ public void NullCoalescingRightToLeft()
+ {
+ BinaryOperatorExpression boe = ParseUtilCSharp.ParseExpression("a ?? b ?? c");
+ Assert.IsTrue(boe.Left is IdentifierExpression);
+ Assert.IsTrue(boe.Right is BinaryOperatorExpression);
+ }
+
+ [Test]
+ public void BitwiseAndTest()
+ {
+ TestBinaryOperatorExpressionTest("a & b", BinaryOperatorType.BitwiseAnd);
+ }
+
+ [Test]
+ public void BitwiseOrTest()
+ {
+ TestBinaryOperatorExpressionTest("a | b", BinaryOperatorType.BitwiseOr);
+ }
+
+ [Test]
+ public void LogicalAndTest()
+ {
+ TestBinaryOperatorExpressionTest("a && b", BinaryOperatorType.ConditionalAnd);
+ }
+
+ [Test]
+ public void LogicalOrTest()
+ {
+ TestBinaryOperatorExpressionTest("a || b", BinaryOperatorType.ConditionalOr);
+ }
+
+ [Test]
+ public void ExclusiveOrTest()
+ {
+ TestBinaryOperatorExpressionTest("a ^ b", BinaryOperatorType.ExclusiveOr);
+ }
+
+
+ [Test]
+ public void GreaterThanTest()
+ {
+ TestBinaryOperatorExpressionTest("a > b", BinaryOperatorType.GreaterThan);
+ }
+
+ [Test]
+ public void GreaterThanOrEqualTest()
+ {
+ TestBinaryOperatorExpressionTest("a >= b", BinaryOperatorType.GreaterThanOrEqual);
+ }
+
+ [Test]
+ public void EqualityTest()
+ {
+ TestBinaryOperatorExpressionTest("a == b", BinaryOperatorType.Equality);
+ }
+
+ [Test]
+ public void InEqualityTest()
+ {
+ TestBinaryOperatorExpressionTest("a != b", BinaryOperatorType.InEquality);
+ }
+
+ [Test]
+ public void LessThanTest()
+ {
+ TestBinaryOperatorExpressionTest("a < b", BinaryOperatorType.LessThan);
+ }
+
+ [Test]
+ public void LessThanOrEqualTest()
+ {
+ TestBinaryOperatorExpressionTest("a <= b", BinaryOperatorType.LessThanOrEqual);
+ }
+
+ [Test]
+ public void AddTest()
+ {
+ TestBinaryOperatorExpressionTest("a + b", BinaryOperatorType.Add);
+ }
+
+ [Test]
+ public void SubtractTest()
+ {
+ TestBinaryOperatorExpressionTest("a - b", BinaryOperatorType.Subtract);
+ }
+
+ [Test]
+ public void MultiplyTest()
+ {
+ TestBinaryOperatorExpressionTest("a * b", BinaryOperatorType.Multiply);
+ }
+
+ [Test]
+ public void DivideTest()
+ {
+ TestBinaryOperatorExpressionTest("a / b", BinaryOperatorType.Divide);
+ }
+
+ [Test]
+ public void ModulusTest()
+ {
+ TestBinaryOperatorExpressionTest("a % b", BinaryOperatorType.Modulus);
+ }
+
+ [Test]
+ public void ShiftLeftTest()
+ {
+ TestBinaryOperatorExpressionTest("a << b", BinaryOperatorType.ShiftLeft);
+ }
+
+ [Test]
+ public void ShiftRightTest()
+ {
+ TestBinaryOperatorExpressionTest("a >> b", BinaryOperatorType.ShiftRight);
+ }
+
+ [Test]
+ public void NullCoalescingTest()
+ {
+ TestBinaryOperatorExpressionTest("a ?? b", BinaryOperatorType.NullCoalescing);
+ }
+
+ [Test]
+ public void LessThanOrGreaterTest()
+ {
+ const string expr = "i1 < 0 || i1 > (Count - 1)";
+ BinaryOperatorExpression boe = ParseUtilCSharp.ParseExpression(expr);
+ Assert.AreEqual(BinaryOperatorType.ConditionalOr, boe.Operator);
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/CastExpressionTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/CastExpressionTests.cs
new file mode 100644
index 0000000000..2909f71843
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/CastExpressionTests.cs
@@ -0,0 +1,165 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
+{
+ [TestFixture]
+ public class CastExpressionTests
+ {
+ [Test]
+ public void SimpleCastExpression()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "(MyObject)o",
+ new CastExpression {
+ Type = new SimpleType("MyObject"),
+ Expression = new IdentifierExpression("o")
+ });
+ }
+
+ [Test]
+ public void ArrayCastExpression()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "(MyType[])o",
+ new CastExpression {
+ Type = new SimpleType("MyType").MakeArrayType(1),
+ Expression = new IdentifierExpression("o")
+ });
+ }
+
+ [Test]
+ public void NullablePrimitiveCastExpression()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "(int?)o",
+ new CastExpression {
+ Type = new ComposedType { BaseType = new PrimitiveType("int"), HasNullableSpecifier = true },
+ Expression = new IdentifierExpression("o")
+ });
+ }
+
+ [Test]
+ public void NullableCastExpression()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "(MyType?)o",
+ new CastExpression {
+ Type = new ComposedType { BaseType = new SimpleType("MyType"), HasNullableSpecifier = true },
+ Expression = new IdentifierExpression("o")
+ });
+ }
+
+ [Test]
+ public void NullableTryCastExpression()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "o as int?",
+ new AsExpression {
+ Type = new ComposedType { BaseType = new PrimitiveType("int"), HasNullableSpecifier = true },
+ Expression = new IdentifierExpression("o")
+ });
+ }
+
+ [Test]
+ public void GenericCastExpression()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "(List)o",
+ new CastExpression {
+ Type = new SimpleType("List") { TypeArguments = { new PrimitiveType("string") } },
+ Expression = new IdentifierExpression("o")
+ });
+ }
+
+ [Test]
+ public void GenericArrayCastExpression()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "(List[])o",
+ new CastExpression {
+ Type = new ComposedType {
+ BaseType = new SimpleType("List") { TypeArguments = { new PrimitiveType("string") } },
+ ArraySpecifiers = { new ArraySpecifier(1) }
+ },
+ Expression = new IdentifierExpression("o")
+ });
+ }
+
+ [Test]
+ public void GenericArrayAsCastExpression()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "o as List[]",
+ new AsExpression {
+ Type = new ComposedType {
+ BaseType = new SimpleType("List") { TypeArguments = { new PrimitiveType("string") } },
+ ArraySpecifiers = { new ArraySpecifier(1) }
+ },
+ Expression = new IdentifierExpression("o")
+ });
+ }
+
+ [Test]
+ public void CastMemberReferenceOnParenthesizedExpression()
+ {
+ // yes, we really want to evaluate .Member on expr and THEN cast the result to MyType
+ ParseUtilCSharp.AssertExpression(
+ "(MyType)(expr).Member",
+ new CastExpression {
+ Type = new SimpleType("MyType"),
+ Expression = new ParenthesizedExpression { Expression = new IdentifierExpression("expr") }.Member("Member")
+ });
+ }
+
+ [Test]
+ public void TryCastParenthesizedExpression()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "(o) as string",
+ new AsExpression {
+ Expression = new ParenthesizedExpression { Expression = new IdentifierExpression("o") },
+ Type = new PrimitiveType("string")
+ });
+ }
+
+ [Test]
+ public void CastNegation()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "(uint)-negativeValue",
+ new CastExpression {
+ Type = new PrimitiveType("uint"),
+ Expression = new UnaryOperatorExpression(
+ UnaryOperatorType.Minus,
+ new IdentifierExpression("negativeValue")
+ )});
+ }
+
+ [Test]
+ public void SubtractionIsNotCast()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "(BigInt)-negativeValue",
+ new BinaryOperatorExpression {
+ Left = new ParenthesizedExpression { Expression = new IdentifierExpression("BigInt") },
+ Operator = BinaryOperatorType.Subtract,
+ Right = new IdentifierExpression("negativeValue")
+ });
+ }
+
+ [Test, Ignore ("TODO")]
+ public void IntMaxValueToBigInt()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "(BigInt)int.MaxValue",
+ new CastExpression {
+ Type = new SimpleType("BigInt"),
+ Expression = new PrimitiveExpression("int").Member("MaxValue")
+ });
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/CheckedExpressionTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/CheckedExpressionTests.cs
new file mode 100644
index 0000000000..696a28b7a6
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/CheckedExpressionTests.cs
@@ -0,0 +1,26 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
+{
+ [TestFixture]
+ public class CheckedExpressionTests
+ {
+ [Test]
+ public void CheckedExpressionTest()
+ {
+ CheckedExpression ce = ParseUtilCSharp.ParseExpression("checked(a)");
+ Assert.IsTrue(ce.Expression is IdentifierExpression);
+ }
+
+ [Test]
+ public void UncheckedExpressionTest()
+ {
+ UncheckedExpression ce = ParseUtilCSharp.ParseExpression("unchecked(a)");
+ Assert.IsTrue(ce.Expression is IdentifierExpression);
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/ConditionalExpressionTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/ConditionalExpressionTests.cs
new file mode 100644
index 0000000000..819b16582d
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/ConditionalExpressionTests.cs
@@ -0,0 +1,104 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
+{
+ [TestFixture]
+ public class ConditionalExpressionTests
+ {
+ [Test]
+ public void ConditionalExpressionTest()
+ {
+ ConditionalExpression ce = ParseUtilCSharp.ParseExpression("a == b ? a() : a.B");
+
+ Assert.IsTrue(ce.Condition is BinaryOperatorExpression);
+ Assert.IsTrue(ce.TrueExpression is InvocationExpression);
+ Assert.IsTrue(ce.FalseExpression is MemberReferenceExpression);
+ }
+
+ [Test]
+ public void ConditionalIsExpressionTest()
+ {
+ // (as is b?) ERROR (conflict with nullables, SD-419)
+ ConditionalExpression ce = ParseUtilCSharp.ParseExpression("a is b ? a() : a.B");
+
+ Assert.IsTrue(ce.Condition is IsExpression);
+ Assert.IsTrue(ce.TrueExpression is InvocationExpression);
+ Assert.IsTrue(ce.FalseExpression is MemberReferenceExpression);
+ }
+
+ [Test]
+ public void ConditionalIsWithNullableExpressionTest()
+ {
+ ConditionalExpression ce = ParseUtilCSharp.ParseExpression("a is b? ? a() : a.B");
+
+ Assert.IsTrue(ce.Condition is IsExpression);
+ Assert.IsTrue(ce.TrueExpression is InvocationExpression);
+ Assert.IsTrue(ce.FalseExpression is MemberReferenceExpression);
+ }
+
+ [Test]
+ public void ConditionalIsExpressionTest2()
+ {
+ ConditionalExpression ce = ParseUtilCSharp.ParseExpression("a is b ? (a()) : a.B");
+
+ Assert.IsTrue(ce.Condition is IsExpression);
+ Assert.IsTrue(ce.TrueExpression is ParenthesizedExpression);
+ Assert.IsTrue(ce.FalseExpression is MemberReferenceExpression);
+ }
+
+ [Test]
+ public void ConditionalExpressionNegativeValue()
+ {
+ ConditionalExpression ce = ParseUtilCSharp.ParseExpression("isNegative ? -1 : 1");
+
+ Assert.IsTrue(ce.Condition is IdentifierExpression);
+ Assert.IsTrue(ce.TrueExpression is UnaryOperatorExpression);
+ Assert.IsTrue(ce.FalseExpression is PrimitiveExpression);
+ }
+
+
+ [Test]
+ public void ConditionalIsWithNegativeValue()
+ {
+ ConditionalExpression ce = ParseUtilCSharp.ParseExpression("a is b ? -1 : 1");
+
+ Assert.IsTrue(ce.Condition is IsExpression);
+ Assert.IsTrue(ce.TrueExpression is UnaryOperatorExpression);
+ Assert.IsTrue(ce.FalseExpression is PrimitiveExpression);
+ }
+
+ [Test]
+ public void ConditionalIsWithExplicitPositiveValue()
+ {
+ ConditionalExpression ce = ParseUtilCSharp.ParseExpression("a is b ? +1 : 1");
+
+ Assert.IsTrue(ce.Condition is IsExpression);
+ Assert.IsTrue(ce.TrueExpression is UnaryOperatorExpression);
+ Assert.IsTrue(ce.FalseExpression is PrimitiveExpression);
+ }
+
+ [Test]
+ public void RepeatedConditionalExpr()
+ {
+ ConditionalExpression ce = ParseUtilCSharp.ParseExpression("a ? b : c ? d : e");
+
+ Assert.AreEqual("a", ((IdentifierExpression)ce.Condition).Identifier);
+ Assert.AreEqual("b", ((IdentifierExpression)ce.TrueExpression).Identifier);
+ Assert.IsTrue(ce.FalseExpression is ConditionalExpression);
+ }
+
+ [Test]
+ public void NestedConditionalExpr()
+ {
+ ConditionalExpression ce = ParseUtilCSharp.ParseExpression("a ? b ? c : d : e");
+
+ Assert.AreEqual("a", ((IdentifierExpression)ce.Condition).Identifier);
+ Assert.AreEqual("e", ((IdentifierExpression)ce.FalseExpression).Identifier);
+ Assert.IsTrue(ce.TrueExpression is ConditionalExpression);
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/DefaultValueExpressionTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/DefaultValueExpressionTests.cs
new file mode 100644
index 0000000000..03f5617535
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/DefaultValueExpressionTests.cs
@@ -0,0 +1,79 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
+{
+ [TestFixture]
+ public class DefaultValueExpressionTests
+ {
+ [Test]
+ public void SimpleDefaultValue()
+ {
+ DefaultValueExpression toe = ParseUtilCSharp.ParseExpression("default(T)");
+ Assert.AreEqual("T", ((SimpleType)toe.Type).Identifier);
+ }
+
+ [Test]
+ public void FullQualifiedDefaultValue()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "default(global::MyNamespace.N1.MyType)",
+ new DefaultValueExpression {
+ Type = new MemberType {
+ Target = new MemberType {
+ Target = new MemberType {
+ Target = new SimpleType("global"),
+ IsDoubleColon = true,
+ MemberName = "MyNamespace"
+ },
+ MemberName = "N1"
+ },
+ MemberName = "MyType"
+ }
+ });
+ }
+
+ [Test]
+ public void GenericDefaultValue()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "default(MyNamespace.N1.MyType)",
+ new DefaultValueExpression {
+ Type = new MemberType {
+ Target = new MemberType {
+ Target = new SimpleType("MyNamespace"),
+ MemberName = "N1"
+ },
+ MemberName = "MyType",
+ TypeArguments = { new PrimitiveType("string") }
+ }
+ });
+ }
+
+ [Test]
+ public void DefaultValueAsIntializer()
+ {
+ // This test was problematic (in old NRefactory) because we need a resolver for the "default:" / "default(" conflict.
+ ParseUtilCSharp.AssertStatement(
+ "T a = default(T);",
+ new VariableDeclarationStatement {
+ Type = new SimpleType("T"),
+ Variables = {
+ new VariableInitializer("a", new DefaultValueExpression { Type = new SimpleType("T") })
+ }});
+ }
+
+ [Test]
+ public void DefaultValueInReturnStatement()
+ {
+ ParseUtilCSharp.AssertStatement(
+ "return default(T);",
+ new ReturnStatement {
+ Expression = new DefaultValueExpression { Type = new SimpleType("T") }
+ });
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/IdentifierExpressionTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/IdentifierExpressionTests.cs
new file mode 100644
index 0000000000..5a054efe6f
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/IdentifierExpressionTests.cs
@@ -0,0 +1,87 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using NUnit.Framework;
+using ICSharpCode.NRefactory.PatternMatching;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
+{
+ [TestFixture]
+ public class IdentifierExpressionTests
+ {
+ void CheckIdentifier(string sourceCode, string identifier)
+ {
+ IdentifierExpression ident = ParseUtilCSharp.ParseExpression(sourceCode);
+ Assert.AreEqual(identifier, ident.Identifier);
+ }
+
+ [Test]
+ public void TestIdentifier()
+ {
+ CheckIdentifier("a_Bc05", "a_Bc05");
+ }
+
+ [Test]
+ public void TestIdentifierStartingWithUnderscore()
+ {
+ CheckIdentifier("_Bc05", "_Bc05");
+ }
+
+ [Test]
+ public void TestIdentifierStartingWithEscapeSequence()
+ {
+ CheckIdentifier(@"\u006cexer", "lexer");
+ }
+
+ [Test]
+ public void TestIdentifierContainingEscapeSequence()
+ {
+ CheckIdentifier(@"l\U00000065xer", "lexer");
+ }
+
+ [Test, Ignore("The @ should not be part of IdentifierExpression.Identifier")]
+ public void TestKeyWordAsIdentifier()
+ {
+ CheckIdentifier("@int", "int");
+ }
+
+ [Test, Ignore("Mono parser bug?")]
+ public void TestKeywordWithEscapeSequenceIsIdentifier()
+ {
+ CheckIdentifier(@"i\u006et", "int");
+ }
+
+ [Test, Ignore("The @ should not be part of IdentifierExpression.Identifier")]
+ public void TestKeyWordAsIdentifierStartingWithUnderscore()
+ {
+ CheckIdentifier("@_int", "_int");
+ }
+
+ [Test]
+ public void GenericMethodReference()
+ {
+ IdentifierExpression ident = ParseUtilCSharp.ParseExpression("M");
+ Assert.IsTrue(
+ new IdentifierExpression {
+ Identifier = "M" ,
+ TypeArguments = {
+ new PrimitiveType("int")
+ }
+ }.IsMatch(ident));
+ }
+
+ [Test]
+ public void GenericMethodReference2()
+ {
+ IdentifierExpression ident = ParseUtilCSharp.ParseExpression("TargetMethod");
+ Assert.IsTrue(
+ new IdentifierExpression {
+ Identifier = "TargetMethod" ,
+ TypeArguments = {
+ new PrimitiveType("string")
+ }
+ }.IsMatch(ident));
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/IndexerExpressionTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/IndexerExpressionTests.cs
new file mode 100644
index 0000000000..1a46dc63ff
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/IndexerExpressionTests.cs
@@ -0,0 +1,29 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using System.Linq;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
+{
+ [TestFixture]
+ public class IndexerExpressionTests
+ {
+ [Test]
+ public void IndexerExpressionTest()
+ {
+ IndexerExpression ie = ParseUtilCSharp.ParseExpression("field[1, \"Hello\", 'a']");
+ Assert.IsTrue(ie.Target is IdentifierExpression);
+
+ Assert.AreEqual(3, ie.Arguments.Count());
+
+ Assert.IsTrue(ie.Arguments.ElementAt(0) is PrimitiveExpression);
+ Assert.AreEqual(1, (int)((PrimitiveExpression)ie.Arguments.ElementAt(0)).Value);
+ Assert.IsTrue(ie.Arguments.ElementAt(1) is PrimitiveExpression);
+ Assert.AreEqual("Hello", (string)((PrimitiveExpression)ie.Arguments.ElementAt(1)).Value);
+ Assert.IsTrue(ie.Arguments.ElementAt(2) is PrimitiveExpression);
+ Assert.AreEqual('a', (char)((PrimitiveExpression)ie.Arguments.ElementAt(2)).Value);
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/InvocationExpressionTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/InvocationExpressionTests.cs
new file mode 100644
index 0000000000..53c89bbf89
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/InvocationExpressionTests.cs
@@ -0,0 +1,172 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using System.Linq;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
+{
+ [TestFixture]
+ public class InvocationExpressionTests
+ {
+ [Test]
+ public void SimpleInvocationExpressionTest()
+ {
+ var ie = ParseUtilCSharp.ParseExpression("myMethod()");
+ Assert.AreEqual(0, ie.Arguments.Count());
+ Assert.IsTrue(ie.Target is IdentifierExpression);
+ Assert.AreEqual("myMethod", ((IdentifierExpression)ie.Target).Identifier);
+ }
+
+ [Test]
+ public void GenericInvocationExpressionTest()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "myMethod('a')",
+ new InvocationExpression {
+ Target = new IdentifierExpression {
+ Identifier = "myMethod",
+ TypeArguments = { new PrimitiveType("char") }
+ },
+ Arguments = { new PrimitiveExpression('a') }
+ }
+ );
+ }
+
+ [Test]
+ public void GenericInvocation2ExpressionTest()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "myMethod()",
+ new InvocationExpression {
+ Target = new IdentifierExpression {
+ Identifier = "myMethod",
+ TypeArguments = {
+ new SimpleType("T"),
+ new PrimitiveType("bool")
+ }
+ }
+ }
+ );
+ }
+
+ [Test]
+ public void AmbiguousGrammarGenericMethodCall()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "F(G(7))",
+ new InvocationExpression {
+ Target = new IdentifierExpression("F"),
+ Arguments = {
+ new InvocationExpression {
+ Target = new IdentifierExpression {
+ Identifier = "G",
+ TypeArguments = { new SimpleType("A"), new SimpleType("B") }
+ },
+ Arguments = { new PrimitiveExpression(7) }
+ }}});
+ }
+
+ [Test, Ignore("Mono Parser Bug???")]
+ public void AmbiguousGrammarNotAGenericMethodCall()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "F+y",
+ new BinaryOperatorExpression {
+ Left = new BinaryOperatorExpression {
+ Left = new IdentifierExpression("F"),
+ Operator = BinaryOperatorType.LessThan,
+ Right = new IdentifierExpression("A")
+ },
+ Operator = BinaryOperatorType.GreaterThan,
+ Right = new UnaryOperatorExpression {
+ Operator = UnaryOperatorType.Plus,
+ Expression = new IdentifierExpression("y")
+ }});
+ }
+
+ [Test]
+ public void InvalidNestedInvocationExpressionTest()
+ {
+ // this test was written because this bug caused the AbstractASTVisitor to crash
+
+ InvocationExpression expr = ParseUtilCSharp.ParseExpression("WriteLine(myMethod(,))", true);
+ Assert.IsTrue(expr.Target is IdentifierExpression);
+ Assert.AreEqual("WriteLine", ((IdentifierExpression)expr.Target).Identifier);
+
+ Assert.AreEqual(1, expr.Arguments.Count); // here a second null parameter was added incorrectly
+
+ Assert.IsTrue(expr.Arguments.Single() is InvocationExpression);
+ }
+
+ [Test, Ignore("Positions not yet accurate when parsing expression only (because class/method is added around it)")]
+ public void NestedInvocationPositions()
+ {
+ InvocationExpression expr = ParseUtilCSharp.ParseExpression("a.B().C(args)");
+ Assert.AreEqual(new AstLocation(1, 8), expr.StartLocation);
+ Assert.AreEqual(new AstLocation(1, 14), expr.EndLocation);
+ MemberReferenceExpression mre = (MemberReferenceExpression)expr.Target;
+ Assert.AreEqual(new AstLocation(1, 6), mre.StartLocation);
+ Assert.AreEqual(new AstLocation(1, 8), mre.EndLocation);
+
+ Assert.AreEqual(new AstLocation(1, 4), mre.Target.StartLocation);
+ Assert.AreEqual(new AstLocation(1, 6), mre.Target.EndLocation);
+ }
+
+ [Test]
+ public void InvocationOnGenericType()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "A.Foo()",
+ new IdentifierExpression {
+ Identifier = "A",
+ TypeArguments = { new SimpleType("T") }
+ }.Invoke("Foo")
+ );
+ }
+
+ [Test]
+ public void InvocationOnInnerClassInGenericType()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "A.B.Foo()",
+ new IdentifierExpression {
+ Identifier = "A",
+ TypeArguments = { new SimpleType("T") }
+ }.Member("B").Invoke("Foo")
+ );
+ }
+
+ [Test]
+ public void InvocationOnGenericInnerClassInGenericType()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "A.B.C.Foo()",
+ new MemberReferenceExpression {
+ Target = new IdentifierExpression {
+ Identifier = "A",
+ TypeArguments = { new SimpleType("T") }
+ }.Member("B"),
+ MemberName = "C",
+ TypeArguments = { new SimpleType("U") }
+ }.Invoke("Foo"));
+ }
+
+ [Test]
+ public void InvocationWithNamedArgument()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "a(arg: ref v)",
+ new InvocationExpression {
+ Target = new IdentifierExpression("a"),
+ Arguments = {
+ new NamedArgumentExpression {
+ Identifier = "arg",
+ Expression = new DirectionExpression {
+ FieldDirection = FieldDirection.Ref,
+ Expression = new IdentifierExpression("v")
+ }}}});
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/IsExpressionTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/IsExpressionTests.cs
new file mode 100644
index 0000000000..bbab99a6f4
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/IsExpressionTests.cs
@@ -0,0 +1,46 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
+{
+ [TestFixture]
+ public class IsExpressionTests
+ {
+ [Test]
+ public void GenericArrayIsExpression()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "o is List[]",
+ new IsExpression {
+ Expression = new IdentifierExpression("o"),
+ Type = new SimpleType("List") { TypeArguments = { new PrimitiveType("string") } }.MakeArrayType(1)
+ }
+ );
+ }
+
+ [Test]
+ public void NullableIsExpression()
+ {
+ IsExpression ce = ParseUtilCSharp.ParseExpression("o is int?");
+ ComposedType type = (ComposedType)ce.Type;
+ Assert.IsTrue(type.HasNullableSpecifier);
+ Assert.AreEqual("int", ((PrimitiveType)type.BaseType).Keyword);
+ Assert.IsTrue(ce.Expression is IdentifierExpression);
+ }
+
+ [Test]
+ public void NullableIsExpressionInBinaryOperatorExpression()
+ {
+ BinaryOperatorExpression boe;
+ boe = ParseUtilCSharp.ParseExpression("o is int? == true");
+ IsExpression ce = (IsExpression)boe.Left;
+ ComposedType type = (ComposedType)ce.Type;
+ Assert.IsTrue(type.HasNullableSpecifier);
+ Assert.AreEqual("int", ((PrimitiveType)type.BaseType).Keyword);
+ Assert.IsTrue(ce.Expression is IdentifierExpression);
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/LambdaExpressionTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/LambdaExpressionTests.cs
new file mode 100644
index 0000000000..d389bac7c1
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/LambdaExpressionTests.cs
@@ -0,0 +1,108 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
+{
+ [TestFixture]
+ public class LambdaExpressionTests
+ {
+ [Test]
+ public void ImplicitlyTypedExpressionBody()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "(x) => x + 1",
+ new LambdaExpression {
+ Parameters = { new ParameterDeclaration { Name = "x" } },
+ Body = new BinaryOperatorExpression(new IdentifierExpression("x"), BinaryOperatorType.Add, new PrimitiveExpression(1))
+ });
+ }
+
+ [Test]
+ public void ImplicitlyTypedExpressionBodyWithoutParenthesis()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "x => x + 1",
+ new LambdaExpression {
+ Parameters = { new ParameterDeclaration { Name = "x" } },
+ Body = new BinaryOperatorExpression(new IdentifierExpression("x"), BinaryOperatorType.Add, new PrimitiveExpression(1))
+ });
+ }
+
+ [Test]
+ public void ImplicitlyTypedStatementBody()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "(x) => { return x + 1; }",
+ new LambdaExpression {
+ Parameters = { new ParameterDeclaration { Name = "x" } },
+ Body = new BlockStatement {
+ new ReturnStatement {
+ Expression = new BinaryOperatorExpression(
+ new IdentifierExpression("x"), BinaryOperatorType.Add, new PrimitiveExpression(1))
+ }}});
+ }
+
+ [Test]
+ public void ImplicitlyTypedStatementBodyWithoutParenthesis()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "x => { return x + 1; }",
+ new LambdaExpression {
+ Parameters = { new ParameterDeclaration { Name = "x" } },
+ Body = new BlockStatement {
+ new ReturnStatement {
+ Expression = new BinaryOperatorExpression(
+ new IdentifierExpression("x"), BinaryOperatorType.Add, new PrimitiveExpression(1))
+ }}});
+ }
+
+ [Test]
+ public void ExplicitlyTypedStatementBody()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "(int x) => { return x + 1; }",
+ new LambdaExpression {
+ Parameters = { new ParameterDeclaration { Type = new PrimitiveType("int"), Name = "x" } },
+ Body = new BlockStatement {
+ new ReturnStatement {
+ Expression = new BinaryOperatorExpression(
+ new IdentifierExpression("x"), BinaryOperatorType.Add, new PrimitiveExpression(1))
+ }}});
+ }
+
+ [Test]
+ public void ExplicitlyTypedWithRefParameter()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "(ref int i) => i = 1",
+ new LambdaExpression {
+ Parameters = {
+ new ParameterDeclaration {
+ ParameterModifier = ParameterModifier.Ref,
+ Type = new PrimitiveType("int"),
+ Name = "i"
+ }
+ },
+ Body = new AssignmentExpression(new IdentifierExpression("i"), new PrimitiveExpression(1))
+ });
+ }
+
+ [Test]
+ public void LambdaExpressionContainingConditionalExpression()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "rr => rr != null ? rr.ResolvedType : null",
+ new LambdaExpression {
+ Parameters = { new ParameterDeclaration { Name = "rr" } },
+ Body = new ConditionalExpression {
+ Condition = new BinaryOperatorExpression(
+ new IdentifierExpression("rr"), BinaryOperatorType.InEquality, new NullReferenceExpression()),
+ TrueExpression = new IdentifierExpression("rr").Member("ResolvedType"),
+ FalseExpression = new NullReferenceExpression()
+ }});
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/MemberReferenceExpressionTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/MemberReferenceExpressionTests.cs
new file mode 100644
index 0000000000..038b33644d
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/MemberReferenceExpressionTests.cs
@@ -0,0 +1,93 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
+{
+ [TestFixture]
+ public class MemberReferenceExpressionTests
+ {
+ [Test]
+ public void SimpleFieldReferenceExpressionTest()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "myTargetObject.myField",
+ new IdentifierExpression("myTargetObject").Member("myField")
+ );
+ }
+
+ [Test, Ignore("parser is broken and produces IdentifierExpression instead of PrimitiveType")]
+ public void ShortMaxValueTest()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "short.MaxValue",
+ new PrimitiveType("short").Member("MaxValue")
+ );
+ }
+
+ [Test, Ignore("Parsing of @-identifiers is broken")]
+ public void IdentShortMaxValueTest()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "@short.MaxValue",
+ new IdentifierExpression("short").Member("MaxValue")
+ );
+ }
+
+ [Test]
+ public void GenericFieldReferenceExpressionTest()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "SomeClass.myField",
+ new IdentifierExpression("SomeClass") { TypeArguments = { new PrimitiveType("string") } }.Member("myField")
+ );
+ }
+
+ [Test]
+ public void FullNamespaceGenericFieldReferenceExpressionTest()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "Namespace.Subnamespace.SomeClass.myField",
+ new MemberReferenceExpression {
+ Target = new IdentifierExpression("Namespace").Member("Subnamespace"),
+ TypeArguments = { new PrimitiveType("string") }
+ }.Member("myField")
+ );
+ }
+
+ [Test]
+ public void GlobalFullNamespaceGenericFieldReferenceExpressionTest()
+ {
+ var target = new MemberType {
+ Target = new SimpleType("global"),
+ IsDoubleColon = true,
+ MemberName = "Namespace"
+ }.Member("Subnamespace").Member ("SomeClass");
+
+ target.AddChild (new PrimitiveType("string"), MemberReferenceExpression.Roles.TypeArgument);
+
+ ParseUtilCSharp.AssertExpression(
+ "global::Namespace.Subnamespace.SomeClass.myField",
+ new MemberReferenceExpression {
+ Target = target,
+ MemberName = "myField"
+ }
+ );
+ }
+
+ [Test]
+ public void NestedGenericFieldReferenceExpressionTest()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "MyType.InnerClass.myField",
+ new MemberReferenceExpression {
+ Target = new IdentifierExpression("MyType") { TypeArguments = { new PrimitiveType("string") } },
+ MemberName = "InnerClass",
+ TypeArguments = { new PrimitiveType("int") }
+ }.Member("myField")
+ );
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/ParenthesizedExpressionTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/ParenthesizedExpressionTests.cs
new file mode 100644
index 0000000000..c60bcbf1f9
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/ParenthesizedExpressionTests.cs
@@ -0,0 +1,21 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
+{
+ [TestFixture]
+ public class ParenthesizedExpressionTests
+ {
+ [Test]
+ public void PrimitiveParenthesizedExpression()
+ {
+ ParenthesizedExpression p = ParseUtilCSharp.ParseExpression("((1))");
+ Assert.IsTrue(p.Expression is ParenthesizedExpression);
+ p = (ParenthesizedExpression)p.Expression;
+ Assert.IsTrue(p.Expression is PrimitiveExpression);
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/PointerReferenceExpressionTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/PointerReferenceExpressionTests.cs
new file mode 100644
index 0000000000..8104524b91
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/PointerReferenceExpressionTests.cs
@@ -0,0 +1,33 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
+{
+ [TestFixture]
+ public class PointerReferenceExpressionTests
+ {
+ [Test]
+ public void PointerReferenceExpressionTest()
+ {
+ PointerReferenceExpression pre = ParseUtilCSharp.ParseExpression("myObj.field->b");
+ Assert.IsTrue(pre.Target is MemberReferenceExpression);
+ Assert.AreEqual("b", pre.MemberName);
+ }
+
+ [Test]
+ public void PointerReferenceGenericMethodTest()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "ptr->M();",
+ new InvocationExpression {
+ Target = new PointerReferenceExpression {
+ Target = new IdentifierExpression("ptr"),
+ MemberName = "M",
+ TypeArguments = { new PrimitiveType("string") }
+ }});
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/PrimitiveExpressionTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/PrimitiveExpressionTests.cs
new file mode 100644
index 0000000000..9b4b1efcc6
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/PrimitiveExpressionTests.cs
@@ -0,0 +1,203 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using System.Linq;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
+{
+ [TestFixture]
+ public class PrimitiveExpressionTests
+ {
+ [Test]
+ public void HexIntegerTest1()
+ {
+ InvocationExpression invExpr = ParseUtilCSharp.ParseExpression("0xAFFE.ToString()");
+ Assert.AreEqual(0, invExpr.Arguments.Count());
+ Assert.IsTrue(invExpr.Target is MemberReferenceExpression);
+ MemberReferenceExpression fre = invExpr.Target as MemberReferenceExpression;
+ Assert.AreEqual("ToString", fre.MemberName);
+
+ Assert.IsTrue(fre.Target is PrimitiveExpression);
+ PrimitiveExpression pe = fre.Target as PrimitiveExpression;
+
+ Assert.AreEqual(0xAFFE, (int)pe.Value);
+
+ }
+
+ void CheckLiteral(string code, object value)
+ {
+ PrimitiveExpression pe = ParseUtilCSharp.ParseExpression(code);
+ Assert.AreEqual(value.GetType(), pe.Value.GetType());
+ Assert.AreEqual(value, pe.Value);
+ }
+
+ [Test]
+ public void DoubleTest1()
+ {
+ CheckLiteral(".5e-06", .5e-06);
+ }
+
+ [Test]
+ public void CharTest1()
+ {
+ CheckLiteral("'\\u0356'", '\u0356');
+ }
+
+ [Test, Ignore("this special case isn't implemented yet")]
+ public void IntMinValueTest()
+ {
+ CheckLiteral("-2147483648", -2147483648);
+ }
+
+ [Test]
+ public void IntMaxValueTest()
+ {
+ CheckLiteral("2147483647", 2147483647); // int
+ CheckLiteral("2147483648", 2147483648); // uint
+ }
+
+ [Test, Ignore("this special case isn't implemented yet")]
+ public void LongMinValueTest()
+ {
+ CheckLiteral("-9223372036854775808", -9223372036854775808);
+ }
+
+ [Test]
+ public void LongMaxValueTest()
+ {
+ CheckLiteral("9223372036854775807", 9223372036854775807); // long
+ CheckLiteral("9223372036854775808", 9223372036854775808); // ulong
+ }
+
+ [Test]
+ public void StringTest1()
+ {
+ CheckLiteral("\"\\n\\t\\u0005 Hello World !!!\"", "\n\t\u0005 Hello World !!!");
+ }
+
+ [Test]
+ public void TestSingleDigit()
+ {
+ CheckLiteral("5", 5);
+ }
+
+ [Test]
+ public void TestZero()
+ {
+ CheckLiteral("0", 0);
+ }
+
+ [Test]
+ public void TestInteger()
+ {
+ CheckLiteral("66", 66);
+ }
+
+ [Test]
+ public void TestNonOctalInteger()
+ {
+ // C# does not have octal integers, so 077 should parse to 77
+ Assert.IsTrue(077 == 77);
+
+ CheckLiteral("077", 077);
+ CheckLiteral("056", 056);
+ }
+
+ [Test]
+ public void TestHexadecimalInteger()
+ {
+ CheckLiteral("0x99F", 0x99F);
+ CheckLiteral("0xAB1f", 0xAB1f);
+ CheckLiteral("0xffffffff", 0xffffffff);
+ CheckLiteral("0xffffffffL", 0xffffffffL);
+ CheckLiteral("0xffffffffuL", 0xffffffffuL);
+ }
+
+ [Test]
+ public void InvalidHexadecimalInteger()
+ {
+ // don't check result, just make sure there is no exception
+ ParseUtilCSharp.ParseExpression("0x2GF", expectErrors: true);
+ ParseUtilCSharp.ParseExpression("0xG2F", expectErrors: true);
+ ParseUtilCSharp.ParseExpression("0x", expectErrors: true); // SD-457
+ // hexadecimal integer >ulong.MaxValue
+ ParseUtilCSharp.ParseExpression("0xfedcba98765432100", expectErrors: true);
+ }
+
+ [Test]
+ public void TestLongHexadecimalInteger()
+ {
+ CheckLiteral("0x4244636f446c6d58", 0x4244636f446c6d58);
+ CheckLiteral("0xf244636f446c6d58", 0xf244636f446c6d58);
+ }
+
+ [Test]
+ public void TestLongInteger()
+ {
+ CheckLiteral("9223372036854775807", 9223372036854775807); // long.MaxValue
+ CheckLiteral("9223372036854775808", 9223372036854775808); // long.MaxValue+1
+ CheckLiteral("18446744073709551615", 18446744073709551615); // ulong.MaxValue
+ }
+
+ [Test]
+ public void TestTooLongInteger()
+ {
+ // ulong.MaxValue+1
+ ParseUtilCSharp.ParseExpression("18446744073709551616", expectErrors: true);
+
+ CheckLiteral("18446744073709551616f", 18446744073709551616f); // ulong.MaxValue+1 as float
+ CheckLiteral("18446744073709551616d", 18446744073709551616d); // ulong.MaxValue+1 as double
+ CheckLiteral("18446744073709551616m", 18446744073709551616m); // ulong.MaxValue+1 as decimal
+ }
+
+ [Test]
+ public void TestDouble()
+ {
+ CheckLiteral("1.0", 1.0);
+ CheckLiteral("1.1", 1.1);
+ CheckLiteral("1.1e-2", 1.1e-2);
+ }
+
+ [Test]
+ public void TestFloat()
+ {
+ CheckLiteral("1f", 1f);
+ CheckLiteral("1.0f", 1.0f);
+ CheckLiteral("1.1f", 1.1f);
+ CheckLiteral("1.1e-2f", 1.1e-2f);
+ }
+
+ [Test]
+ public void TestDecimal()
+ {
+ CheckLiteral("1m", 1m);
+ CheckLiteral("1.0m", 1.0m);
+ CheckLiteral("1.1m", 1.1m);
+ CheckLiteral("1.1e-2m", 1.1e-2m);
+ CheckLiteral("2.0e-5m", 2.0e-5m);
+ }
+
+ [Test]
+ public void TestString()
+ {
+ CheckLiteral(@"@""-->""""<--""", @"-->""<--");
+ CheckLiteral(@"""-->\""<--""", "-->\"<--");
+
+ CheckLiteral(@"""\U00000041""", "\U00000041");
+ CheckLiteral(@"""\U00010041""", "\U00010041");
+ }
+
+ [Test]
+ public void TestCharLiteral()
+ {
+ CheckLiteral(@"'a'", 'a');
+ CheckLiteral(@"'\u0041'", '\u0041');
+ CheckLiteral(@"'\x41'", '\x41');
+ CheckLiteral(@"'\x041'", '\x041');
+ CheckLiteral(@"'\x0041'", '\x0041');
+ CheckLiteral(@"'\U00000041'", '\U00000041');
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/QueryExpressionTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/QueryExpressionTests.cs
new file mode 100644
index 0000000000..35e3f54896
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/QueryExpressionTests.cs
@@ -0,0 +1,284 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
+{
+ [TestFixture]
+ public class QueryExpressionTests
+ {
+ [Test]
+ public void SimpleExpression()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "from c in customers where c.City == \"London\" select c",
+ new QueryExpression {
+ Clauses = {
+ new QueryFromClause {
+ Identifier = "c",
+ Expression = new IdentifierExpression("customers")
+ },
+ new QueryWhereClause {
+ Condition = new BinaryOperatorExpression {
+ Left = new IdentifierExpression("c").Member("City"),
+ Operator = BinaryOperatorType.Equality,
+ Right = new PrimitiveExpression("London")
+ }
+ },
+ new QuerySelectClause {
+ Expression = new IdentifierExpression("c")
+ }
+ }});
+ }
+
+ [Test]
+ public void ExpressionWithType1()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "from Customer c in customers select c",
+ new QueryExpression {
+ Clauses = {
+ new QueryFromClause {
+ Type = new SimpleType("Customer"),
+ Identifier = "c",
+ Expression = new IdentifierExpression("customers")
+ },
+ new QuerySelectClause {
+ Expression = new IdentifierExpression("c")
+ }
+ }});
+ }
+
+ [Test]
+ public void ExpressionWithType2()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "from int c in customers select c",
+ new QueryExpression {
+ Clauses = {
+ new QueryFromClause {
+ Type = new PrimitiveType("int"),
+ Identifier = "c",
+ Expression = new IdentifierExpression("customers")
+ },
+ new QuerySelectClause {
+ Expression = new IdentifierExpression("c")
+ }
+ }});
+ }
+
+
+ [Test]
+ public void ExpressionWithType3()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "from S? c in customers select c",
+ new QueryExpression {
+ Clauses = {
+ new QueryFromClause {
+ Type = new ComposedType {
+ BaseType = new SimpleType {
+ Identifier = "S",
+ TypeArguments = {
+ new PrimitiveType("int").MakeArrayType()
+ }
+ },
+ HasNullableSpecifier = true
+ },
+ Identifier = "c",
+ Expression = new IdentifierExpression("customers")
+ },
+ new QuerySelectClause {
+ Expression = new IdentifierExpression("c")
+ }
+ }});
+ }
+
+ [Test]
+ public void MultipleGenerators()
+ {
+ ParseUtilCSharp.AssertExpression(
+ @"
+from c in customers
+where c.City == ""London""
+from o in c.Orders
+where o.OrderDate.Year == 2005
+select new { c.Name, o.OrderID, o.Total }",
+ new QueryExpression {
+ Clauses = {
+ new QueryFromClause {
+ Identifier = "c",
+ Expression = new IdentifierExpression("customers")
+ },
+ new QueryWhereClause {
+ Condition = new BinaryOperatorExpression {
+ Left = new IdentifierExpression("c").Member("City"),
+ Operator = BinaryOperatorType.Equality,
+ Right = new PrimitiveExpression("London")
+ }
+ },
+ new QueryFromClause {
+ Identifier = "o",
+ Expression = new IdentifierExpression("c").Member("Orders")
+ },
+ new QueryWhereClause {
+ Condition = new BinaryOperatorExpression {
+ Left = new IdentifierExpression("o").Member("OrderDate").Member("Year"),
+ Operator = BinaryOperatorType.Equality,
+ Right = new PrimitiveExpression(2005)
+ }
+ },
+ new QuerySelectClause {
+ Expression = new AnonymousTypeCreateExpression {
+ Initializer = {
+ new IdentifierExpression("c").Member("Name"),
+ new IdentifierExpression("o").Member("OrderID"),
+ new IdentifierExpression("o").Member("Total")
+ }
+ }
+ }
+ }});
+ }
+
+ [Test]
+ public void ExpressionWithOrderBy()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "from c in customers orderby c.Name select c",
+ new QueryExpression {
+ Clauses = {
+ new QueryFromClause {
+ Identifier = "c",
+ Expression = new IdentifierExpression("customers")
+ },
+ new QueryOrderClause {
+ Orderings = {
+ new QueryOrdering {
+ Expression = new IdentifierExpression("c").Member("Name")
+ }
+ }
+ },
+ new QuerySelectClause {
+ Expression = new IdentifierExpression("c")
+ }
+ }});
+ }
+
+ [Test]
+ public void ExpressionWithOrderByAndLet()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "from c in customers orderby c.Name descending let x = c select x",
+ new QueryExpression {
+ Clauses = {
+ new QueryFromClause {
+ Identifier = "c",
+ Expression = new IdentifierExpression("customers")
+ },
+ new QueryOrderClause {
+ Orderings = {
+ new QueryOrdering {
+ Expression = new IdentifierExpression("c").Member("Name"),
+ Direction = QueryOrderingDirection.Descending
+ }
+ }
+ },
+ new QueryLetClause {
+ Identifier = "x",
+ Expression = new IdentifierExpression("c")
+ },
+ new QuerySelectClause {
+ Expression = new IdentifierExpression("x")
+ }
+ }});
+ }
+
+ [Test]
+ public void QueryContinuation()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "from a in b select c into d select e",
+ new QueryExpression {
+ Clauses = {
+ new QueryContinuationClause {
+ PrecedingQuery = new QueryExpression {
+ Clauses = {
+ new QueryFromClause {
+ Identifier = "a",
+ Expression = new IdentifierExpression("b")
+ },
+ new QuerySelectClause { Expression = new IdentifierExpression("c") }
+ }
+ },
+ Identifier = "d"
+ },
+ new QuerySelectClause { Expression = new IdentifierExpression("e") }
+ }
+ }
+ );
+ }
+
+
+ [Test]
+ public void QueryContinuationWithMultipleFrom()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "from a in b from c in d select e into f select g",
+ new QueryExpression {
+ Clauses = {
+ new QueryContinuationClause {
+ PrecedingQuery = new QueryExpression {
+ Clauses = {
+ new QueryFromClause {
+ Identifier = "a",
+ Expression = new IdentifierExpression("b")
+ },
+ new QueryFromClause {
+ Identifier = "c",
+ Expression = new IdentifierExpression("d")
+ },
+ new QuerySelectClause { Expression = new IdentifierExpression("e") }
+ }
+ },
+ Identifier = "f"
+ },
+ new QuerySelectClause { Expression = new IdentifierExpression("g") }
+ }
+ }
+ );
+ }
+
+ [Test]
+ public void MultipleQueryContinuation()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "from a in b select c into d select e into f select g",
+ new QueryExpression {
+ Clauses = {
+ new QueryContinuationClause {
+ PrecedingQuery = new QueryExpression {
+ Clauses = {
+ new QueryContinuationClause {
+ PrecedingQuery = new QueryExpression {
+ Clauses = {
+ new QueryFromClause {
+ Identifier = "a",
+ Expression = new IdentifierExpression("b")
+ },
+ new QuerySelectClause { Expression = new IdentifierExpression("c") }
+ }
+ },
+ Identifier = "d"
+ },
+ new QuerySelectClause { Expression = new IdentifierExpression("e") }
+ }
+ },
+ Identifier = "f"
+ },
+ new QuerySelectClause { Expression = new IdentifierExpression("g") }
+ }});
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/SizeOfExpressionTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/SizeOfExpressionTests.cs
new file mode 100644
index 0000000000..f6a85fcb3b
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/SizeOfExpressionTests.cs
@@ -0,0 +1,19 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
+{
+ [TestFixture]
+ public class SizeOfExpressionTests
+ {
+ [Test]
+ public void SizeOfExpressionTest()
+ {
+ SizeOfExpression soe = ParseUtilCSharp.ParseExpression("sizeof(MyType)");
+ Assert.AreEqual("MyType", ((SimpleType)soe.Type).Identifier);
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/StackAllocExpressionTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/StackAllocExpressionTests.cs
new file mode 100644
index 0000000000..c28d559fcb
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/StackAllocExpressionTests.cs
@@ -0,0 +1,22 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using System.Linq;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
+{
+ [TestFixture]
+ public class StackAllocExpressionTests
+ {
+ [Test]
+ public void StackAllocExpressionTest()
+ {
+ var vd = ParseUtilCSharp.ParseStatement("int* a = stackalloc int[100];");
+ StackAllocExpression sae = (StackAllocExpression)vd.Variables.Single().Initializer;
+ Assert.AreEqual("int", ((PrimitiveType)sae.Type).Keyword);
+ Assert.AreEqual(100, ((PrimitiveExpression)sae.CountExpression).Value);
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/ThisReferenceExpressionTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/ThisReferenceExpressionTests.cs
new file mode 100644
index 0000000000..7c547adeac
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/ThisReferenceExpressionTests.cs
@@ -0,0 +1,18 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
+{
+ [TestFixture]
+ public class ThisReferenceExpressionTests
+ {
+ [Test]
+ public void TestMethod()
+ {
+ ParseUtilCSharp.ParseExpression("this");
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/TypeOfExpressionTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/TypeOfExpressionTests.cs
new file mode 100644
index 0000000000..847b705670
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/TypeOfExpressionTests.cs
@@ -0,0 +1,139 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
+{
+ [TestFixture]
+ public class TypeOfExpressionTests
+ {
+ [Test]
+ public void SimpleTypeOfExpressionTest()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "typeof(MyNamespace.N1.MyType)",
+ new TypeOfExpression {
+ Type = new MemberType {
+ Target = new MemberType {
+ Target = new SimpleType("MyNamespace"),
+ MemberName = "N1"
+ },
+ MemberName = "MyType"
+ }});
+ }
+
+ [Test]
+ public void GlobalTypeOfExpressionTest()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "typeof(global::System.Console)",
+ new TypeOfExpression {
+ Type = new MemberType {
+ Target = new MemberType {
+ Target = new SimpleType("global"),
+ IsDoubleColon = true,
+ MemberName = "System"
+ },
+ MemberName = "Console"
+ }});
+ }
+
+ [Test]
+ public void PrimitiveTypeOfExpressionTest()
+ {
+ TypeOfExpression toe = ParseUtilCSharp.ParseExpression("typeof(int)");
+ Assert.AreEqual("int", ((PrimitiveType)toe.Type).Keyword);
+ }
+
+ [Test]
+ public void VoidTypeOfExpressionTest()
+ {
+ TypeOfExpression toe = ParseUtilCSharp.ParseExpression("typeof(void)");
+ Assert.AreEqual("void", ((PrimitiveType)toe.Type).Keyword);
+ }
+
+ [Test]
+ public void ArrayTypeOfExpressionTest()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "typeof(MyType[])",
+ new TypeOfExpression {
+ Type = new SimpleType("MyType").MakeArrayType()
+ });
+ }
+
+ [Test]
+ public void GenericTypeOfExpressionTest()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "typeof(MyNamespace.N1.MyType)",
+ new TypeOfExpression {
+ Type = new MemberType {
+ Target = new MemberType {
+ Target = new SimpleType("MyNamespace"),
+ MemberName = "N1"
+ },
+ MemberName = "MyType",
+ TypeArguments = { new PrimitiveType("string") }
+ }});
+ }
+
+ [Test]
+ public void NestedGenericTypeOfExpressionTest()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "typeof(MyType.InnerClass.InnerInnerClass)",
+ new TypeOfExpression {
+ Type = new MemberType {
+ Target = new MemberType {
+ Target = new SimpleType("MyType") { TypeArguments = { new PrimitiveType("string") } },
+ MemberName = "InnerClass",
+ TypeArguments = { new PrimitiveType("int") }
+ },
+ MemberName = "InnerInnerClass"
+ }});
+ }
+
+ [Test]
+ public void NullableTypeOfExpressionTest()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "typeof(MyStruct?)",
+ new TypeOfExpression {
+ Type = new ComposedType {
+ BaseType = new SimpleType("MyType"),
+ HasNullableSpecifier = true
+ }});
+ }
+
+ [Test]
+ public void UnboundTypeOfExpressionTest()
+ {
+ var type = new SimpleType("MyType");
+ type.AddChild (new SimpleType (), SimpleType.Roles.TypeArgument);
+ type.AddChild (new SimpleType (), SimpleType.Roles.TypeArgument);
+ ParseUtilCSharp.AssertExpression(
+ "typeof(MyType<,>)",
+ new TypeOfExpression {
+ Type = type
+ });
+ }
+
+ [Test]
+ public void NestedArraysTest()
+ {
+ ParseUtilCSharp.AssertExpression(
+ "typeof(int[,][])",
+ new TypeOfExpression {
+ Type = new ComposedType {
+ BaseType = new PrimitiveType("int"),
+ ArraySpecifiers = {
+ new ArraySpecifier(2),
+ new ArraySpecifier(1)
+ }
+ }});
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/TypeReferenceExpressionTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/TypeReferenceExpressionTests.cs
new file mode 100644
index 0000000000..31f01ce394
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/TypeReferenceExpressionTests.cs
@@ -0,0 +1,62 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using NUnit.Framework;
+using ICSharpCode.NRefactory.PatternMatching;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
+{
+ [TestFixture]
+ public class TypeReferenceExpressionTests
+ {
+ [Test]
+ public void GlobalTypeReferenceExpression()
+ {
+ TypeReferenceExpression tr = ParseUtilCSharp.ParseExpression("global::System");
+ Assert.IsTrue (tr.IsMatch (new TypeReferenceExpression () {
+ Type = new MemberType () {
+ Target = new SimpleType ("global"),
+ IsDoubleColon = true,
+ MemberName = "System"
+ }
+ }));
+ }
+
+ [Test, Ignore ("Doesn't work")]
+ public void GlobalTypeReferenceExpressionWithoutTypeName()
+ {
+ TypeReferenceExpression tr = ParseUtilCSharp.ParseExpression("global::", true);
+ Assert.IsTrue (tr.IsMatch (new TypeReferenceExpression () {
+ Type = new MemberType () {
+ Target = new SimpleType ("global"),
+ IsDoubleColon = true,
+ }
+ }));
+ }
+
+ [Test, Ignore("Primitive types as member reference target are not supported yet")]
+ public void IntReferenceExpression()
+ {
+ MemberReferenceExpression fre = ParseUtilCSharp.ParseExpression("int.MaxValue");
+ Assert.IsTrue (fre.IsMatch (new MemberReferenceExpression () {
+ Target = new TypeReferenceExpression () {
+ Type = new PrimitiveType("int")
+ },
+ MemberName = "MaxValue"
+ }));
+ }
+
+ /* [Test]
+ public void StandaloneIntReferenceExpression()
+ {
+ // doesn't work because a = int; gives a compiler error.
+ // But how do we handle this case for code completion?
+ TypeReferenceExpression tre = ParseUtilCSharp.ParseExpression("int");
+ Assert.IsNotNull (tre.Match (new TypeReferenceExpression () {
+ Type = new SimpleType ("int")
+ }));
+ }*/
+
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/UnaryOperatorExpressionTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/UnaryOperatorExpressionTests.cs
new file mode 100644
index 0000000000..a968af1ebd
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/UnaryOperatorExpressionTests.cs
@@ -0,0 +1,95 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
+{
+ [TestFixture]
+ public class UnaryOperatorExpressionTests
+ {
+ void TestUnaryOperatorExpressionTest(string program, UnaryOperatorType op)
+ {
+ UnaryOperatorExpression uoe = ParseUtilCSharp.ParseExpression(program);
+ Assert.AreEqual(op, uoe.Operator);
+
+ Assert.IsTrue(uoe.Expression is IdentifierExpression);
+ }
+
+ [Test]
+ public void NotTest()
+ {
+ TestUnaryOperatorExpressionTest("!a", UnaryOperatorType.Not);
+ }
+
+ [Test]
+ public void BitNotTest()
+ {
+ TestUnaryOperatorExpressionTest("~a", UnaryOperatorType.BitNot);
+ }
+
+ [Test]
+ public void MinusTest()
+ {
+ TestUnaryOperatorExpressionTest("-a", UnaryOperatorType.Minus);
+ }
+
+ [Test]
+ public void PlusTest()
+ {
+ TestUnaryOperatorExpressionTest("+a", UnaryOperatorType.Plus);
+ }
+
+ [Test]
+ public void IncrementTest()
+ {
+ TestUnaryOperatorExpressionTest("++a", UnaryOperatorType.Increment);
+ }
+
+ [Test]
+ public void DecrementTest()
+ {
+ TestUnaryOperatorExpressionTest("--a", UnaryOperatorType.Decrement);
+ }
+
+ [Test]
+ public void PostIncrementTest()
+ {
+ TestUnaryOperatorExpressionTest("a++", UnaryOperatorType.PostIncrement);
+ }
+
+ [Test]
+ public void PostDecrementTest()
+ {
+ TestUnaryOperatorExpressionTest("a--", UnaryOperatorType.PostDecrement);
+ }
+
+ [Test]
+ public void StarTest()
+ {
+ TestUnaryOperatorExpressionTest("*a", UnaryOperatorType.Dereference);
+ }
+
+ [Test]
+ public void BitWiseAndTest()
+ {
+ TestUnaryOperatorExpressionTest("&a", UnaryOperatorType.AddressOf);
+ }
+
+ [Test]
+ public void DereferenceAfterCast()
+ {
+ UnaryOperatorExpression uoe = ParseUtilCSharp.ParseExpression("*((SomeType*) &w)");
+ Assert.AreEqual(UnaryOperatorType.Dereference, uoe.Operator);
+ ParenthesizedExpression pe = (ParenthesizedExpression)uoe.Expression;
+ CastExpression ce = (CastExpression)pe.Expression;
+ ComposedType type = (ComposedType)ce.Type;
+ Assert.AreEqual("SomeType", ((SimpleType)type.BaseType).Identifier);
+ Assert.AreEqual(1, type.PointerRank);
+
+ UnaryOperatorExpression adrOf = (UnaryOperatorExpression)ce.Expression;
+ Assert.AreEqual(UnaryOperatorType.AddressOf, adrOf.Operator);
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/AttributeSectionTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/AttributeSectionTests.cs
new file mode 100644
index 0000000000..15707c51b5
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/AttributeSectionTests.cs
@@ -0,0 +1,142 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using System.Linq;
+using System.Text.RegularExpressions;
+
+using ICSharpCode.NRefactory.PatternMatching;
+using ICSharpCode.NRefactory.TypeSystem;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.GeneralScope
+{
+ [TestFixture]
+ public class AttributeSectionTests
+ {
+ [Test]
+ public void GlobalAttributeCSharp()
+ {
+ string program = @"[global::Microsoft.VisualBasic.CompilerServices.DesignerGenerated()]
+[someprefix::DesignerGenerated()]
+public class Form1 {
+}";
+
+ TypeDeclaration decl = ParseUtilCSharp.ParseGlobal(program);
+ Assert.AreEqual(2, decl.Attributes.Count);
+ Assert.AreEqual("global::Microsoft.VisualBasic.CompilerServices.DesignerGenerated",
+ decl.Attributes.First().Attributes.Single().Type.ToString());
+ Assert.AreEqual("someprefix::DesignerGenerated", decl.Attributes.Last().Attributes.Single().Type.ToString());
+ }
+
+ [Test]
+ public void AssemblyAttributeCSharp()
+ {
+ string program = @"[assembly: System.Attribute()]";
+ AttributeSection decl = ParseUtilCSharp.ParseGlobal(program);
+ Assert.AreEqual(new AstLocation(1, 1), decl.StartLocation);
+ Assert.AreEqual("assembly", decl.AttributeTarget);
+ }
+
+ [Test, Ignore("assembly/module attributes are broken")]
+ public void AssemblyAttributeCSharpWithNamedArguments()
+ {
+ string program = @"[assembly: Foo(1, namedArg: 2, prop = 3)]";
+ AttributeSection decl = ParseUtilCSharp.ParseGlobal(program);
+ Assert.AreEqual("assembly", decl.AttributeTarget);
+ var a = decl.Attributes.Single();
+ Assert.AreEqual("Foo", a.Type);
+ Assert.AreEqual(3, a.Arguments.Count());
+
+ Assert.IsTrue(a.Arguments.ElementAt(0).IsMatch(new PrimitiveExpression(1)));
+ Assert.IsTrue(a.Arguments.ElementAt(1).IsMatch(new NamedArgumentExpression {
+ Identifier = "namedArg",
+ Expression = new PrimitiveExpression(2)
+ }));
+ Assert.IsTrue(a.Arguments.ElementAt(2).IsMatch(new AssignmentExpression {
+ Left = new IdentifierExpression("prop"),
+ Operator = AssignmentOperatorType.Assign,
+ Right = new PrimitiveExpression(3)
+ }));
+ }
+
+ [Test, Ignore("assembly/module attributes are broken")]
+ public void ModuleAttributeCSharp()
+ {
+ string program = @"[module: System.Attribute()]";
+ AttributeSection decl = ParseUtilCSharp.ParseGlobal(program);
+ Assert.AreEqual(new AstLocation(1, 1), decl.StartLocation);
+ Assert.AreEqual("module", decl.AttributeTarget);
+ }
+
+ [Test]
+ public void TypeAttributeCSharp()
+ {
+ string program = @"[type: System.Attribute()] class Test {}";
+ TypeDeclaration type = ParseUtilCSharp.ParseGlobal(program);
+ AttributeSection decl = type.Attributes.Single();
+ Assert.AreEqual(new AstLocation(1, 1), decl.StartLocation);
+ Assert.AreEqual("type", decl.AttributeTarget);
+ }
+
+ [Test, Ignore("Parser doesn't support attributes on type parameters")]
+ public void AttributesOnTypeParameter()
+ {
+ ParseUtilCSharp.AssertGlobal(
+ "class Test<[A,B]C> {}",
+ new TypeDeclaration {
+ ClassType = ClassType.Class,
+ Name = "Test",
+ TypeParameters = {
+ new TypeParameterDeclaration {
+ Attributes = {
+ new AttributeSection {
+ Attributes = {
+ new Attribute { Type = new SimpleType("A") },
+ new Attribute { Type = new SimpleType("B") }
+ }
+ }
+ },
+ Name = "C"
+ }
+ }});
+ }
+
+ [Test]
+ public void AttributeOnMethodParameter()
+ {
+ ParseUtilCSharp.AssertTypeMember(
+ "void M([In] int p);",
+ new MethodDeclaration {
+ ReturnType = new PrimitiveType("void"),
+ Name = "M",
+ Parameters = {
+ new ParameterDeclaration {
+ Attributes = { new AttributeSection(new Attribute { Type = new SimpleType("In") }) },
+ Type = new PrimitiveType("int"),
+ Name = "p"
+ }
+ }});
+ }
+
+ [Test]
+ public void AttributeOnSetterValue()
+ {
+ ParseUtilCSharp.AssertTypeMember(
+ "int P { get; [param: In] set; }",
+ new PropertyDeclaration {
+ ReturnType = new PrimitiveType("int"),
+ Name = "P",
+ Getter = new Accessor(),
+ Setter = new Accessor {
+ Attributes = {
+ new AttributeSection {
+ AttributeTarget = "param",
+ Attributes = { new Attribute { Type = new SimpleType("In") } },
+ } },
+ }});
+ }
+
+ // TODO: Tests for other contexts where attributes can appear
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/DelegateDeclarationTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/DelegateDeclarationTests.cs
new file mode 100644
index 0000000000..b41c5e569f
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/DelegateDeclarationTests.cs
@@ -0,0 +1,63 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using System.Linq;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.GeneralScope
+{
+ [TestFixture]
+ public class DelegateDeclarationTests
+ {
+ [Test]
+ public void SimpleCSharpDelegateDeclarationTest()
+ {
+ ParseUtilCSharp.AssertGlobal(
+ "public delegate void MyDelegate(int a, int secondParam, MyObj lastParam);",
+ new DelegateDeclaration {
+ Modifiers = Modifiers.Public,
+ ReturnType = new PrimitiveType("void"),
+ Name = "MyDelegate",
+ Parameters = {
+ new ParameterDeclaration(new PrimitiveType("int"), "a"),
+ new ParameterDeclaration(new PrimitiveType("int"), "secondParam"),
+ new ParameterDeclaration(new SimpleType("MyObj"), "lastParam")
+ }});
+ }
+
+ [Test]
+ public void GenericDelegateDeclarationTest()
+ {
+ ParseUtilCSharp.AssertGlobal(
+ "public delegate T CreateObject() where T : ICloneable;",
+ new DelegateDeclaration {
+ Modifiers = Modifiers.Public,
+ ReturnType = new SimpleType("T"),
+ Name = "CreateObject",
+ TypeParameters = { new TypeParameterDeclaration { Name = "T" } },
+ Constraints = {
+ new Constraint {
+ TypeParameter = "T",
+ BaseTypes = { new SimpleType("ICloneable") }
+ }
+ }});
+ }
+
+ [Test]
+ public void DelegateDeclarationInNamespace()
+ {
+ string program = "namespace N { delegate void MyDelegate(); }";
+ NamespaceDeclaration nd = ParseUtilCSharp.ParseGlobal(program);
+ Assert.AreEqual("MyDelegate", ((DelegateDeclaration)nd.Members.Single()).Name);
+ }
+
+ [Test]
+ public void DelegateDeclarationInClass()
+ {
+ string program = "class Outer { delegate void Inner(); }";
+ TypeDeclaration td = ParseUtilCSharp.ParseGlobal(program);
+ Assert.AreEqual("Inner", ((DelegateDeclaration)td.Members.Single()).Name);
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/NamespaceDeclarationTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/NamespaceDeclarationTests.cs
new file mode 100644
index 0000000000..bec5732709
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/NamespaceDeclarationTests.cs
@@ -0,0 +1,36 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using System.Linq;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.GeneralScope
+{
+ [TestFixture]
+ public class NamespaceDeclarationTests
+ {
+ [Test]
+ public void SimpleNamespaceTest()
+ {
+ string program = "namespace TestNamespace {\n" +
+ "}\n";
+ NamespaceDeclaration ns = ParseUtilCSharp.ParseGlobal(program);
+ Assert.AreEqual("TestNamespace", ns.Name);
+ }
+
+ [Test]
+ public void NestedNamespaceTest()
+ {
+ string program = "namespace N1 {//TestNamespace\n" +
+ " namespace N2 {// Declares a namespace named N2 within N1.\n" +
+ " }\n" +
+ "}\n";
+ NamespaceDeclaration ns = ParseUtilCSharp.ParseGlobal(program);
+
+ Assert.AreEqual("N1", ns.Name);
+
+ Assert.AreEqual("N2", ns.Children.OfType().Single().Name);
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/TypeDeclarationTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/TypeDeclarationTests.cs
new file mode 100644
index 0000000000..2c123a5dd6
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/TypeDeclarationTests.cs
@@ -0,0 +1,292 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using System.Linq;
+using ICSharpCode.NRefactory.TypeSystem;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.GeneralScope
+{
+ [TestFixture]
+ public class TypeDeclarationTests
+ {
+ [Test]
+ public void SimpleClassTypeDeclarationTest()
+ {
+ TypeDeclaration td = ParseUtilCSharp.ParseGlobal("class MyClass : My.Base.Class { }");
+
+ Assert.AreEqual(ClassType.Class, td.ClassType);
+ Assert.AreEqual("MyClass", td.Name);
+ Assert.AreEqual("My.Base.Class", td.BaseTypes.First ().ToString ());
+ Assert.AreEqual(Modifiers.None, td.Modifiers);
+ }
+
+ [Test]
+ public void SimpleClassRegionTest()
+ {
+ const string program = "class MyClass\n{\n}\n";
+ TypeDeclaration td = ParseUtilCSharp.ParseGlobal(program);
+ Assert.AreEqual(1, td.StartLocation.Line, "StartLocation.Y");
+ Assert.AreEqual(1, td.StartLocation.Column, "StartLocation.X");
+ AstLocation bodyStartLocation = td.GetChildByRole(AstNode.Roles.LBrace).PrevSibling.EndLocation;
+ Assert.AreEqual(1, bodyStartLocation.Line, "BodyStartLocation.Y");
+ Assert.AreEqual(14, bodyStartLocation.Column, "BodyStartLocation.X");
+ Assert.AreEqual(3, td.EndLocation.Line, "EndLocation.Y");
+ Assert.AreEqual(2, td.EndLocation.Column, "EndLocation.Y");
+ }
+
+ [Test]
+ public void SimplePartialClassTypeDeclarationTest()
+ {
+ TypeDeclaration td = ParseUtilCSharp.ParseGlobal("partial class MyClass { }");
+ Assert.IsFalse(td.IsNull);
+ Assert.AreEqual(ClassType.Class, td.ClassType);
+ Assert.AreEqual("MyClass", td.Name);
+ Assert.AreEqual(Modifiers.Partial, td.Modifiers);
+ }
+
+ [Test]
+ public void NestedClassesTest()
+ {
+ TypeDeclaration td = ParseUtilCSharp.ParseGlobal("class MyClass { partial class P1 {} public partial class P2 {} static class P3 {} internal static class P4 {} }");
+ Assert.IsFalse(td.IsNull);
+ Assert.AreEqual(ClassType.Class, td.ClassType);
+ Assert.AreEqual("MyClass", td.Name);
+ Assert.AreEqual(Modifiers.Partial, ((TypeDeclaration)td.Members.ElementAt(0)).Modifiers);
+ Assert.AreEqual(Modifiers.Partial | Modifiers.Public, ((TypeDeclaration)td.Members.ElementAt(1)).Modifiers);
+ Assert.AreEqual(Modifiers.Static, ((TypeDeclaration)td.Members.ElementAt(2)).Modifiers);
+ Assert.AreEqual(Modifiers.Static | Modifiers.Internal, ((TypeDeclaration)td.Members.ElementAt(3)).Modifiers);
+ }
+
+ [Test]
+ public void SimpleStaticClassTypeDeclarationTest()
+ {
+ TypeDeclaration td = ParseUtilCSharp.ParseGlobal("static class MyClass { }");
+ Assert.IsFalse(td.IsNull);
+ Assert.AreEqual(ClassType.Class, td.ClassType);
+ Assert.AreEqual("MyClass", td.Name);
+ Assert.AreEqual(Modifiers.Static, td.Modifiers);
+ }
+
+ [Test]
+ public void GenericClassTypeDeclarationTest()
+ {
+ ParseUtilCSharp.AssertGlobal(
+ "public class G {}",
+ new TypeDeclaration {
+ Modifiers = Modifiers.Public,
+ ClassType = ClassType.Class,
+ Name = "G",
+ TypeParameters = { new TypeParameterDeclaration { Name = "T" } }
+ });
+ }
+
+ [Test]
+ public void GenericClassWithWhere()
+ {
+ ParseUtilCSharp.AssertGlobal(
+ @"public class Test where T : IMyInterface { }",
+ new TypeDeclaration {
+ Modifiers = Modifiers.Public,
+ ClassType = ClassType.Class,
+ Name = "Test",
+ TypeParameters = { new TypeParameterDeclaration { Name = "T" } },
+ Constraints = {
+ new Constraint {
+ TypeParameter = "T",
+ BaseTypes = { new SimpleType("IMyInterface") }
+ }
+ }});
+ }
+
+ [Test, Ignore ("Mono parser bug.")]
+ public void ComplexGenericClassTypeDeclarationTest()
+ {
+ ParseUtilCSharp.AssertGlobal(
+ "public class Generic : System.IComparable where S : G, new() where T : MyNamespace.IMyInterface",
+ new TypeDeclaration {
+ Modifiers = Modifiers.Public,
+ ClassType = ClassType.Class,
+ Name = "Generic",
+ TypeParameters = {
+ new TypeParameterDeclaration { Variance = VarianceModifier.Contravariant, Name = "T" },
+ new TypeParameterDeclaration { Variance = VarianceModifier.Covariant, Name = "S" }
+ },
+ BaseTypes = {
+ new MemberType {
+ Target = new SimpleType("System"),
+ MemberName = "IComparable"
+ }
+ },
+ Constraints = {
+ new Constraint {
+ TypeParameter = "S",
+ BaseTypes = {
+ new SimpleType {
+ Identifier = "G",
+ TypeArguments = { new SimpleType("T").MakeArrayType() }
+ },
+ new PrimitiveType("new")
+ }
+ },
+ new Constraint {
+ TypeParameter = "T",
+ BaseTypes = {
+ new MemberType {
+ Target = new SimpleType("MyNamespace"),
+ MemberName = "IMyInterface"
+ }
+ }
+ }
+ }
+ });
+ }
+
+ [Test]
+ public void ComplexClassTypeDeclarationTest()
+ {
+ ParseUtilCSharp.AssertGlobal(
+ @"
+[MyAttr()]
+public abstract class MyClass : MyBase, Interface1, My.Test.Interface2
+{
+}",
+ new TypeDeclaration {
+ Attributes = {
+ new AttributeSection {
+ Attributes = {
+ new Attribute { Type = new SimpleType("MyAttr") }
+ }
+ }
+ },
+ Modifiers = Modifiers.Public | Modifiers.Abstract,
+ ClassType = ClassType.Class,
+ Name = "MyClass",
+ BaseTypes = {
+ new SimpleType("MyBase"),
+ new SimpleType("Interface1"),
+ new MemberType {
+ Target = new MemberType {
+ Target = new SimpleType("My"),
+ MemberName = "Test"
+ },
+ MemberName = "Interface2"
+ }
+ }});
+ }
+
+ [Test]
+ public void SimpleStructTypeDeclarationTest()
+ {
+ TypeDeclaration td = ParseUtilCSharp.ParseGlobal("struct MyStruct {}");
+
+ Assert.AreEqual(ClassType.Struct, td.ClassType);
+ Assert.AreEqual("MyStruct", td.Name);
+ }
+
+ [Test]
+ public void SimpleInterfaceTypeDeclarationTest()
+ {
+ TypeDeclaration td = ParseUtilCSharp.ParseGlobal("interface MyInterface {}");
+
+ Assert.AreEqual(ClassType.Interface, td.ClassType);
+ Assert.AreEqual("MyInterface", td.Name);
+ }
+
+ [Test]
+ public void SimpleEnumTypeDeclarationTest()
+ {
+ TypeDeclaration td = ParseUtilCSharp.ParseGlobal("enum MyEnum {}");
+
+ Assert.AreEqual(ClassType.Enum, td.ClassType);
+ Assert.AreEqual("MyEnum", td.Name);
+ }
+
+ [Test, Ignore("Mono parser bug?")]
+ public void ContextSensitiveKeywordTest()
+ {
+ ParseUtilCSharp.AssertGlobal(
+ "partial class partial<[partial: where] where> where where : partial { }",
+ new TypeDeclaration {
+ Modifiers = Modifiers.Partial,
+ ClassType = ClassType.Class,
+ Name = "partial",
+ TypeParameters = {
+ new TypeParameterDeclaration {
+ Attributes = {
+ new AttributeSection {
+ AttributeTarget = "partial",
+ Attributes = { new Attribute { Type = new SimpleType("where") } }
+ }
+ },
+ Name = "where"
+ }
+ },
+ Constraints = {
+ new Constraint {
+ TypeParameter = "where",
+ BaseTypes = {
+ new SimpleType {
+ Identifier = "partial",
+ TypeArguments = { new SimpleType("where") }
+ }
+ }
+ }
+ }});
+ }
+
+ [Test]
+ public void TypeInNamespaceTest()
+ {
+ NamespaceDeclaration ns = ParseUtilCSharp.ParseGlobal("namespace N { class MyClass { } }");
+
+ Assert.AreEqual("N", ns.Name);
+ Assert.AreEqual("MyClass", ((TypeDeclaration)ns.Members.Single()).Name);
+ }
+
+ [Test]
+ public void StructInNamespaceTest()
+ {
+ NamespaceDeclaration ns = ParseUtilCSharp.ParseGlobal("namespace N { struct MyClass { } }");
+
+ Assert.AreEqual("N", ns.Name);
+ Assert.AreEqual("MyClass", ((TypeDeclaration)ns.Members.Single()).Name);
+ }
+
+ [Test]
+ public void EnumInNamespaceTest()
+ {
+ NamespaceDeclaration ns = ParseUtilCSharp.ParseGlobal("namespace N { enum MyClass { } }");
+
+ Assert.AreEqual("N", ns.Name);
+ Assert.AreEqual("MyClass", ((TypeDeclaration)ns.Members.Single()).Name);
+ }
+
+ [Test]
+ public void InterfaceInNamespaceTest()
+ {
+ NamespaceDeclaration ns = ParseUtilCSharp.ParseGlobal("namespace N { interface MyClass { } }");
+
+ Assert.AreEqual("N", ns.Name);
+ Assert.AreEqual("MyClass", ((TypeDeclaration)ns.Members.Single()).Name);
+ }
+
+ [Test]
+ public void EnumWithInitializer()
+ {
+ TypeDeclaration td = ParseUtilCSharp.ParseGlobal("enum MyEnum { Val1 = 10 }");
+ EnumMemberDeclaration member = (EnumMemberDeclaration)td.Members.Single();
+ Assert.AreEqual("Val1", member.Name);
+ Assert.AreEqual(10, ((PrimitiveExpression)member.Initializer).Value);
+ }
+
+ [Test]
+ public void EnumWithBaseType()
+ {
+ TypeDeclaration td = ParseUtilCSharp.ParseGlobal("enum MyEnum : short { }");
+ Assert.AreEqual("MyEnum", td.Name);
+ Assert.AreEqual("short", ((PrimitiveType)td.BaseTypes.Single()).Keyword);
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/UsingDeclarationTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/UsingDeclarationTests.cs
new file mode 100644
index 0000000000..e5a82c3ea1
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/UsingDeclarationTests.cs
@@ -0,0 +1,101 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using System.IO;
+using System.Linq;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.GeneralScope
+{
+ [TestFixture]
+ public class UsingDeclarationTests
+ {
+ [Test]
+ public void WrongUsingTest()
+ {
+ string program = "using\n";
+ CSharpParser parser = new CSharpParser();
+ CompilationUnit cu = parser.Parse(new StringReader(program));
+ Assert.AreEqual(0, cu.Children.Count());
+ Assert.IsTrue(parser.HasErrors);
+ }
+
+ [Test]
+ public void DeclarationTest()
+ {
+ string program = "using System;\n" +
+ "using My.Name.Space;\n";
+ CSharpParser parser = new CSharpParser();
+ CompilationUnit cu = parser.Parse(new StringReader(program));
+ Assert.IsFalse(parser.HasErrors);
+
+ Assert.AreEqual(2, cu.Children.Count());
+ Assert.IsTrue(cu.Children.ElementAt(0) is UsingDeclaration);
+ Assert.IsFalse(cu.Children.ElementAt(0) is UsingAliasDeclaration);
+ UsingDeclaration ud = (UsingDeclaration)cu.Children.ElementAt(0);
+ Assert.AreEqual("System", ud.Namespace);
+
+ Assert.IsTrue(cu.Children.ElementAt(1) is UsingDeclaration);
+ Assert.IsFalse(cu.Children.ElementAt(1) is UsingAliasDeclaration);
+ ud = (UsingDeclaration)cu.Children.ElementAt(1);
+ Assert.AreEqual("My.Name.Space", ud.Namespace);
+ }
+
+ [Test]
+ public void UsingAliasDeclarationTest()
+ {
+ string program = "using TESTME=System;\n" +
+ "using myAlias=My.Name.Space;\n" +
+ "using StringCollection = System.Collections.Generic.List;\n";
+ CSharpParser parser = new CSharpParser();
+ CompilationUnit cu = parser.Parse(new StringReader(program));
+ Assert.IsFalse(parser.HasErrors);
+
+ Assert.AreEqual(3, cu.Children.Count());
+
+ Assert.IsTrue(cu.Children.ElementAt(0) is UsingAliasDeclaration);
+ UsingAliasDeclaration ud = (UsingAliasDeclaration)cu.Children.ElementAt(0);
+ Assert.AreEqual("TESTME", ud.Alias);
+ Assert.AreEqual("System", ud.Import.ToString());
+
+ Assert.IsTrue(cu.Children.ElementAt(1) is UsingAliasDeclaration);
+ ud = (UsingAliasDeclaration)cu.Children.ElementAt(1);
+ Assert.AreEqual("myAlias", ud.Alias);
+ Assert.AreEqual("My.Name.Space", ud.Import.ToString());
+
+ Assert.IsTrue(cu.Children.ElementAt(2) is UsingAliasDeclaration);
+ ud = (UsingAliasDeclaration)cu.Children.ElementAt(2);
+ Assert.AreEqual("StringCollection", ud.Alias);
+ Assert.AreEqual("System.Collections.Generic.List", ud.Import.ToString());
+ }
+
+ [Test]
+ public void UsingWithAliasing()
+ {
+ string program = "using global::System;\n" +
+ "using myAlias=global::My.Name.Space;\n" +
+ "using a::b.c;\n";
+ CSharpParser parser = new CSharpParser();
+ CompilationUnit cu = parser.Parse(new StringReader(program));
+ Assert.IsFalse(parser.HasErrors);
+
+ Assert.AreEqual(3, cu.Children.Count());
+
+ Assert.IsTrue(cu.Children.ElementAt(0) is UsingDeclaration);
+ Assert.IsFalse(cu.Children.ElementAt(0) is UsingAliasDeclaration);
+ UsingDeclaration ud = (UsingDeclaration)cu.Children.ElementAt(0);
+ Assert.AreEqual("global::System", ud.Namespace);
+
+ Assert.IsTrue(cu.Children.ElementAt(1) is UsingAliasDeclaration);
+ UsingAliasDeclaration uad = (UsingAliasDeclaration)cu.Children.ElementAt(1);
+ Assert.AreEqual("myAlias", uad.Alias);
+ Assert.AreEqual("global::My.Name.Space", uad.Import.ToString());
+
+ Assert.IsTrue(cu.Children.ElementAt(2) is UsingDeclaration);
+ Assert.IsFalse(cu.Children.ElementAt(2) is UsingAliasDeclaration);
+ ud = (UsingDeclaration)cu.Children.ElementAt(2);
+ Assert.AreEqual("a::b.c", ud.Namespace);
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/ParseUtil.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/ParseUtil.cs
new file mode 100644
index 0000000000..cef1f56529
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/ParseUtil.cs
@@ -0,0 +1,109 @@
+// Copyright (c) 2010 AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using System.IO;
+using System.Linq;
+
+using ICSharpCode.NRefactory.PatternMatching;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser
+{
+ ///
+ /// Helper methods for parser unit tests.
+ ///
+ public static class ParseUtilCSharp
+ {
+ public static T ParseGlobal(string code, bool expectErrors = false) where T : AstNode
+ {
+ CSharpParser parser = new CSharpParser();
+ CompilationUnit cu = parser.Parse(new StringReader(code));
+
+ Assert.AreEqual(expectErrors, parser.HasErrors, "HasErrors");
+
+ AstNode node = cu.Children.Single();
+ Type type = typeof(T);
+ Assert.IsTrue(type.IsAssignableFrom(node.GetType()), String.Format("Parsed node was {0} instead of {1} ({2})", node.GetType(), type, node));
+ return (T)node;
+ }
+
+ public static void AssertGlobal(string code, AstNode expectedNode)
+ {
+ var node = ParseGlobal(code);
+ if (!expectedNode.IsMatch(node)) {
+ Assert.Fail("Expected '{0}' but was '{1}'", ToCSharp(expectedNode), ToCSharp(node));
+ }
+ }
+
+ public static T ParseStatement(string stmt, bool expectErrors = false) where T : AstNode
+ {
+ CSharpParser parser = new CSharpParser();
+ var statements = parser.ParseStatements(new StringReader(stmt));
+
+ Assert.AreEqual(expectErrors, parser.HasErrors, "HasErrors");
+
+ AstNode statement = statements.Single();
+ Type type = typeof(T);
+ Assert.IsTrue(type.IsAssignableFrom(statement.GetType()), String.Format("Parsed statement was {0} instead of {1} ({2})", statement.GetType(), type, statement));
+ return (T)statement;
+ }
+
+ public static void AssertStatement(string code, CSharp.Statement expectedStmt)
+ {
+ var stmt = ParseStatement(code);
+ if (!expectedStmt.IsMatch(stmt)) {
+ Assert.Fail("Expected '{0}' but was '{1}'", ToCSharp(expectedStmt), ToCSharp(stmt));
+ }
+ }
+
+ public static T ParseExpression(string expr, bool expectErrors = false) where T : AstNode
+ {
+ CSharpParser parser = new CSharpParser();
+ AstNode parsedExpression = parser.ParseExpression(new StringReader(expr));
+
+ Assert.AreEqual(expectErrors, parser.HasErrors, "HasErrors");
+ if (expectErrors && parsedExpression == null)
+ return default (T);
+ Type type = typeof(T);
+ Assert.IsTrue(type.IsAssignableFrom(parsedExpression.GetType()), String.Format("Parsed expression was {0} instead of {1} ({2})", parsedExpression.GetType(), type, parsedExpression));
+ return (T)parsedExpression;
+ }
+
+ public static void AssertExpression(string code, CSharp.Expression expectedExpr)
+ {
+ var expr = ParseExpression(code);
+ if (!expectedExpr.IsMatch(expr)) {
+ Assert.Fail("Expected '{0}' but was '{1}'", ToCSharp(expectedExpr), ToCSharp(expr));
+ }
+ }
+
+ public static T ParseTypeMember(string expr, bool expectErrors = false) where T : AttributedNode
+ {
+ CSharpParser parser = new CSharpParser();
+ var members = parser.ParseTypeMembers(new StringReader(expr));
+
+ Assert.AreEqual(expectErrors, parser.HasErrors, "HasErrors");
+
+ AttributedNode m = members.Single();
+ Type type = typeof(T);
+ Assert.IsTrue(type.IsAssignableFrom(m.GetType()), String.Format("Parsed member was {0} instead of {1} ({2})", m.GetType(), type, m));
+ return (T)m;
+ }
+
+ public static void AssertTypeMember(string code, CSharp.AttributedNode expectedMember)
+ {
+ var member = ParseTypeMember(code);
+ if (!expectedMember.IsMatch(member)) {
+ Assert.Fail("Expected '{0}' but was '{1}'", ToCSharp(expectedMember), ToCSharp(member));
+ }
+ }
+
+ static string ToCSharp(AstNode node)
+ {
+ StringWriter w = new StringWriter();
+ node.AcceptVisitor(new OutputVisitor(w, new CSharpFormattingOptions()), null);
+ return w.ToString();
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/BlockStatementTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/BlockStatementTests.cs
new file mode 100644
index 0000000000..2aaa2c57bf
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/BlockStatementTests.cs
@@ -0,0 +1,42 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using System.Linq;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.Statements
+{
+ [TestFixture]
+ public class BlockStatementTests
+ {
+ [Test]
+ public void BlockStatementTest()
+ {
+ BlockStatement blockStmt = ParseUtilCSharp.ParseStatement("{}");
+ Assert.AreEqual(0, blockStmt.Statements.Count());
+ }
+
+ [Test]
+ public void ComplexBlockStatementPositionTest()
+ {
+ string code = @"{
+ WebClient wc = new WebClient();
+ wc.Test();
+ wc.UploadStringCompleted += delegate {
+ output.BeginInvoke((MethodInvoker)delegate {
+ output.Text += newText;
+ });
+ };
+}";
+ BlockStatement blockStmt = ParseUtilCSharp.ParseStatement(code);
+// start column gets moved by ParseStatement
+// Assert.AreEqual(1, blockStmt.StartLocation.Column);
+ Assert.AreEqual(1, blockStmt.StartLocation.Line);
+ Assert.AreEqual(2, blockStmt.EndLocation.Column);
+ Assert.AreEqual(9, blockStmt.EndLocation.Line);
+
+ Assert.AreEqual(3, blockStmt.Statements.Count());
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/CheckedStatementTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/CheckedStatementTests.cs
new file mode 100644
index 0000000000..15628db47e
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/CheckedStatementTests.cs
@@ -0,0 +1,45 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using System.Linq;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.Statements
+{
+ [TestFixture]
+ public class CheckedStatementTests
+ {
+ [Test]
+ public void CheckedStatementTest()
+ {
+ CheckedStatement checkedStatement = ParseUtilCSharp.ParseStatement("checked { }");
+ Assert.IsFalse(checkedStatement.Body.IsNull);
+ }
+
+ [Test]
+ public void CheckedStatementAndExpressionTest()
+ {
+ CheckedStatement checkedStatement = ParseUtilCSharp.ParseStatement("checked { checked(++i).ToString(); }");
+ ExpressionStatement es = (ExpressionStatement)checkedStatement.Body.Statements.Single();
+ CheckedExpression ce = (CheckedExpression)((MemberReferenceExpression)((InvocationExpression)es.Expression).Target).Target;
+ Assert.IsTrue(ce.Expression is UnaryOperatorExpression);
+ }
+
+ [Test]
+ public void UncheckedStatementTest()
+ {
+ UncheckedStatement uncheckedStatement = ParseUtilCSharp.ParseStatement("unchecked { }");
+ Assert.IsFalse(uncheckedStatement.Body.IsNull);
+ }
+
+ [Test]
+ public void UncheckedStatementAndExpressionTest()
+ {
+ UncheckedStatement uncheckedStatement = ParseUtilCSharp.ParseStatement("unchecked { unchecked(++i).ToString(); }");
+ ExpressionStatement es = (ExpressionStatement)uncheckedStatement.Body.Statements.Single();
+ UncheckedExpression ce = (UncheckedExpression)((MemberReferenceExpression)((InvocationExpression)es.Expression).Target).Target;
+ Assert.IsTrue(ce.Expression is UnaryOperatorExpression);
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/EmptyStatementTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/EmptyStatementTests.cs
new file mode 100644
index 0000000000..b492b21edd
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/EmptyStatementTests.cs
@@ -0,0 +1,18 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.Statements
+{
+ [TestFixture]
+ public class EmptyStatementTests
+ {
+ [Test]
+ public void EmptyStatementTest()
+ {
+ EmptyStatement emptyStmt = ParseUtilCSharp.ParseStatement(";");
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/ExpressionStatementTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/ExpressionStatementTests.cs
new file mode 100644
index 0000000000..9489deffc0
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/ExpressionStatementTests.cs
@@ -0,0 +1,26 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.Statements
+{
+ [TestFixture]
+ public class ExpressionStatementTests
+ {
+ [Test]
+ public void StatementExpressionTest()
+ {
+ ExpressionStatement stmtExprStmt = ParseUtilCSharp.ParseStatement("a = my.Obj.PropCall;");
+ Assert.IsTrue(stmtExprStmt.Expression is AssignmentExpression);
+ }
+
+ [Test]
+ public void StatementExpressionTest1()
+ {
+ ExpressionStatement stmtExprStmt = ParseUtilCSharp.ParseStatement("yield.yield();");
+ Assert.IsTrue(stmtExprStmt.Expression is InvocationExpression);
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/FixedStatementTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/FixedStatementTests.cs
new file mode 100644
index 0000000000..374bf760b5
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/FixedStatementTests.cs
@@ -0,0 +1,52 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.Statements
+{
+ [TestFixture]
+ public class FixedStatementTests
+ {
+ [Test]
+ public void FixedStatementTest()
+ {
+ ParseUtilCSharp.AssertStatement(
+ "fixed (int* ptr = myIntArr) { }",
+ new FixedStatement {
+ Type = new PrimitiveType("int").MakePointerType(),
+ Variables = {
+ new VariableInitializer {
+ Name = "ptr",
+ Initializer = new IdentifierExpression("myIntArr")
+ }
+ },
+ EmbeddedStatement = new BlockStatement()
+ });
+ }
+
+ [Test]
+ public void FixedStatementWithMultipleVariables()
+ {
+ ParseUtilCSharp.AssertStatement(
+ "fixed (int* ptr1 = &myIntArr[1], ptr2 = myIntArr) { }",
+ new FixedStatement {
+ Type = new PrimitiveType("int").MakePointerType(),
+ Variables = {
+ new VariableInitializer {
+ Name = "ptr1",
+ Initializer = new UnaryOperatorExpression(
+ UnaryOperatorType.AddressOf,
+ new IndexerExpression { Target = new IdentifierExpression("myIntArr"), Arguments = { new PrimitiveExpression(1) } })
+ },
+ new VariableInitializer {
+ Name = "ptr2",
+ Initializer = new IdentifierExpression("myIntArr")
+ }
+ },
+ EmbeddedStatement = new BlockStatement()
+ });
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/ForStatementTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/ForStatementTests.cs
new file mode 100644
index 0000000000..44232de5a0
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/ForStatementTests.cs
@@ -0,0 +1,67 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using System.Linq;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.Statements
+{
+ [TestFixture]
+ public class ForStatementTests
+ {
+ [Test]
+ public void ForeachStatementTest()
+ {
+ ParseUtilCSharp.AssertStatement(
+ "foreach (int i in myColl) {} ",
+ new ForeachStatement {
+ VariableType = new PrimitiveType("int"),
+ VariableName = "i",
+ InExpression = new IdentifierExpression("myColl"),
+ EmbeddedStatement = new BlockStatement()
+ });
+ }
+
+ [Test]
+ public void EmptyForStatementTest()
+ {
+ ForStatement forStmt = ParseUtilCSharp.ParseStatement("for (;;) ;");
+ Assert.AreEqual(0, forStmt.Initializers.Count());
+ Assert.AreEqual(0, forStmt.Iterators.Count());
+ Assert.IsTrue(forStmt.Condition.IsNull);
+ Assert.IsTrue(forStmt.EmbeddedStatement is EmptyStatement);
+ }
+
+ [Test]
+ public void ForStatementTest()
+ {
+ ForStatement forStmt = ParseUtilCSharp.ParseStatement("for (int i = 5; i < 6; ++i) {} ");
+ var init = (VariableDeclarationStatement)forStmt.Initializers.Single();
+ Assert.AreEqual("i", init.Variables.Single().Name);
+
+ Assert.IsTrue(forStmt.Condition is BinaryOperatorExpression);
+
+ var inc = (ExpressionStatement)forStmt.Iterators.Single();
+ Assert.IsTrue(inc.Expression is UnaryOperatorExpression);
+ }
+
+ [Test]
+ public void ForStatementTestMultipleInitializers()
+ {
+ ForStatement forStmt = ParseUtilCSharp.ParseStatement("for (i = 0, j = 1; i < 6; ++i) {} ");
+ Assert.AreEqual(2, forStmt.Initializers.Count());
+ Assert.IsTrue(forStmt.Iterators.All(i => i is ExpressionStatement));
+ }
+
+ [Test]
+ public void ForStatementTestMultipleIterators()
+ {
+ ForStatement forStmt = ParseUtilCSharp.ParseStatement("for (int i = 5, j = 10; i < 6; ++i, j--) {} ");
+ Assert.AreEqual(1, forStmt.Initializers.Count());
+ Assert.AreEqual(2, ((VariableDeclarationStatement)forStmt.Initializers.Single()).Variables.Count());
+ Assert.AreEqual(2, forStmt.Iterators.Count());
+ Assert.IsTrue(forStmt.Iterators.All(i => i is ExpressionStatement));
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/GotoStatementTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/GotoStatementTests.cs
new file mode 100644
index 0000000000..f5a882b0b4
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/GotoStatementTests.cs
@@ -0,0 +1,45 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+
+using System;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.Statements
+{
+ [TestFixture]
+ public class GotoStatementTests
+ {
+ [Test]
+ public void GotoStatementTest()
+ {
+ var gotoStmt = ParseUtilCSharp.ParseStatement("goto myLabel;");
+ Assert.AreEqual("myLabel", gotoStmt.Label);
+ }
+
+ [Test]
+ public void GotoDefaultStatementTest()
+ {
+ var gotoCaseStmt = ParseUtilCSharp.ParseStatement("goto default;");
+ }
+
+ [Test]
+ public void GotoCaseStatementTest()
+ {
+ var gotoCaseStmt = ParseUtilCSharp.ParseStatement("goto case 6;");
+ Assert.IsTrue(gotoCaseStmt.LabelExpression is PrimitiveExpression);
+ }
+
+ [Test]
+ public void BreakStatementTest()
+ {
+ BreakStatement breakStmt = ParseUtilCSharp.ParseStatement("break;");
+ }
+
+ [Test]
+ public void ContinueStatementTest()
+ {
+ ContinueStatement continueStmt = ParseUtilCSharp.ParseStatement("continue;");
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/IfElseStatementTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/IfElseStatementTests.cs
new file mode 100644
index 0000000000..e0daaba5f3
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/IfElseStatementTests.cs
@@ -0,0 +1,39 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.Statements
+{
+ [TestFixture]
+ public class IfElseStatementTests
+ {
+ [Test]
+ public void SimpleIfStatementTest()
+ {
+ IfElseStatement ifElseStatement = ParseUtilCSharp.ParseStatement("if (true) { }");
+ Assert.IsTrue(ifElseStatement.Condition is PrimitiveExpression);
+ Assert.IsTrue(ifElseStatement.TrueStatement is BlockStatement);
+ Assert.IsTrue(ifElseStatement.FalseStatement.IsNull);
+ }
+
+ [Test]
+ public void SimpleIfElseStatementTest()
+ {
+ IfElseStatement ifElseStatement = ParseUtilCSharp.ParseStatement("if (true) { } else { }");
+ Assert.IsTrue(ifElseStatement.Condition is PrimitiveExpression);
+ Assert.IsTrue(ifElseStatement.TrueStatement is BlockStatement);
+ Assert.IsTrue(ifElseStatement.FalseStatement is BlockStatement);
+ }
+
+ [Test]
+ public void IfElseIfStatementTest()
+ {
+ IfElseStatement ifElseStatement = ParseUtilCSharp.ParseStatement("if (1) { } else if (2) { } else if (3) { } else { }");
+ Assert.IsTrue(ifElseStatement.Condition is PrimitiveExpression);
+ Assert.IsTrue(ifElseStatement.TrueStatement is BlockStatement);
+ Assert.IsTrue(ifElseStatement.FalseStatement is IfElseStatement);
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/LabelStatementTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/LabelStatementTests.cs
new file mode 100644
index 0000000000..3ce3339fdf
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/LabelStatementTests.cs
@@ -0,0 +1,29 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using System.Linq;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.Statements
+{
+ [TestFixture]
+ public class LabelStatementTests
+ {
+ [Test]
+ public void LabelStatementTest()
+ {
+ BlockStatement block = ParseUtilCSharp.ParseStatement("{ myLabel: ; }");
+ LabelStatement labelStmt = (LabelStatement)block.Statements.First();
+ Assert.AreEqual("myLabel", labelStmt.Label);
+ }
+
+ [Test]
+ public void Label2StatementTest()
+ {
+ BlockStatement block = ParseUtilCSharp.ParseStatement("{ yield: ; }");
+ LabelStatement labelStmt = (LabelStatement)block.Statements.First();
+ Assert.AreEqual("yield", labelStmt.Label);
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/LockStatementTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/LockStatementTests.cs
new file mode 100644
index 0000000000..a85dc06c97
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/LockStatementTests.cs
@@ -0,0 +1,19 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.Statements
+{
+ [TestFixture]
+ public class LockStatementTests
+ {
+ [Test]
+ public void LockStatementTest()
+ {
+ LockStatement lockStmt = ParseUtilCSharp.ParseStatement("lock (myObj) {}");
+ // TODO : Extend test.
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/ReturnStatementTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/ReturnStatementTests.cs
new file mode 100644
index 0000000000..3747198eea
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/ReturnStatementTests.cs
@@ -0,0 +1,33 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.Statements
+{
+ [TestFixture]
+ public class ReturnStatementTests
+ {
+ [Test]
+ public void EmptyReturnStatementTest()
+ {
+ ReturnStatement returnStatement = ParseUtilCSharp.ParseStatement("return;");
+ Assert.IsTrue(returnStatement.Expression.IsNull);
+ }
+
+ [Test]
+ public void ReturnStatementTest()
+ {
+ ReturnStatement returnStatement = ParseUtilCSharp.ParseStatement("return 5;");
+ Assert.IsTrue(returnStatement.Expression is PrimitiveExpression);
+ }
+
+ [Test]
+ public void ReturnStatementTest1()
+ {
+ ReturnStatement returnStatement = ParseUtilCSharp.ParseStatement("return yield;");
+ Assert.IsTrue(returnStatement.Expression is IdentifierExpression);
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/SwitchStatementTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/SwitchStatementTests.cs
new file mode 100644
index 0000000000..0800ffb613
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/SwitchStatementTests.cs
@@ -0,0 +1,20 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.Statements
+{
+ [TestFixture]
+ public class SwitchStatementTests
+ {
+ [Test]
+ public void SwitchStatementTest()
+ {
+ SwitchStatement switchStmt = ParseUtilCSharp.ParseStatement("switch (a) { case 4: case 5: break; case 6: break; default: break; }");
+ Assert.AreEqual("a", ((IdentifierExpression)switchStmt.Expression).Identifier);
+ // TODO: Extend test
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/ThrowStatementTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/ThrowStatementTests.cs
new file mode 100644
index 0000000000..4ec682f00b
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/ThrowStatementTests.cs
@@ -0,0 +1,26 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.Statements
+{
+ [TestFixture]
+ public class ThrowStatementTests
+ {
+ [Test]
+ public void EmptyThrowStatementTest()
+ {
+ ThrowStatement throwStmt = ParseUtilCSharp.ParseStatement("throw;");
+ Assert.IsTrue(throwStmt.Expression.IsNull);
+ }
+
+ [Test]
+ public void ThrowStatementTest()
+ {
+ ThrowStatement throwStmt = ParseUtilCSharp.ParseStatement("throw new Exception();");
+ Assert.IsTrue(throwStmt.Expression is ObjectCreateExpression);
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/TryCatchStatementTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/TryCatchStatementTests.cs
new file mode 100644
index 0000000000..5854bf904d
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/TryCatchStatementTests.cs
@@ -0,0 +1,74 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using System.Linq;
+using NUnit.Framework;
+using ICSharpCode.NRefactory.PatternMatching;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.Statements
+{
+ [TestFixture]
+ public class TryCatchStatementTests
+ {
+ [Test]
+ public void SimpleTryCatchStatementTest()
+ {
+ TryCatchStatement tryCatchStatement = ParseUtilCSharp.ParseStatement("try { } catch { } ");
+ Assert.IsTrue(tryCatchStatement.FinallyBlock.IsNull);
+ Assert.AreEqual(1, tryCatchStatement.CatchClauses.Count());
+ Assert.IsTrue(tryCatchStatement.CatchClauses.Single().Type.IsNull);
+ Assert.AreEqual(string.Empty, tryCatchStatement.CatchClauses.Single().VariableName);
+ }
+
+ [Test]
+ public void SimpleTryCatchStatementTest2()
+ {
+ ParseUtilCSharp.AssertStatement(
+ "try { } catch (Exception e) { } ",
+ new TryCatchStatement {
+ TryBlock = new BlockStatement(),
+ CatchClauses = {
+ new CatchClause {
+ Type = new SimpleType("Exception"),
+ VariableName = "e",
+ Body = new BlockStatement()
+ }
+ }});
+ }
+
+ [Test]
+ public void SimpleTryCatchFinallyStatementTest()
+ {
+ ParseUtilCSharp.AssertStatement(
+ "try { } catch (Exception) { } catch { } finally { } ",
+ new TryCatchStatement {
+ TryBlock = new BlockStatement(),
+ CatchClauses = {
+ new CatchClause {
+ Type = new SimpleType("Exception"),
+ Body = new BlockStatement()
+ },
+ new CatchClause { Body = new BlockStatement() }
+ },
+ FinallyBlock = new BlockStatement()
+ });
+ }
+
+ [Test]
+ public void TestEmptyFinallyDoesNotMatchNullFinally()
+ {
+ TryCatchStatement c1 = new TryCatchStatement {
+ TryBlock = new BlockStatement(),
+ CatchClauses = { new CatchClause { Body = new BlockStatement() } }
+ };
+ TryCatchStatement c2 = new TryCatchStatement {
+ TryBlock = new BlockStatement(),
+ CatchClauses = { new CatchClause { Body = new BlockStatement() } },
+ FinallyBlock = new BlockStatement()
+ };
+ Assert.IsFalse(c1.IsMatch(c2));
+ Assert.IsFalse(c2.IsMatch(c1)); // and vice versa
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/UnsafeStatementTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/UnsafeStatementTests.cs
new file mode 100644
index 0000000000..bdeed271f7
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/UnsafeStatementTests.cs
@@ -0,0 +1,19 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.Statements
+{
+ [TestFixture]
+ public class UnsafeStatementTests
+ {
+ [Test]
+ public void UnsafeStatementTest()
+ {
+ UnsafeStatement unsafeStatement = ParseUtilCSharp.ParseStatement("unsafe { }");
+ Assert.IsFalse(unsafeStatement.Body.IsNull);
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/UsingStatementTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/UsingStatementTests.cs
new file mode 100644
index 0000000000..db377d0782
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/UsingStatementTests.cs
@@ -0,0 +1,31 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using System.Linq;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.Statements
+{
+ [TestFixture]
+ public class UsingStatementTests
+ {
+ [Test, Ignore("Parser doesn't report the VariableDeclarationStatement")]
+ public void UsingStatementWithVariableDeclaration()
+ {
+ UsingStatement usingStmt = ParseUtilCSharp.ParseStatement("using (MyVar var = new MyVar()) { } ");
+ VariableDeclarationStatement varDecl = (VariableDeclarationStatement)usingStmt.ResourceAcquisition;
+ Assert.AreEqual("var", varDecl.Variables.Single().Name);
+ Assert.IsTrue(varDecl.Variables.Single().Initializer is ObjectCreateExpression);
+ Assert.AreEqual("MyVar", ((SimpleType)varDecl.Type).Identifier);
+ Assert.IsTrue(usingStmt.EmbeddedStatement is BlockStatement);
+ }
+
+ public void UsingStatementWithExpression()
+ {
+ UsingStatement usingStmt = ParseUtilCSharp.ParseStatement("using (new MyVar()) { } ");
+ Assert.IsTrue(usingStmt.ResourceAcquisition is ObjectCreateExpression);
+ Assert.IsTrue(usingStmt.EmbeddedStatement is BlockStatement);
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/VariableDeclarationStatementTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/VariableDeclarationStatementTests.cs
new file mode 100644
index 0000000000..74564a6bf8
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/VariableDeclarationStatementTests.cs
@@ -0,0 +1,207 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using System.Linq;
+using ICSharpCode.NRefactory.PatternMatching;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.Statements
+{
+ [TestFixture]
+ public class VariableDeclarationStatementTests
+ {
+ [Test]
+ public void VariableDeclarationStatementTest()
+ {
+ VariableDeclarationStatement lvd = ParseUtilCSharp.ParseStatement("int a = 5;");
+ Assert.AreEqual(1, lvd.Variables.Count());
+ Assert.AreEqual("a", lvd.Variables.First ().Name);
+ var type = lvd.Type;
+ Assert.AreEqual("int", type.ToString ());
+ Assert.AreEqual(5, ((PrimitiveExpression)lvd.Variables.First ().Initializer).Value);
+ }
+
+ [Test]
+ public void VoidPointerVariableDeclarationTest()
+ {
+ VariableDeclarationStatement lvd = ParseUtilCSharp.ParseStatement("void *a;");
+ Assert.IsTrue(new VariableDeclarationStatement(new PrimitiveType("void").MakePointerType(), "a").IsMatch(lvd));
+ }
+
+ [Test]
+ public void ComplexGenericVariableDeclarationStatementTest()
+ {
+ VariableDeclarationStatement lvd = ParseUtilCSharp.ParseStatement("Generic > where = new Generic>();");
+ AstType type = new SimpleType("Generic") {
+ TypeArguments = {
+ new MemberType { Target = new SimpleType("Namespace"), MemberName = "Printable" },
+ new SimpleType("G") { TypeArguments = { new SimpleType("Printable").MakeArrayType() } }
+ }};
+ Assert.IsTrue(new VariableDeclarationStatement(type, "where", new ObjectCreateExpression { Type = type.Clone() }).IsMatch(lvd));
+ }
+
+ [Test]
+ public void NestedGenericVariableDeclarationStatementTest()
+ {
+ VariableDeclarationStatement lvd = ParseUtilCSharp.ParseStatement("MyType.InnerClass.InnerInnerClass a;");
+ AstType type = new MemberType {
+ Target = new MemberType {
+ Target = new SimpleType("MyType") { TypeArguments = { new PrimitiveType("string") } },
+ MemberName = "InnerClass",
+ TypeArguments = { new PrimitiveType("int") }
+ },
+ MemberName = "InnerInnerClass"
+ };
+ Assert.IsTrue(new VariableDeclarationStatement(type, "a").IsMatch(lvd));
+ }
+
+ [Test]
+ public void GenericWithArrayVariableDeclarationStatementTest1()
+ {
+ VariableDeclarationStatement lvd = ParseUtilCSharp.ParseStatement("G[] a;");
+ AstType type = new SimpleType("G") {
+ TypeArguments = { new PrimitiveType("int") }
+ }.MakeArrayType();
+ Assert.IsTrue(new VariableDeclarationStatement(type, "a").IsMatch(lvd));
+ }
+
+ [Test]
+ public void GenericWithArrayVariableDeclarationStatementTest2()
+ {
+ VariableDeclarationStatement lvd = ParseUtilCSharp.ParseStatement("G a;");
+ AstType type = new SimpleType("G") {
+ TypeArguments = { new PrimitiveType("int").MakeArrayType() }
+ };
+ Assert.IsTrue(new VariableDeclarationStatement(type, "a").IsMatch(lvd));
+ }
+
+ [Test]
+ public void GenericVariableDeclarationStatementTest2()
+ {
+ VariableDeclarationStatement lvd = ParseUtilCSharp.ParseStatement("G > a;");
+ AstType type = new SimpleType("G") {
+ TypeArguments = {
+ new SimpleType("G") { TypeArguments = { new PrimitiveType("int") } }
+ }
+ };
+ Assert.IsTrue(new VariableDeclarationStatement(type, "a").IsMatch(lvd));
+ }
+
+ [Test]
+ public void GenericVariableDeclarationStatementTest2WithoutSpace()
+ {
+ VariableDeclarationStatement lvd = ParseUtilCSharp.ParseStatement("G> a;");
+ AstType type = new SimpleType("G") {
+ TypeArguments = {
+ new SimpleType("G") { TypeArguments = { new PrimitiveType("int") } }
+ }
+ };
+ Assert.IsTrue(new VariableDeclarationStatement(type, "a").IsMatch(lvd));
+ }
+
+ [Test]
+ public void GenericVariableDeclarationStatementTest()
+ {
+ VariableDeclarationStatement lvd = ParseUtilCSharp.ParseStatement("G a;");
+ AstType type = new SimpleType("G") {
+ TypeArguments = { new PrimitiveType("int") }
+ };
+ Assert.IsTrue(new VariableDeclarationStatement(type, "a").IsMatch(lvd));
+ }
+
+ [Test]
+ public void SimpleVariableDeclarationStatementTest()
+ {
+ VariableDeclarationStatement lvd = ParseUtilCSharp.ParseStatement("MyVar var = new MyVar();");
+ Assert.IsTrue(new VariableDeclarationStatement(new SimpleType("MyVar"), "var", new ObjectCreateExpression { Type = new SimpleType("MyVar") }).IsMatch(lvd));
+ }
+
+ [Test]
+ public void SimpleVariableDeclarationStatementTest1()
+ {
+ VariableDeclarationStatement lvd = ParseUtilCSharp.ParseStatement("yield yield = new yield();");
+ Assert.IsTrue(new VariableDeclarationStatement(new SimpleType("yield"), "yield", new ObjectCreateExpression { Type = new SimpleType("yield") }).IsMatch(lvd));
+ }
+
+ [Test]
+ public void NullableVariableDeclarationStatementTest1()
+ {
+ VariableDeclarationStatement lvd = ParseUtilCSharp.ParseStatement("int? a;");
+ Assert.IsTrue(new VariableDeclarationStatement(new PrimitiveType("int").MakeNullableType(), "a").IsMatch(lvd));
+ }
+
+ [Test]
+ public void NullableVariableDeclarationStatementTest2()
+ {
+ VariableDeclarationStatement lvd = ParseUtilCSharp.ParseStatement("DateTime? a;");
+ Assert.IsTrue(new VariableDeclarationStatement(new SimpleType("DateTime").MakeNullableType(), "a").IsMatch(lvd));
+ }
+
+ [Test, Ignore("The parser creates nested ComposedTypes while MakeArrayType() adds the specifier to the existing ComposedType")]
+ public void NullableVariableDeclarationStatementTest3()
+ {
+ VariableDeclarationStatement lvd = ParseUtilCSharp.ParseStatement("DateTime?[] a;");
+ Assert.IsTrue(new VariableDeclarationStatement(new SimpleType("DateTime").MakeNullableType().MakeArrayType(), "a").IsMatch(lvd));
+ }
+
+ [Test]
+ public void NullableVariableDeclarationStatementTest4()
+ {
+ VariableDeclarationStatement lvd = ParseUtilCSharp.ParseStatement("SomeStruct? a;");
+ AstType type = new SimpleType("SomeStruct") {
+ TypeArguments = { new PrimitiveType("int").MakeNullableType() }
+ }.MakeNullableType();
+ Assert.IsTrue(new VariableDeclarationStatement(type, "a").IsMatch(lvd));
+ }
+
+ [Test]
+ public void PositionTestWithoutModifier()
+ {
+ VariableDeclarationStatement lvd = ParseUtilCSharp.ParseStatement("\ndouble w = 7;");
+ Assert.AreEqual(2, lvd.StartLocation.Line);
+ Assert.AreEqual(1, lvd.StartLocation.Column);
+ Assert.AreEqual(2, lvd.EndLocation.Line);
+ Assert.AreEqual(14, lvd.EndLocation.Column);
+ }
+
+ [Test]
+ public void PositionTestWithModifier()
+ {
+ VariableDeclarationStatement lvd = ParseUtilCSharp.ParseStatement("\nconst double w = 7;");
+ Assert.AreEqual(Modifiers.Const, lvd.Modifiers);
+ Assert.AreEqual(2, lvd.StartLocation.Line);
+ Assert.AreEqual(1, lvd.StartLocation.Column);
+ Assert.AreEqual(2, lvd.EndLocation.Line);
+ Assert.AreEqual(20, lvd.EndLocation.Column);
+ }
+
+ [Test, Ignore("Nested arrays are broken in the parser")]
+ public void NestedArray()
+ {
+ VariableDeclarationStatement lvd = ParseUtilCSharp.ParseStatement("DateTime[,][] a;");
+ Assert.IsTrue(new VariableDeclarationStatement(new SimpleType("DateTime").MakeArrayType(1).MakeArrayType(2), "a").IsMatch(lvd));
+ }
+
+ [Test, Ignore("Nested pointers are broken in the parser")]
+ public void NestedPointers()
+ {
+ VariableDeclarationStatement lvd = ParseUtilCSharp.ParseStatement("DateTime*** a;");
+ Assert.IsTrue(new VariableDeclarationStatement(new SimpleType("DateTime").MakePointerType().MakePointerType().MakePointerType(), "a").IsMatch(lvd));
+ }
+
+ [Test, Ignore("The parser creates nested ComposedTypes while MakeArrayType() adds the specifier to the existing ComposedType")]
+ public void ArrayOfPointers()
+ {
+ VariableDeclarationStatement lvd = ParseUtilCSharp.ParseStatement("DateTime*[] a;");
+ Assert.IsTrue(new VariableDeclarationStatement(new SimpleType("DateTime").MakePointerType().MakeArrayType(), "a").IsMatch(lvd));
+ }
+
+ [Test, Ignore("The parser creates nested ComposedTypes while MakeArrayType() adds the specifier to the existing ComposedType")]
+ public void ArrayOfNullables()
+ {
+ VariableDeclarationStatement lvd = ParseUtilCSharp.ParseStatement("DateTime?[] a;");
+ Assert.IsTrue(new VariableDeclarationStatement(new SimpleType("DateTime").MakeNullableType().MakeArrayType(), "a").IsMatch(lvd));
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/WhileStatementTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/WhileStatementTests.cs
new file mode 100644
index 0000000000..689eb05845
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/WhileStatementTests.cs
@@ -0,0 +1,28 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.Statements
+{
+ [TestFixture]
+ public class WhileStatementTests
+ {
+ [Test]
+ public void WhileStatementTest()
+ {
+ WhileStatement loopStmt = ParseUtilCSharp.ParseStatement("while (true) { }");
+ Assert.IsTrue(loopStmt.Condition is PrimitiveExpression);
+ Assert.IsTrue(loopStmt.EmbeddedStatement is BlockStatement);
+ }
+
+ [Test]
+ public void DoWhileStatementTest()
+ {
+ DoWhileStatement loopStmt = ParseUtilCSharp.ParseStatement("do { } while (true);");
+ Assert.IsTrue(loopStmt.Condition is PrimitiveExpression);
+ Assert.IsTrue(loopStmt.EmbeddedStatement is BlockStatement);
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/YieldStatementTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/YieldStatementTests.cs
new file mode 100644
index 0000000000..ae4d75d933
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/YieldStatementTests.cs
@@ -0,0 +1,40 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+
+using System;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.Statements
+{
+ [TestFixture]
+ public class YieldStatementTests
+ {
+ [Test]
+ public void YieldReturnStatementTest()
+ {
+ YieldStatement yieldStmt = ParseUtilCSharp.ParseStatement("yield return \"Foo\";");
+ PrimitiveExpression expr = (PrimitiveExpression)yieldStmt.Expression;
+ Assert.AreEqual("Foo", expr.Value);
+ }
+
+ [Test]
+ public void YieldBreakStatementTest()
+ {
+ ParseUtilCSharp.ParseStatement("yield break;");
+ }
+
+ [Test]
+ public void YieldAsVariableTest()
+ {
+ ExpressionStatement se = ParseUtilCSharp.ParseStatement("yield = 3;");
+ AssignmentExpression ae = se.Expression as AssignmentExpression;
+
+ Assert.AreEqual(AssignmentOperatorType.Assign, ae.Operator);
+
+ Assert.IsTrue(ae.Left is IdentifierExpression);
+ Assert.AreEqual("yield", ((IdentifierExpression)ae.Left).Identifier);
+ Assert.IsTrue(ae.Right is PrimitiveExpression);
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeMembers/ConstructorDeclarationTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeMembers/ConstructorDeclarationTests.cs
new file mode 100644
index 0000000000..3d3124a39e
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeMembers/ConstructorDeclarationTests.cs
@@ -0,0 +1,52 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using System.Linq;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.TypeMembers
+{
+ [TestFixture]
+ public class ConstructorDeclarationTests
+ {
+ [Test]
+ public void ConstructorDeclarationTest1()
+ {
+ ConstructorDeclaration cd = ParseUtilCSharp.ParseTypeMember("MyClass() {}");
+ Assert.IsTrue(cd.Initializer.IsNull);
+ }
+
+ [Test]
+ public void ConstructorDeclarationTest2()
+ {
+ ConstructorDeclaration cd = ParseUtilCSharp.ParseTypeMember("MyClass() : this(5) {}");
+ Assert.AreEqual(ConstructorInitializerType.This, cd.Initializer.ConstructorInitializerType);
+ Assert.AreEqual(1, cd.Initializer.Arguments.Count());
+ }
+
+ [Test]
+ public void ConstructorDeclarationTest3()
+ {
+ ConstructorDeclaration cd = ParseUtilCSharp.ParseTypeMember("MyClass() : base(1, 2, 3) {}");
+ Assert.AreEqual(ConstructorInitializerType.Base, cd.Initializer.ConstructorInitializerType);
+ Assert.AreEqual(3, cd.Initializer.Arguments.Count());
+ }
+
+ [Test]
+ public void StaticConstructorDeclarationTest1()
+ {
+ ConstructorDeclaration cd = ParseUtilCSharp.ParseTypeMember("static MyClass() {}");
+ Assert.IsTrue(cd.Initializer.IsNull);
+ Assert.AreEqual(Modifiers.Static, cd.Modifiers);
+ }
+
+ [Test]
+ public void ExternStaticConstructorDeclarationTest()
+ {
+ ConstructorDeclaration cd = ParseUtilCSharp.ParseTypeMember("extern static MyClass();");
+ Assert.IsTrue(cd.Initializer.IsNull);
+ Assert.AreEqual(Modifiers.Static | Modifiers.Extern, cd.Modifiers);
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeMembers/DestructorDeclarationTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeMembers/DestructorDeclarationTests.cs
new file mode 100644
index 0000000000..25ba714f74
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeMembers/DestructorDeclarationTests.cs
@@ -0,0 +1,32 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.TypeMembers
+{
+ [TestFixture]
+ public class DestructorDeclarationTests
+ {
+ [Test]
+ public void DestructorDeclarationTest()
+ {
+ DestructorDeclaration dd = ParseUtilCSharp.ParseTypeMember("~MyClass() {}");
+ }
+
+ [Test]
+ public void ExternDestructorDeclarationTest()
+ {
+ DestructorDeclaration dd = ParseUtilCSharp.ParseTypeMember("extern ~MyClass();");
+ Assert.AreEqual(Modifiers.Extern, dd.Modifiers);
+ }
+
+ [Test]
+ public void UnsafeDestructorDeclarationTest()
+ {
+ DestructorDeclaration dd = ParseUtilCSharp.ParseTypeMember("unsafe ~MyClass() {}");
+ Assert.AreEqual(Modifiers.Unsafe, dd.Modifiers);
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeMembers/EventDeclarationTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeMembers/EventDeclarationTests.cs
new file mode 100644
index 0000000000..35c98a4a19
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeMembers/EventDeclarationTests.cs
@@ -0,0 +1,89 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.TypeMembers
+{
+ [TestFixture]
+ public class EventDeclarationTests
+ {
+ [Test]
+ public void SimpleEventDeclarationTest()
+ {
+ ParseUtilCSharp.AssertTypeMember(
+ "event EventHandler MyEvent;",
+ new EventDeclaration {
+ ReturnType = new SimpleType("EventHandler"),
+ Variables = {
+ new VariableInitializer {
+ Name = "MyEvent"
+ }
+ }});
+ }
+
+ [Test]
+ public void MultipleEventDeclarationTest()
+ {
+ ParseUtilCSharp.AssertTypeMember(
+ "public event EventHandler A = null, B = delegate {};",
+ new EventDeclaration {
+ Modifiers = Modifiers.Public,
+ ReturnType = new SimpleType("EventHandler"),
+ Variables = {
+ new VariableInitializer {
+ Name = "A",
+ Initializer = new NullReferenceExpression()
+ },
+ new VariableInitializer {
+ Name = "B",
+ Initializer = new AnonymousMethodExpression() { Body = new BlockStatement ()}
+ }
+ }});
+ }
+
+ [Test]
+ public void AddRemoveEventDeclarationTest()
+ {
+ ParseUtilCSharp.AssertTypeMember(
+ "public event System.EventHandler MyEvent { add { } remove { } }",
+ new CustomEventDeclaration {
+ Modifiers = Modifiers.Public,
+ ReturnType = new MemberType {
+ Target = new SimpleType("System"),
+ MemberName = "EventHandler"
+ },
+ Name = "MyEvent",
+ AddAccessor = new Accessor { Body = new BlockStatement() },
+ RemoveAccessor = new Accessor { Body = new BlockStatement() }
+ });
+ }
+
+ [Test]
+ public void EventImplementingGenericInterfaceDeclarationTest()
+ {
+ ParseUtilCSharp.AssertTypeMember(
+ "event EventHandler MyInterface.MyEvent { add { } [Attr] remove {} }",
+ new CustomEventDeclaration {
+ ReturnType = new SimpleType("EventHandler"),
+ PrivateImplementationType = new SimpleType{
+ Identifier = "MyInterface",
+ TypeArguments = { new PrimitiveType("string") }
+ },
+ Name = "MyEvent",
+ AddAccessor = new Accessor { Body = new BlockStatement() },
+ RemoveAccessor = new Accessor {
+ Attributes = {
+ new AttributeSection {
+ Attributes = {
+ new Attribute { Type = new SimpleType("Attr") }
+ }
+ }
+ },
+ Body = new BlockStatement()
+ }
+ });
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeMembers/FieldDeclarationTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeMembers/FieldDeclarationTests.cs
new file mode 100644
index 0000000000..1ed04478b4
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeMembers/FieldDeclarationTests.cs
@@ -0,0 +1,76 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.TypeMembers
+{
+ [TestFixture]
+ public class FieldDeclarationTests
+ {
+ [Test]
+ public void SimpleFieldDeclarationTest()
+ {
+ ParseUtilCSharp.AssertTypeMember(
+ "int[,,,] myField;",
+ new FieldDeclaration {
+ ReturnType = new PrimitiveType("int").MakeArrayType(4),
+ Variables = { new VariableInitializer("myField") }
+ });
+ }
+
+ [Test]
+ public void MultipleFieldDeclarationTest()
+ {
+ ParseUtilCSharp.AssertTypeMember(
+ "int a = 1, b = 2;",
+ new FieldDeclaration {
+ ReturnType = new PrimitiveType("int"),
+ Variables = {
+ new VariableInitializer("a", new PrimitiveExpression(1)),
+ new VariableInitializer("b", new PrimitiveExpression(2)),
+ }
+ });
+ }
+
+ [Test]
+ public void FieldWithArrayInitializer()
+ {
+ ParseUtilCSharp.AssertTypeMember(
+ "public static readonly int[] arr = { 1, 2, 3 };",
+ new FieldDeclaration {
+ Modifiers = Modifiers.Public | Modifiers.Static | Modifiers.Readonly,
+ ReturnType = new PrimitiveType("int").MakeArrayType(),
+ Variables = {
+ new VariableInitializer {
+ Name = "arr",
+ Initializer = new ArrayInitializerExpression {
+ Elements = {
+ new PrimitiveExpression(1),
+ new PrimitiveExpression(2),
+ new PrimitiveExpression(3)
+ }
+ }
+ }
+ }});
+ }
+
+ [Test]
+ public void FieldWithFixedSize()
+ {
+ ParseUtilCSharp.AssertTypeMember(
+ "public unsafe fixed int Field[100];",
+ new FixedFieldDeclaration() {
+ Modifiers = Modifiers.Public | Modifiers.Unsafe,
+ ReturnType = new PrimitiveType("int"),
+ Variables = {
+ new FixedVariableInitializer {
+ Name = "Field",
+ CountExpression = new PrimitiveExpression(100)
+ }
+ }
+ });
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeMembers/IndexerDeclarationTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeMembers/IndexerDeclarationTests.cs
new file mode 100644
index 0000000000..a324c51b1f
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeMembers/IndexerDeclarationTests.cs
@@ -0,0 +1,58 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using System.Linq;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.TypeMembers
+{
+ [TestFixture]
+ public class IndexerDeclarationTests
+ {
+ [Test]
+ public void IndexerDeclarationTest()
+ {
+ IndexerDeclaration id = ParseUtilCSharp.ParseTypeMember("public int this[int a, string b] { get { } protected set { } }");
+ Assert.AreEqual(2, id.Parameters.Count());
+ Assert.IsNotNull(id.Getter, "No get region found!");
+ Assert.IsNotNull(id.Setter, "No set region found!");
+ Assert.AreEqual(Modifiers.Public, id.Modifiers);
+ Assert.AreEqual(Modifiers.None, id.Getter.Modifiers);
+ Assert.AreEqual(Modifiers.Protected, id.Setter.Modifiers);
+ }
+
+ [Test]
+ public void IndexerImplementingInterfaceTest()
+ {
+ IndexerDeclaration id = ParseUtilCSharp.ParseTypeMember("int MyInterface.this[int a, string b] { get { } set { } }");
+ Assert.AreEqual(2, id.Parameters.Count());
+ Assert.IsNotNull(id.Getter, "No get region found!");
+ Assert.IsNotNull(id.Setter, "No set region found!");
+
+ Assert.AreEqual("MyInterface", ((SimpleType)id.PrivateImplementationType).Identifier);
+ }
+
+ [Test]
+ public void IndexerImplementingGenericInterfaceTest()
+ {
+ ParseUtilCSharp.AssertTypeMember(
+ "int MyInterface.this[int a, string b] { get { } [Attr] set { } }",
+ new IndexerDeclaration {
+ ReturnType = new PrimitiveType("int"),
+ PrivateImplementationType = new SimpleType {
+ Identifier = "MyInterface",
+ TypeArguments = { new PrimitiveType("string") }
+ },
+ Parameters = {
+ new ParameterDeclaration(new PrimitiveType("int"), "a"),
+ new ParameterDeclaration(new PrimitiveType("string"), "b")
+ },
+ Getter = new Accessor { Body = new BlockStatement() },
+ Setter = new Accessor {
+ Attributes = { new AttributeSection(new Attribute { Type = new SimpleType("Attr") }) },
+ Body = new BlockStatement()
+ }});
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeMembers/MethodDeclarationTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeMembers/MethodDeclarationTests.cs
new file mode 100644
index 0000000000..c0a8ab3c3f
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeMembers/MethodDeclarationTests.cs
@@ -0,0 +1,344 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using System.Linq;
+using ICSharpCode.NRefactory.TypeSystem;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.TypeMembers
+{
+ [TestFixture]
+ public class MethodDeclarationTests
+ {
+ [Test]
+ public void SimpleMethodDeclarationTest()
+ {
+ MethodDeclaration md = ParseUtilCSharp.ParseTypeMember("void MyMethod() {} ");
+ Assert.AreEqual("void", ((PrimitiveType)md.ReturnType).Keyword);
+ Assert.AreEqual(0, md.Parameters.Count());
+ Assert.IsFalse(md.IsExtensionMethod);
+ }
+
+ [Test]
+ public void AbstractMethodDeclarationTest()
+ {
+ MethodDeclaration md = ParseUtilCSharp.ParseTypeMember("abstract void MyMethod();");
+ Assert.AreEqual("void", ((PrimitiveType)md.ReturnType).Keyword);
+ Assert.AreEqual(0, md.Parameters.Count());
+ Assert.IsFalse(md.IsExtensionMethod);
+ Assert.IsTrue(md.Body.IsNull);
+ Assert.AreEqual(Modifiers.Abstract, md.Modifiers);
+ }
+
+ [Test]
+ public void DefiningPartialMethodDeclarationTest()
+ {
+ MethodDeclaration md = ParseUtilCSharp.ParseTypeMember("partial void MyMethod();");
+ Assert.AreEqual("void", ((PrimitiveType)md.ReturnType).Keyword);
+ Assert.AreEqual(0, md.Parameters.Count());
+ Assert.IsFalse(md.IsExtensionMethod);
+ Assert.IsTrue(md.Body.IsNull);
+ Assert.AreEqual(Modifiers.Partial, md.Modifiers);
+ }
+
+ [Test]
+ public void ImplementingPartialMethodDeclarationTest()
+ {
+ MethodDeclaration md = ParseUtilCSharp.ParseTypeMember("partial void MyMethod() { }");
+ Assert.AreEqual("void", ((PrimitiveType)md.ReturnType).Keyword);
+ Assert.AreEqual(0, md.Parameters.Count());
+ Assert.IsFalse(md.IsExtensionMethod);
+ Assert.IsFalse(md.Body.IsNull);
+ Assert.AreEqual(Modifiers.Partial, md.Modifiers);
+ }
+
+ [Test]
+ public void SimpleMethodRegionTest()
+ {
+ const string program = @"
+ void MyMethod()
+ {
+ OtherMethod();
+ }
+";
+ MethodDeclaration md = ParseUtilCSharp.ParseTypeMember(program);
+ Assert.AreEqual(2, md.StartLocation.Line, "StartLocation.Y");
+ Assert.AreEqual(5, md.EndLocation.Line, "EndLocation.Y");
+ Assert.AreEqual(3, md.StartLocation.Column, "StartLocation.X");
+ Assert.AreEqual(4, md.EndLocation.Column, "EndLocation.X");
+ }
+
+ [Test]
+ public void MethodWithModifiersRegionTest()
+ {
+ const string program = @"
+ public static void MyMethod()
+ {
+ OtherMethod();
+ }
+";
+ MethodDeclaration md = ParseUtilCSharp.ParseTypeMember(program);
+ Assert.AreEqual(2, md.StartLocation.Line, "StartLocation.Y");
+ Assert.AreEqual(5, md.EndLocation.Line, "EndLocation.Y");
+ Assert.AreEqual(3, md.StartLocation.Column, "StartLocation.X");
+ Assert.AreEqual(4, md.EndLocation.Column, "EndLocation.X");
+ }
+
+ [Test]
+ public void MethodWithUnnamedParameterDeclarationTest()
+ {
+ MethodDeclaration md = ParseUtilCSharp.ParseTypeMember("void MyMethod(int) {} ", true);
+ Assert.AreEqual("void", md.ReturnType.ToString ());
+ Assert.AreEqual(1, md.Parameters.Count());
+ Assert.AreEqual("int", ((PrimitiveType)md.Parameters.Single().Type).Keyword);
+ }
+
+ [Test]
+ public void GenericVoidMethodDeclarationTest()
+ {
+ ParseUtilCSharp.AssertTypeMember(
+ "void MyMethod(T a) {} ",
+ new MethodDeclaration {
+ ReturnType = new PrimitiveType("void"),
+ Name = "MyMethod",
+ TypeParameters = { new TypeParameterDeclaration { Name = "T" } },
+ Parameters = { new ParameterDeclaration(new SimpleType("T"), "a") },
+ Body = new BlockStatement()
+ });
+ }
+
+ [Test]
+ public void GenericMethodDeclarationTest()
+ {
+ ParseUtilCSharp.AssertTypeMember(
+ "T MyMethod(T a) {} ",
+ new MethodDeclaration {
+ ReturnType = new SimpleType("T"),
+ Name = "MyMethod",
+ TypeParameters = { new TypeParameterDeclaration { Name = "T" } },
+ Parameters = { new ParameterDeclaration(new SimpleType("T"), "a") },
+ Body = new BlockStatement()
+ });
+ }
+
+ [Test]
+ public void GenericMethodDeclarationWithConstraintTest()
+ {
+ ParseUtilCSharp.AssertTypeMember(
+ "T MyMethod(T a) where T : ISomeInterface {} ",
+ new MethodDeclaration {
+ ReturnType = new SimpleType("T"),
+ Name = "MyMethod",
+ TypeParameters = { new TypeParameterDeclaration { Name = "T" } },
+ Parameters = { new ParameterDeclaration(new SimpleType("T"), "a") },
+ Constraints = {
+ new Constraint {
+ TypeParameter = "T",
+ BaseTypes = { new SimpleType("ISomeInterface") }
+ }
+ },
+ Body = new BlockStatement()
+ });
+ }
+
+ [Test]
+ public void GenericMethodInInterface()
+ {
+ ParseUtilCSharp.AssertGlobal(
+ @"interface MyInterface {
+ T MyMethod(T a) where T : ISomeInterface;
+}
+",
+ new TypeDeclaration {
+ ClassType = ClassType.Interface,
+ Members = {
+ new MethodDeclaration {
+ ReturnType = new SimpleType("T"),
+ Name = "MyMethod",
+ TypeParameters = { new TypeParameterDeclaration { Name = "T" } },
+ Parameters = { new ParameterDeclaration(new SimpleType("T"), "a") },
+ Constraints = {
+ new Constraint {
+ TypeParameter = "T",
+ BaseTypes = { new SimpleType("ISomeInterface") }
+ }
+ }
+ }}});
+ }
+
+ [Test]
+ public void GenericVoidMethodInInterface()
+ {
+ ParseUtilCSharp.AssertGlobal(
+ @"interface MyInterface {
+ void MyMethod(T a) where T : ISomeInterface;
+}
+",
+ new TypeDeclaration {
+ ClassType = ClassType.Interface,
+ Members = {
+ new MethodDeclaration {
+ ReturnType = new PrimitiveType("void"),
+ Name = "MyMethod",
+ TypeParameters = { new TypeParameterDeclaration { Name = "T" } },
+ Parameters = { new ParameterDeclaration(new SimpleType("T"), "a") },
+ Constraints = {
+ new Constraint {
+ TypeParameter = "T",
+ BaseTypes = { new SimpleType("ISomeInterface") }
+ }
+ }
+ }}});
+ }
+
+ [Test]
+ public void ShadowingMethodInInterface()
+ {
+ ParseUtilCSharp.AssertGlobal(
+ @"interface MyInterface : IDisposable {
+ new void Dispose();
+}
+",
+ new TypeDeclaration {
+ ClassType = ClassType.Interface,
+ Name = "MyInterface",
+ BaseTypes = { new SimpleType("IDisposable") },
+ Members = {
+ new MethodDeclaration {
+ Modifiers = Modifiers.New,
+ ReturnType = new PrimitiveType("void"),
+ Name = "Dispose"
+ }}});
+ }
+
+ [Test]
+ public void MethodImplementingInterfaceTest()
+ {
+ ParseUtilCSharp.AssertTypeMember(
+ "int MyInterface.MyMethod() {} ",
+ new MethodDeclaration {
+ ReturnType = new PrimitiveType("int"),
+ PrivateImplementationType = new SimpleType("MyInterface"),
+ Name = "MyMethod",
+ Body = new BlockStatement()
+ });
+ }
+
+ [Test]
+ public void MethodImplementingGenericInterfaceTest()
+ {
+ ParseUtilCSharp.AssertTypeMember(
+ "int MyInterface.MyMethod() {} ",
+ new MethodDeclaration {
+ ReturnType = new PrimitiveType("int"),
+ PrivateImplementationType = new SimpleType("MyInterface") { TypeArguments = { new PrimitiveType("string") } },
+ Name = "MyMethod",
+ Body = new BlockStatement()
+ });
+ }
+
+ [Test]
+ public void VoidMethodImplementingInterfaceTest()
+ {
+ ParseUtilCSharp.AssertTypeMember (
+ "void MyInterface.MyMethod() {} ",
+ new MethodDeclaration {
+ ReturnType = new PrimitiveType("void"),
+ PrivateImplementationType = new SimpleType("MyInterface"),
+ Name = "MyMethod",
+ Body = new BlockStatement()
+ });
+ }
+
+ [Test]
+ public void VoidMethodImplementingGenericInterfaceTest()
+ {
+ ParseUtilCSharp.AssertTypeMember (
+ "void MyInterface.MyMethod() {} ",
+ new MethodDeclaration {
+ ReturnType = new PrimitiveType("void"),
+ PrivateImplementationType = new SimpleType("MyInterface") { TypeArguments = { new PrimitiveType("string") } },
+ Name = "MyMethod",
+ Body = new BlockStatement()
+ });
+ }
+
+ [Test]
+ public void IncompleteConstraintsTest()
+ {
+ MethodDeclaration md = ParseUtilCSharp.ParseTypeMember(
+ "void a() where T { }", true // expect errors
+ );
+ Assert.AreEqual("a", md.Name);
+ Assert.AreEqual(1, md.TypeParameters.Count);
+ Assert.AreEqual("T", md.TypeParameters.Single().Name);
+ Assert.AreEqual(0, md.Constraints.Count());
+ }
+
+ [Test]
+ public void ExtensionMethodTest()
+ {
+ MethodDeclaration md = ParseUtilCSharp.ParseTypeMember(
+ "public static int ToInt32(this string s) { return int.Parse(s); }"
+ );
+ Assert.AreEqual("ToInt32", md.Name);
+ Assert.AreEqual("s", md.Parameters.First().Name);
+ Assert.AreEqual(ParameterModifier.This, md.Parameters.First().ParameterModifier);
+ Assert.AreEqual("string", ((PrimitiveType)md.Parameters.First().Type).Keyword);
+ Assert.IsTrue(md.IsExtensionMethod);
+ }
+
+ [Test]
+ public void VoidExtensionMethodTest()
+ {
+ MethodDeclaration md = ParseUtilCSharp.ParseTypeMember(
+ "public static void Print(this string s) { Console.WriteLine(s); }"
+ );
+ Assert.AreEqual("Print", md.Name);
+ Assert.AreEqual("s", md.Parameters.First().Name);
+ Assert.AreEqual(ParameterModifier.This, md.Parameters.First().ParameterModifier);
+ Assert.AreEqual("string", ((PrimitiveType)md.Parameters.First().Type).Keyword);
+ Assert.IsTrue(md.IsExtensionMethod);
+ }
+
+ [Test]
+ public void MethodWithEmptyAssignmentErrorInBody()
+ {
+ MethodDeclaration md = ParseUtilCSharp.ParseTypeMember(
+ "void A ()\n" +
+ "{\n" +
+ "int a = 3;\n" +
+ " = 4;\n" +
+ "}", true // expect errors
+ );
+ Assert.AreEqual("A", md.Name);
+ Assert.AreEqual(new AstLocation(2, 1), md.Body.StartLocation);
+ Assert.AreEqual(new AstLocation(5, 2), md.Body.EndLocation);
+ }
+
+ [Test]
+ public void OptionalParameterTest()
+ {
+ ParseUtilCSharp.AssertTypeMember(
+ "public void Foo(string bar = null, int baz = 0) { }",
+ new MethodDeclaration {
+ Modifiers = Modifiers.Public,
+ ReturnType = new PrimitiveType("void"),
+ Name = "Foo",
+ Body = new BlockStatement(),
+ Parameters = {
+ new ParameterDeclaration {
+ Type = new PrimitiveType("string"),
+ Name = "bar",
+ DefaultExpression = new NullReferenceExpression()
+ },
+ new ParameterDeclaration {
+ Type = new PrimitiveType("int"),
+ Name = "baz",
+ DefaultExpression = new PrimitiveExpression(0)
+ }
+ }});
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeMembers/OperatorDeclarationTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeMembers/OperatorDeclarationTests.cs
new file mode 100644
index 0000000000..4956d374aa
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeMembers/OperatorDeclarationTests.cs
@@ -0,0 +1,53 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using System.Linq;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.TypeMembers
+{
+ [TestFixture]
+ public class OperatorDeclarationTests
+ {
+ [Test]
+ public void ImplictOperatorDeclarationTest()
+ {
+ OperatorDeclaration od = ParseUtilCSharp.ParseTypeMember("public static implicit operator double(MyObject f) { return 0.5d; }");
+ Assert.AreEqual(OperatorType.Implicit, od.OperatorType);
+ Assert.AreEqual(1, od.Parameters.Count());
+ Assert.AreEqual("double", ((PrimitiveType)od.ReturnType).Keyword);
+ Assert.AreEqual("op_Implicit", od.Name);
+ }
+
+ [Test]
+ public void ExplicitOperatorDeclarationTest()
+ {
+ OperatorDeclaration od = ParseUtilCSharp.ParseTypeMember("public static explicit operator double(MyObject f) { return 0.5d; }");
+ Assert.AreEqual(OperatorType.Explicit, od.OperatorType);
+ Assert.AreEqual(1, od.Parameters.Count());
+ Assert.AreEqual("double", ((PrimitiveType)od.ReturnType).Keyword);
+ Assert.AreEqual("op_Explicit", od.Name);
+ }
+
+ [Test]
+ public void BinaryPlusOperatorDeclarationTest()
+ {
+ OperatorDeclaration od = ParseUtilCSharp.ParseTypeMember("public static MyObject operator +(MyObject a, MyObject b) {}");
+ Assert.AreEqual(OperatorType.Addition, od.OperatorType);
+ Assert.AreEqual(2, od.Parameters.Count());
+ Assert.AreEqual("MyObject", ((SimpleType)od.ReturnType).Identifier);
+ Assert.AreEqual("op_Addition", od.Name);
+ }
+
+ [Test]
+ public void UnaryPlusOperatorDeclarationTest()
+ {
+ OperatorDeclaration od = ParseUtilCSharp.ParseTypeMember("public static MyObject operator +(MyObject a) {}");
+ Assert.AreEqual(OperatorType.UnaryPlus, od.OperatorType);
+ Assert.AreEqual(1, od.Parameters.Count());
+ Assert.AreEqual("MyObject", ((SimpleType)od.ReturnType).Identifier);
+ Assert.AreEqual("op_UnaryPlus", od.Name);
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeMembers/PropertyDeclarationTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeMembers/PropertyDeclarationTests.cs
new file mode 100644
index 0000000000..a9d0711d4d
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeMembers/PropertyDeclarationTests.cs
@@ -0,0 +1,92 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using System.IO;
+using System.Linq;
+using NUnit.Framework;
+using ICSharpCode.NRefactory.PatternMatching;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser.TypeMembers
+{
+ [TestFixture]
+ public class PropertyDeclarationTests
+ {
+ [Test]
+ public void SimpleGetSetPropertyDeclarationTest()
+ {
+ PropertyDeclaration pd = ParseUtilCSharp.ParseTypeMember("int MyProperty { get {} set {} } ");
+ Assert.AreEqual("MyProperty", pd.Name);
+ Assert.IsFalse(pd.Getter.IsNull);
+ Assert.IsFalse(pd.Setter.IsNull);
+ }
+
+ [Test]
+ public void GetSetPropertyDeclarationWithAccessorModifiers()
+ {
+ PropertyDeclaration pd = ParseUtilCSharp.ParseTypeMember("int MyProperty { private get {} protected internal set {} } ");
+ Assert.AreEqual("MyProperty", pd.Name);
+ Assert.IsFalse(pd.Getter.IsNull);
+ Assert.IsFalse(pd.Setter.IsNull);
+ }
+
+ [Test]
+ public void SimpleGetPropertyDeclarationTest()
+ {
+ PropertyDeclaration pd = ParseUtilCSharp.ParseTypeMember("int MyProperty { get {} } ");
+ Assert.AreEqual("MyProperty", pd.Name);
+ Assert.IsFalse(pd.Getter.IsNull);
+ Assert.IsTrue(pd.Setter.IsNull);
+ }
+
+ [Test]
+ public void SimpleSetPropertyDeclarationTest()
+ {
+ PropertyDeclaration pd = ParseUtilCSharp.ParseTypeMember("int MyProperty { set {} } ");
+ Assert.AreEqual("MyProperty", pd.Name);
+ Assert.IsTrue(pd.Getter.IsNull);
+ Assert.IsFalse(pd.Setter.IsNull);
+ }
+
+ [Test]
+ public void PropertyRegionTest()
+ {
+ const string code = "class T {\n\tint Prop {\n\t\tget { return f; }\n\t\tset { f = value; }\n\t}\n}\n";
+ int line2Pos = code.IndexOf("\tint Prop");
+ int line3Pos = code.IndexOf("\t\tget");
+ int line4Pos = code.IndexOf("\t\tset");
+
+ CSharpParser parser = new CSharpParser();
+ CompilationUnit cu = parser.Parse(new StringReader(code));
+ PropertyDeclaration pd = (PropertyDeclaration)cu.Children.Single().GetChildByRole(TypeDeclaration.MemberRole);
+ Assert.AreEqual(new AstLocation(2, code.IndexOf("{\n\t\tget") - line2Pos + 1), pd.GetChildByRole(AstNode.Roles.LBrace).StartLocation);
+ Assert.AreEqual(new AstLocation(5, 3), pd.EndLocation);
+ Assert.AreEqual(new AstLocation(3, code.IndexOf("{ return") - line3Pos + 1), pd.Getter.Body.StartLocation);
+ Assert.AreEqual(new AstLocation(3, code.IndexOf("}\n\t\tset") + 1 - line3Pos + 1), pd.Getter.Body.EndLocation);
+ Assert.AreEqual(new AstLocation(4, code.IndexOf("{ f =") - line4Pos + 1), pd.Setter.Body.StartLocation);
+ Assert.AreEqual(new AstLocation(4, code.IndexOf("}\n\t}") + 1 - line4Pos + 1), pd.Setter.Body.EndLocation);
+ }
+
+ [Test]
+ public void PropertyImplementingInterfaceTest()
+ {
+ PropertyDeclaration pd = ParseUtilCSharp.ParseTypeMember("int MyInterface.MyProperty { get {} } ");
+ Assert.AreEqual("MyProperty", pd.Name);
+ Assert.IsFalse(pd.Getter.IsNull);
+ Assert.IsTrue(pd.Setter.IsNull);
+
+ Assert.AreEqual("MyInterface", ((SimpleType)pd.PrivateImplementationType).Identifier);
+ }
+
+ [Test]
+ public void PropertyImplementingGenericInterfaceTest()
+ {
+ PropertyDeclaration pd = ParseUtilCSharp.ParseTypeMember("int MyInterface.MyProperty { get {} } ");
+ Assert.AreEqual("MyProperty", pd.Name);
+ Assert.IsFalse(pd.Getter.IsNull);
+ Assert.IsTrue(pd.Setter.IsNull);
+
+ Assert.IsTrue(new SimpleType { Identifier = "MyInterface", TypeArguments = { new PrimitiveType("string") } }.IsMatch(pd.PrivateImplementationType));
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeSystemConvertVisitorTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeSystemConvertVisitorTests.cs
new file mode 100644
index 0000000000..9606e32471
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeSystemConvertVisitorTests.cs
@@ -0,0 +1,36 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+
+using System;
+using System.IO;
+using ICSharpCode.NRefactory.TypeSystem;
+using ICSharpCode.NRefactory.TypeSystem.Implementation;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Parser
+{
+ [TestFixture]
+ public class TypeSystemConvertVisitorTests : TypeSystemTests
+ {
+ ITypeResolveContext ctx = CecilLoaderTests.Mscorlib;
+
+ [TestFixtureSetUp]
+ public void FixtureSetUp()
+ {
+ const string fileName = "TypeSystemTests.TestCase.cs";
+
+ CSharpParser parser = new CSharpParser();
+ CompilationUnit cu;
+ using (Stream s = typeof(TypeSystemTests).Assembly.GetManifestResourceStream(typeof(TypeSystemTests), fileName)) {
+ cu = parser.Parse(s);
+ }
+
+ testCasePC = new SimpleProjectContent();
+ TypeSystemConvertVisitor visitor = new TypeSystemConvertVisitor(testCasePC, fileName);
+ cu.AcceptVisitor(visitor, null);
+ ParsedFile parsedFile = visitor.ParsedFile;
+ ((SimpleProjectContent)testCasePC).UpdateProjectContent(null, parsedFile);
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ArrayCreationTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ArrayCreationTests.cs
new file mode 100644
index 0000000000..335b42e7c5
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ArrayCreationTests.cs
@@ -0,0 +1,63 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT license (for details please see \doc\license.txt)
+
+using System;
+using ICSharpCode.NRefactory.TypeSystem;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Resolver
+{
+ [TestFixture]
+ [Ignore("Parser produces incorrect positions")]
+ public class ArrayCreationTests : ResolverTestBase
+ {
+ [Test]
+ public void SimpleArrayCreation()
+ {
+ string program = @"using System.Collections.Generic;
+class A {
+ static void Main() {
+ var a = $new int[] { 42 }$;
+ }
+}
+";
+ var result = Resolve(program);
+ Assert.AreEqual("System.Int32[]", result.Type.ReflectionName);
+ }
+
+ [Test]
+ public void NestedArrayCreation()
+ {
+ string program = @"using System.Collections.Generic;
+class A {
+ static void Main() {
+ var a = $new int[2][,][,,]$;
+ }
+}
+";
+ var result = Resolve(program);
+ // a one-dimensional array of two-dimensional arrays of three-dimensional arrays
+ ArrayType a1 = (ArrayType)result.Type;
+ Assert.AreEqual(1, a1.Dimensions);
+ ArrayType a2 = (ArrayType)a1.ElementType;
+ Assert.AreEqual(2, a2.Dimensions);
+ ArrayType a3 = (ArrayType)a2.ElementType;
+ Assert.AreEqual(3, a3.Dimensions);
+ Assert.AreEqual("System.Int32", a3.ElementType.ReflectionName);
+ }
+
+ [Test]
+ public void InferredType()
+ {
+ string program = @"using System.Collections.Generic;
+class A {
+ static void Main() {
+ var a = $new [] { 1, 1L }$;
+ }
+}
+";
+ var result = Resolve(program);
+ Assert.AreEqual("System.Int64[]", result.Type.ReflectionName);
+ }
+ }
+}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Resolver/AttributeTests.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Resolver/AttributeTests.cs
new file mode 100644
index 0000000000..bca4362542
--- /dev/null
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Resolver/AttributeTests.cs
@@ -0,0 +1,96 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using ICSharpCode.NRefactory.TypeSystem;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.CSharp.Resolver
+{
+ [TestFixture]
+ public class AttributeTests : ResolverTestBase
+ {
+ [Test]
+ public void NamespaceInAttributeContext()
+ {
+ string program = "using System; [$System.Runtime$.CompilerServices.IndexerName(\"bla\")] class Test { }";
+ NamespaceResolveResult result = Resolve(program);
+ Assert.AreEqual("System.Runtime", result.NamespaceName);
+ }
+
+ [Test]
+ public void AttributeWithShortName()
+ {
+ string program = "using System; [$Obsolete$] class Test {}";
+
+ TypeResolveResult result = Resolve(program);
+ Assert.AreEqual("System.ObsoleteAttribute", result.Type.FullName);
+ }
+
+ [Test]
+ public void QualifiedAttributeWithShortName()
+ {
+ string program = "using System; [$System.Obsolete$] class Test {}";
+
+ TypeResolveResult result = Resolve(program);
+ Assert.AreEqual("System.ObsoleteAttribute", result.Type.FullName);
+ }
+
+ [Test]
+ public void AttributeConstructor1()
+ {
+ string program = "using System; [$LoaderOptimization(3)$] class Test { }";
+ var mrr = Resolve(program);
+ Assert.AreEqual("System.LoaderOptimizationAttribute..ctor", mrr.Member.FullName);
+ Assert.AreEqual("System.Byte", (mrr.Member as IMethod).Parameters[0].Type.Resolve(context).FullName);
+ }
+
+ [Test]
+ public void AttributeConstructor2()
+ {
+ string program = "using System; [$LoaderOptimization(LoaderOptimization.NotSpecified)$] class Test { }";
+ var mrr = Resolve