Browse Source

Squashed 'NRefactory/' changes from b28b9a3..2200240

2200240 InsertParenthesesVisitor: don't insert parentheses for "a && b && c"
5a34a9c Fix output of checked and unchecked expressions.
695138d Add visitor support to pattern nodes (IPatternAstVisitor). Add pattern support to output visitor (makes debugging easier if you can print out patterns)
38faf84 Add support for 'any' operator and fix a bug in pattern matching.
eeb4ea5 Add simple backtracking support to pattern matching.
e6c0091 Implement pattern matching for statements.
93cc19d Determine loop condition from CFG
23190aa NRefactory AST: Add 'Repeat' pattern which matches an arbitrary number of nodes.
379063a OutputVisitor bugfix: show return type for custom events.
bce9881 Add some improvements to pattern matching.
f5e89bf Add Choice pattern.
84a5ace OutputVisitor: allow writing constructor declarations without writing their parent type declaration.
13c6417 Add some documentation comments.
7e03cf8 Fix output of using statement when the resource acquisition is a VariableDeclarationStatement.
9d5390c Add pattern matching support to the NRefactory C# AST.
1af927c Fix lambda expression output bug.
904b05f NRefactory: remove collection setters from AST; expose AstNodeCollection<T> instead.
0fa2fd6 Fix missing dot in namespace declarations.
8641726 Escape surrogates in string literals.
f1ce3e9 Fix order of modifiers.
cd9efb5 Fixed infinite loop in AstComparer
3e02950 Merge commit '814b8b3bf3553c719c84be7b0aa71c946731e36a'
7c23366 Merge in the latest NRefactory (8db1fe252f6539e9cde8c9fb5f59aa60e4089d8f)

git-subtree-dir: NRefactory
git-subtree-split: 2200240ef60fc49f32b89eb85c9f3a8ba796b08d
pull/129/head
Daniel Grunwald 15 years ago
parent
commit
7ac091e93d
  1. 74
      ICSharpCode.NRefactory.Tests/CSharp/InsertParenthesesVisitorTests.cs
  2. 42
      ICSharpCode.NRefactory/CSharp/Ast/AstComparer.cs
  3. 70
      ICSharpCode.NRefactory/CSharp/Ast/AstNode.cs
  4. 201
      ICSharpCode.NRefactory/CSharp/Ast/AstNodeCollection.cs
  5. 6
      ICSharpCode.NRefactory/CSharp/Ast/AstType.cs
  6. 52
      ICSharpCode.NRefactory/CSharp/Ast/CSharpModifierToken.cs
  7. 13
      ICSharpCode.NRefactory/CSharp/Ast/CSharpTokenNode.cs
  8. 7
      ICSharpCode.NRefactory/CSharp/Ast/CompilationUnit.cs
  9. 15
      ICSharpCode.NRefactory/CSharp/Ast/ComposedType.cs
  10. 11
      ICSharpCode.NRefactory/CSharp/Ast/Expressions/AnonymousMethodExpression.cs
  11. 11
      ICSharpCode.NRefactory/CSharp/Ast/Expressions/ArgListExpression.cs
  12. 12
      ICSharpCode.NRefactory/CSharp/Ast/Expressions/ArrayCreateExpression.cs
  13. 16
      ICSharpCode.NRefactory/CSharp/Ast/Expressions/ArrayInitializerExpression.cs
  14. 8
      ICSharpCode.NRefactory/CSharp/Ast/Expressions/AsExpression.cs
  15. 12
      ICSharpCode.NRefactory/CSharp/Ast/Expressions/AssignmentExpression.cs
  16. 8
      ICSharpCode.NRefactory/CSharp/Ast/Expressions/BaseReferenceExpression.cs
  17. 18
      ICSharpCode.NRefactory/CSharp/Ast/Expressions/BinaryOperatorExpression.cs
  18. 8
      ICSharpCode.NRefactory/CSharp/Ast/Expressions/CastExpression.cs
  19. 8
      ICSharpCode.NRefactory/CSharp/Ast/Expressions/CheckedExpression.cs
  20. 8
      ICSharpCode.NRefactory/CSharp/Ast/Expressions/ConditionalExpression.cs
  21. 8
      ICSharpCode.NRefactory/CSharp/Ast/Expressions/DefaultValueExpression.cs
  22. 8
      ICSharpCode.NRefactory/CSharp/Ast/Expressions/DirectionExpression.cs
  23. 53
      ICSharpCode.NRefactory/CSharp/Ast/Expressions/Expression.cs
  24. 11
      ICSharpCode.NRefactory/CSharp/Ast/Expressions/IdentifierExpression.cs
  25. 11
      ICSharpCode.NRefactory/CSharp/Ast/Expressions/IndexerExpression.cs
  26. 11
      ICSharpCode.NRefactory/CSharp/Ast/Expressions/InvocationExpression.cs
  27. 8
      ICSharpCode.NRefactory/CSharp/Ast/Expressions/IsExpression.cs
  28. 11
      ICSharpCode.NRefactory/CSharp/Ast/Expressions/LambdaExpression.cs
  29. 11
      ICSharpCode.NRefactory/CSharp/Ast/Expressions/MemberReferenceExpression.cs
  30. 6
      ICSharpCode.NRefactory/CSharp/Ast/Expressions/NamedArgumentExpression.cs
  31. 8
      ICSharpCode.NRefactory/CSharp/Ast/Expressions/NullReferenceExpression.cs
  32. 11
      ICSharpCode.NRefactory/CSharp/Ast/Expressions/ObjectCreateExpression.cs
  33. 8
      ICSharpCode.NRefactory/CSharp/Ast/Expressions/ParenthesizedExpression.cs
  34. 11
      ICSharpCode.NRefactory/CSharp/Ast/Expressions/PointerReferenceExpression.cs
  35. 10
      ICSharpCode.NRefactory/CSharp/Ast/Expressions/PrimitiveExpression.cs
  36. 29
      ICSharpCode.NRefactory/CSharp/Ast/Expressions/QueryExpression.cs
  37. 8
      ICSharpCode.NRefactory/CSharp/Ast/Expressions/SizeOfExpression.cs
  38. 8
      ICSharpCode.NRefactory/CSharp/Ast/Expressions/StackAllocExpression.cs
  39. 8
      ICSharpCode.NRefactory/CSharp/Ast/Expressions/ThisReferenceExpression.cs
  40. 8
      ICSharpCode.NRefactory/CSharp/Ast/Expressions/TypeOfExpression.cs
  41. 8
      ICSharpCode.NRefactory/CSharp/Ast/Expressions/TypeReferenceExpression.cs
  42. 8
      ICSharpCode.NRefactory/CSharp/Ast/Expressions/UnaryOperatorExpression.cs
  43. 8
      ICSharpCode.NRefactory/CSharp/Ast/Expressions/UncheckedExpression.cs
  44. 11
      ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/Attribute.cs
  45. 11
      ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/AttributeSection.cs
  46. 8
      ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/Comment.cs
  47. 11
      ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/Constraint.cs
  48. 11
      ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/DelegateDeclaration.cs
  49. 16
      ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/NamespaceDeclaration.cs
  50. 14
      ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/TypeDeclaration.cs
  51. 6
      ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/TypeParameterDeclaration.cs
  52. 8
      ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/UsingAliasDeclaration.cs
  53. 8
      ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/UsingDeclaration.cs
  54. 8
      ICSharpCode.NRefactory/CSharp/Ast/Identifier.cs
  55. 11
      ICSharpCode.NRefactory/CSharp/Ast/MemberType.cs
  56. 4
      ICSharpCode.NRefactory/CSharp/Ast/NodeType.cs
  57. 35
      ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/AnyNode.cs
  58. 70
      ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Backreference.cs
  59. 54
      ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Choice.cs
  60. 22
      ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/IPatternAstVisitor.cs
  61. 59
      ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Match.cs
  62. 38
      ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/NamedNode.cs
  63. 70
      ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Pattern.cs
  64. 119
      ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Placeholder.cs
  65. 55
      ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Repeat.cs
  66. 8
      ICSharpCode.NRefactory/CSharp/Ast/PrimitiveType.cs
  67. 11
      ICSharpCode.NRefactory/CSharp/Ast/SimpleType.cs
  68. 38
      ICSharpCode.NRefactory/CSharp/Ast/Statements/BlockStatement.cs
  69. 10
      ICSharpCode.NRefactory/CSharp/Ast/Statements/BreakStatement.cs
  70. 8
      ICSharpCode.NRefactory/CSharp/Ast/Statements/CheckedStatement.cs
  71. 8
      ICSharpCode.NRefactory/CSharp/Ast/Statements/ContinueStatement.cs
  72. 8
      ICSharpCode.NRefactory/CSharp/Ast/Statements/DoWhileStatement.cs
  73. 8
      ICSharpCode.NRefactory/CSharp/Ast/Statements/EmptyStatement.cs
  74. 17
      ICSharpCode.NRefactory/CSharp/Ast/Statements/ExpressionStatement.cs
  75. 11
      ICSharpCode.NRefactory/CSharp/Ast/Statements/FixedStatement.cs
  76. 17
      ICSharpCode.NRefactory/CSharp/Ast/Statements/ForStatement.cs
  77. 9
      ICSharpCode.NRefactory/CSharp/Ast/Statements/ForeachStatement.cs
  78. 38
      ICSharpCode.NRefactory/CSharp/Ast/Statements/GotoStatement.cs
  79. 8
      ICSharpCode.NRefactory/CSharp/Ast/Statements/IfElseStatement.cs
  80. 12
      ICSharpCode.NRefactory/CSharp/Ast/Statements/LabelStatement.cs
  81. 8
      ICSharpCode.NRefactory/CSharp/Ast/Statements/LockStatement.cs
  82. 8
      ICSharpCode.NRefactory/CSharp/Ast/Statements/ReturnStatement.cs
  83. 5
      ICSharpCode.NRefactory/CSharp/Ast/Statements/Statement.cs
  84. 29
      ICSharpCode.NRefactory/CSharp/Ast/Statements/SwitchStatement.cs
  85. 8
      ICSharpCode.NRefactory/CSharp/Ast/Statements/ThrowStatement.cs
  86. 17
      ICSharpCode.NRefactory/CSharp/Ast/Statements/TryCatchStatement.cs
  87. 8
      ICSharpCode.NRefactory/CSharp/Ast/Statements/UncheckedStatement.cs
  88. 8
      ICSharpCode.NRefactory/CSharp/Ast/Statements/UnsafeStatement.cs
  89. 8
      ICSharpCode.NRefactory/CSharp/Ast/Statements/UsingStatement.cs
  90. 21
      ICSharpCode.NRefactory/CSharp/Ast/Statements/VariableDeclarationStatement.cs
  91. 8
      ICSharpCode.NRefactory/CSharp/Ast/Statements/WhileStatement.cs
  92. 8
      ICSharpCode.NRefactory/CSharp/Ast/Statements/YieldBreakStatement.cs
  93. 8
      ICSharpCode.NRefactory/CSharp/Ast/Statements/YieldStatement.cs
  94. 9
      ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/Accessor.cs
  95. 13
      ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/AttributedNode.cs
  96. 21
      ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/ConstructorDeclaration.cs
  97. 9
      ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/DestructorDeclaration.cs
  98. 5
      ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/EventDeclaration.cs
  99. 5
      ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/FieldDeclaration.cs
  100. 5
      ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/IndexerDeclaration.cs
  101. Some files were not shown because too many files have changed in this diff Show More

74
ICSharpCode.NRefactory.Tests/CSharp/InsertParenthesesVisitorTests.cs

@ -159,7 +159,7 @@ namespace ICSharpCode.NRefactory.CSharp
public void MethodCallOnQueryExpression() public void MethodCallOnQueryExpression()
{ {
Expression expr = new QueryExpression { Expression expr = new QueryExpression {
Clauses = new QueryClause[] { Clauses = {
new QueryFromClause { new QueryFromClause {
Identifier = "a", Identifier = "a",
Expression = new IdentifierExpression("b") Expression = new IdentifierExpression("b")
@ -178,7 +178,7 @@ namespace ICSharpCode.NRefactory.CSharp
public void SumOfQueries() public void SumOfQueries()
{ {
QueryExpression query = new QueryExpression { QueryExpression query = new QueryExpression {
Clauses = new QueryClause[] { Clauses = {
new QueryFromClause { new QueryFromClause {
Identifier = "a", Identifier = "a",
Expression = new IdentifierExpression("b") Expression = new IdentifierExpression("b")
@ -206,7 +206,7 @@ namespace ICSharpCode.NRefactory.CSharp
public void QueryInTypeTest() public void QueryInTypeTest()
{ {
Expression expr = new QueryExpression { Expression expr = new QueryExpression {
Clauses = new QueryClause[] { Clauses = {
new QueryFromClause { new QueryFromClause {
Identifier = "a", Identifier = "a",
Expression = new IdentifierExpression("b") Expression = new IdentifierExpression("b")
@ -252,5 +252,73 @@ namespace ICSharpCode.NRefactory.CSharp
Assert.AreEqual("(++a)++", InsertRequired(expr)); Assert.AreEqual("(++a)++", InsertRequired(expr));
Assert.AreEqual("(++a)++", InsertReadable(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));
}
} }
} }

42
ICSharpCode.NRefactory/CSharp/Ast/AstComparer.cs

@ -1,42 +0,0 @@
// 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;
namespace ICSharpCode.NRefactory.CSharp
{
/// <summary>
/// Compares whether two ASTs are structurally identical.
/// </summary>
public static class AstComparer
{
static HashSet<Type> nodeTypesWithoutExtraInfo = new HashSet<Type> {
typeof(IdentifierExpression)
};
public static bool? AreEqual(AstNode node1, AstNode node2)
{
if (node1 == node2)
return true;
if (node1 == null || node1.IsNull || node2 == null || node2.IsNull)
return false;
Type nodeType = node1.GetType();
if (nodeType != node2.GetType())
return false;
if (node1.Role != node2.Role)
return false;
AstNode child1 = node1.FirstChild;
AstNode child2 = node2.FirstChild;
bool? result = true;
while (result != false && (child1 != null || child2 != null)) {
result &= AreEqual(child1, child2);
}
if (nodeTypesWithoutExtraInfo.Contains(nodeType))
return result;
if (nodeType == typeof(Identifier))
return ((Identifier)node1).Name == ((Identifier)node2).Name;
return null;
}
}
}

70
ICSharpCode.NRefactory/CSharp/Ast/AstNode.cs

@ -1,4 +1,4 @@
// //
// AstNode.cs // AstNode.cs
// //
// Author: // Author:
@ -25,11 +25,14 @@
// THE SOFTWARE. // THE SOFTWARE.
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using ICSharpCode.NRefactory.CSharp.PatternMatching;
namespace ICSharpCode.NRefactory.CSharp namespace ICSharpCode.NRefactory.CSharp
{ {
public abstract class AstNode public abstract class AstNode
@ -55,6 +58,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return default (S); return default (S);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
return other == null || other.IsNull;
}
} }
#endregion #endregion
@ -164,16 +172,9 @@ namespace ICSharpCode.NRefactory.CSharp
return role.NullObject; return role.NullObject;
} }
public IEnumerable<T> GetChildrenByRole<T>(Role<T> role) where T : AstNode public AstNodeCollection<T> GetChildrenByRole<T>(Role<T> role) where T : AstNode
{ {
AstNode next; return new AstNodeCollection<T>(this, role);
for (AstNode cur = firstChild; cur != null; cur = next) {
// Remember next before yielding cur.
// This allows removing/replacing nodes while iterating through the list.
next = cur.nextSibling;
if (cur.role == role)
yield return (T)cur;
}
} }
protected void SetChildByRole<T>(Role<T> role, T newChild) where T : AstNode protected void SetChildByRole<T>(Role<T> role, T newChild) where T : AstNode
@ -185,24 +186,6 @@ namespace ICSharpCode.NRefactory.CSharp
oldChild.ReplaceWith(newChild); oldChild.ReplaceWith(newChild);
} }
protected void SetChildrenByRole<T>(Role<T> role, IEnumerable<T> newChildren) where T : AstNode
{
// Evaluate 'newChildren' first, since it might change when we remove the old children
// Example: SetChildren(role, GetChildrenByRole(role));
if (newChildren != null)
newChildren = newChildren.ToList();
// remove old children
foreach (AstNode node in GetChildrenByRole(role))
node.Remove();
// add new children
if (newChildren != null) {
foreach (T node in newChildren) {
AddChild(node, role);
}
}
}
public void AddChild<T>(T child, Role<T> role) where T : AstNode public void AddChild<T>(T child, Role<T> role) where T : AstNode
{ {
if (role == null) if (role == null)
@ -594,6 +577,37 @@ namespace ICSharpCode.NRefactory.CSharp
public abstract S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data); public abstract S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data);
#region Pattern Matching
/// <summary>
/// Performs a pattern matching operation.
/// <c>this</c> is the pattern, <paramref name="other"/> is the AST that is being matched.
/// </summary>
/// <returns>
/// If successful, a match object containing the matched groups.
/// If the match failed, returns <c>null</c>.
/// </returns>
/// <remarks>
/// Patterns are ASTs that contain special pattern nodes (from the PatternMatching namespace).
/// However, it is also possible to match two ASTs without any pattern nodes - doing so will produce an empty match object
/// if the two ASTs are structurally identical; or will return <c>null</c> if the ASTs are not identical.
/// </remarks>
public Match Match(AstNode other)
{
Match match = new Match();
if (DoMatch(other, match))
return match;
else
return null;
}
protected static bool MatchString(string name1, string name2)
{
return string.IsNullOrEmpty(name1) || name1 == name2;
}
protected internal abstract bool DoMatch(AstNode other, Match match);
#endregion
// the Root role must be available when creating the null nodes, so we can't put it in the Roles class // the Root role must be available when creating the null nodes, so we can't put it in the Roles class
static readonly Role<AstNode> RootRole = new Role<AstNode>("Root"); static readonly Role<AstNode> RootRole = new Role<AstNode>("Root");

201
ICSharpCode.NRefactory/CSharp/Ast/AstNodeCollection.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.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using ICSharpCode.NRefactory.CSharp.PatternMatching;
namespace ICSharpCode.NRefactory.CSharp
{
/// <summary>
/// Represents the children of an AstNode that have a specific role.
/// </summary>
public class AstNodeCollection<T> : ICollection<T> where T : AstNode
{
readonly AstNode node;
readonly Role<T> role;
public AstNodeCollection(AstNode node, Role<T> role)
{
if (node == null)
throw new ArgumentNullException("node");
if (role == null)
throw new ArgumentNullException("role");
this.node = node;
this.role = role;
}
public int Count {
get {
var e = GetEnumerator();
int count = 0;
while (e.MoveNext())
count++;
return count;
}
}
public void Add(T element)
{
node.AddChild(element, role);
}
public void AddRange(IEnumerable<T> nodes)
{
// Evaluate 'nodes' first, since it might change when we add the new children
// Example: collection.AddRange(collection);
if (nodes != null) {
foreach (T node in nodes.ToList())
Add(node);
}
}
public void AddRange(T[] nodes)
{
// Fast overload for arrays - we don't need to create a copy
if (nodes != null) {
foreach (T node in nodes)
Add(node);
}
}
public void ReplaceWith(IEnumerable<T> nodes)
{
// Evaluate 'nodes' first, since it might change when we call Clear()
// Example: collection.ReplaceWith(collection);
if (nodes != null)
nodes = nodes.ToList();
Clear();
foreach (T node in nodes)
Add(node);
}
public void MoveTo(ICollection<T> targetCollection)
{
foreach (T node in this) {
node.Remove();
targetCollection.Add(node);
}
}
public bool Contains(T element)
{
return element != null && element.Parent == node && element.Role == role;
}
public bool Remove(T element)
{
if (Contains(element)) {
element.Remove();
return true;
} else {
return false;
}
}
public void CopyTo(T[] array, int arrayIndex)
{
foreach (T item in this)
array[arrayIndex++] = item;
}
public void Clear()
{
foreach (T item in this)
item.Remove();
}
bool ICollection<T>.IsReadOnly {
get { return false; }
}
public IEnumerator<T> GetEnumerator()
{
AstNode next;
for (AstNode cur = node.FirstChild; cur != null; cur = next) {
// Remember next before yielding cur.
// This allows removing/replacing nodes while iterating through the list.
next = cur.NextSibling;
if (cur.Role == role)
yield return (T)cur;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
#region Equals and GetHashCode implementation
public override bool Equals(object obj)
{
if (obj is AstNodeCollection<T>) {
return ((AstNodeCollection<T>)obj) == this;
} else {
return false;
}
}
public override int GetHashCode()
{
return node.GetHashCode() ^ role.GetHashCode();
}
public static bool operator ==(AstNodeCollection<T> left, AstNodeCollection<T> right)
{
return left.role == right.role && left.node == right.node;
}
public static bool operator !=(AstNodeCollection<T> left, AstNodeCollection<T> right)
{
return !(left.role == right.role && left.node == right.node);
}
#endregion
internal bool DoMatch(AstNodeCollection<T> other, Match match)
{
Stack<AstNode> patternStack = new Stack<AstNode>();
Stack<Pattern.PossibleMatch> stack = new Stack<Pattern.PossibleMatch>();
patternStack.Push(this.node.FirstChild);
stack.Push(new Pattern.PossibleMatch(other.node.FirstChild, match.CheckPoint()));
while (stack.Count > 0) {
AstNode cur1 = patternStack.Pop();
AstNode cur2 = stack.Peek().NextOther;
match.RestoreCheckPoint(stack.Pop().Checkpoint);
bool success = true;
while (cur1 != null && success) {
while (cur1 != null && cur1.Role != role)
cur1 = cur1.NextSibling;
while (cur2 != null && cur2.Role != role)
cur2 = cur2.NextSibling;
if (cur1 == null)
break;
Pattern pattern = cur1 as Pattern;
if (pattern == null && cur1.NodeType == NodeType.Placeholder)
pattern = cur1.GetChildByRole(TypePlaceholder.ChildRole) as Pattern;
if (pattern != null) {
Debug.Assert(stack.Count == patternStack.Count);
success = pattern.DoMatchCollection(role, cur2, match, stack);
Debug.Assert(stack.Count >= patternStack.Count);
while (stack.Count > patternStack.Count)
patternStack.Push(cur1.NextSibling);
} else {
success = cur1.DoMatch(cur2, match);
}
cur1 = cur1.NextSibling;
if (cur2 != null)
cur2 = cur2.NextSibling;
}
while (cur2 != null && cur2.Role != role)
cur2 = cur2.NextSibling;
if (success && cur2 == null)
return true;
}
return false;
}
}
}

6
ICSharpCode.NRefactory/CSharp/Ast/AstType.cs

@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
namespace ICSharpCode.NRefactory.CSharp namespace ICSharpCode.NRefactory.CSharp
{ {
@ -22,6 +23,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return default (S); return default (S);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
return other == null || other.IsNull;
}
} }
#endregion #endregion

52
ICSharpCode.NRefactory/CSharp/Ast/CSharpModifierToken.cs

@ -25,6 +25,7 @@
// THE SOFTWARE. // THE SOFTWARE.
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
namespace ICSharpCode.NRefactory.CSharp namespace ICSharpCode.NRefactory.CSharp
{ {
@ -36,33 +37,40 @@ namespace ICSharpCode.NRefactory.CSharp
public Modifiers Modifier { public Modifiers Modifier {
get { return modifier; } get { return modifier; }
set { set {
modifier = value; for (int i = 0; i < lengthTable.Count; i++) {
if (!lengthTable.TryGetValue (modifier, out tokenLength)) if (lengthTable[i].Key == value) {
throw new InvalidOperationException ("Modifier " + modifier + " is invalid."); this.modifier = value;
this.tokenLength = lengthTable[i].Value;
return;
}
}
throw new ArgumentException ("Modifier " + value + " is invalid.");
} }
} }
static Dictionary<Modifiers, int> lengthTable = new Dictionary<Modifiers, int> () { // Not worth using a dictionary for such few elements.
{ Modifiers.Public, "public".Length }, // This table is sorted in the order that modifiers should be output when generating code.
{ Modifiers.Protected, "protected".Length }, static readonly List<KeyValuePair<Modifiers, int>> lengthTable = new List<KeyValuePair<Modifiers, int>> () {
{ Modifiers.Private, "private".Length }, new KeyValuePair<Modifiers, int>(Modifiers.Public, "public".Length),
{ Modifiers.Internal, "internal".Length }, new KeyValuePair<Modifiers, int>(Modifiers.Protected, "protected".Length),
{ Modifiers.New, "new".Length }, new KeyValuePair<Modifiers, int>(Modifiers.Private, "private".Length),
{ Modifiers.Unsafe, "unsafe".Length }, new KeyValuePair<Modifiers, int>(Modifiers.Internal, "internal".Length),
{ Modifiers.Abstract, "abstract".Length }, new KeyValuePair<Modifiers, int>(Modifiers.New, "new".Length),
{ Modifiers.Virtual, "virtual".Length }, new KeyValuePair<Modifiers, int>(Modifiers.Unsafe, "unsafe".Length),
{ Modifiers.Sealed, "sealed".Length }, new KeyValuePair<Modifiers, int>(Modifiers.Abstract, "abstract".Length),
{ Modifiers.Static, "static".Length }, new KeyValuePair<Modifiers, int>(Modifiers.Virtual, "virtual".Length),
{ Modifiers.Override, "override".Length }, new KeyValuePair<Modifiers, int>(Modifiers.Sealed, "sealed".Length),
{ Modifiers.Readonly, "readonly".Length }, new KeyValuePair<Modifiers, int>(Modifiers.Static, "static".Length),
{ Modifiers.Volatile, "volatile".Length }, new KeyValuePair<Modifiers, int>(Modifiers.Override, "override".Length),
{ Modifiers.Extern, "extern".Length }, new KeyValuePair<Modifiers, int>(Modifiers.Readonly, "readonly".Length),
{ Modifiers.Partial, "partial".Length }, new KeyValuePair<Modifiers, int>(Modifiers.Volatile, "volatile".Length),
{ Modifiers.Const, "const".Length }, new KeyValuePair<Modifiers, int>(Modifiers.Extern, "extern".Length),
new KeyValuePair<Modifiers, int>(Modifiers.Partial, "partial".Length),
new KeyValuePair<Modifiers, int>(Modifiers.Const, "const".Length)
}; };
public static ICollection<Modifiers> AllModifiers { public static IEnumerable<Modifiers> AllModifiers {
get { return lengthTable.Keys; } get { return lengthTable.Select(p => p.Key); }
} }
public CSharpModifierToken (AstLocation location, Modifiers modifier) : base (location, 0) public CSharpModifierToken (AstLocation location, Modifiers modifier) : base (location, 0)

13
ICSharpCode.NRefactory/CSharp/Ast/CSharpTokenNode.cs

@ -1,4 +1,4 @@
// //
// TokenNode.cs // TokenNode.cs
// //
// Author: // Author:
@ -46,6 +46,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return default (S); return default (S);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
return other == null || other.IsNull;
}
} }
@ -80,6 +85,12 @@ namespace ICSharpCode.NRefactory.CSharp
return visitor.VisitCSharpTokenNode (this, data); return visitor.VisitCSharpTokenNode (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
CSharpTokenNode o = other as CSharpTokenNode;
return o != null;
}
public override string ToString () public override string ToString ()
{ {
return string.Format ("[CSharpTokenNode: StartLocation={0}, EndLocation={1}, Role={2}]", StartLocation, EndLocation, Role); return string.Format ("[CSharpTokenNode: StartLocation={0}, EndLocation={1}, Role={2}]", StartLocation, EndLocation, Role);

7
ICSharpCode.NRefactory/CSharp/Ast/CompilationUnit.cs

@ -42,6 +42,12 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
CompilationUnit o = other as CompilationUnit;
return o != null && GetChildrenByRole(MemberRole).DoMatch(o.GetChildrenByRole(MemberRole), match);
}
public AstNode GetNodeAt (int line, int column) public AstNode GetNodeAt (int line, int column)
{ {
return GetNodeAt (new AstLocation (line, column)); return GetNodeAt (new AstLocation (line, column));
@ -99,7 +105,6 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitCompilationUnit (this, data); return visitor.VisitCompilationUnit (this, data);
} }
} }
} }

15
ICSharpCode.NRefactory/CSharp/Ast/ComposedType.cs

@ -67,9 +67,8 @@ namespace ICSharpCode.NRefactory.CSharp
} }
} }
public IEnumerable<ArraySpecifier> ArraySpecifiers { public AstNodeCollection<ArraySpecifier> ArraySpecifiers {
get { return GetChildrenByRole (ArraySpecifierRole); } get { return GetChildrenByRole (ArraySpecifierRole); }
set { SetChildrenByRole (ArraySpecifierRole, value); }
} }
public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data) public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data)
@ -77,6 +76,12 @@ namespace ICSharpCode.NRefactory.CSharp
return visitor.VisitComposedType (this, data); return visitor.VisitComposedType (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
ComposedType o = other as ComposedType;
return o != null && this.HasNullableSpecifier == o.HasNullableSpecifier && this.PointerRank == o.PointerRank && this.ArraySpecifiers.DoMatch(o.ArraySpecifiers, match);
}
public override string ToString() public override string ToString()
{ {
StringBuilder b = new StringBuilder(); StringBuilder b = new StringBuilder();
@ -157,6 +162,12 @@ namespace ICSharpCode.NRefactory.CSharp
return visitor.VisitArraySpecifier(this, data); return visitor.VisitArraySpecifier(this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
ArraySpecifier o = other as ArraySpecifier;
return o != null && this.Dimensions == o.Dimensions;
}
public override string ToString() public override string ToString()
{ {
return "[" + new string(',', this.Dimensions - 1) + "]"; return "[" + new string(',', this.Dimensions - 1) + "]";

11
ICSharpCode.NRefactory/CSharp/Ast/Expressions/AnonymousMethodExpression.cs

@ -1,4 +1,4 @@
// //
// AnonymousMethodExpression.cs // AnonymousMethodExpression.cs
// //
// Author: // Author:
@ -47,9 +47,8 @@ namespace ICSharpCode.NRefactory.CSharp
get { return GetChildByRole (Roles.LPar); } get { return GetChildByRole (Roles.LPar); }
} }
public IEnumerable<ParameterDeclaration> Parameters { public AstNodeCollection<ParameterDeclaration> Parameters {
get { return GetChildrenByRole (Roles.Parameter); } get { return GetChildrenByRole (Roles.Parameter); }
set { SetChildrenByRole (Roles.Parameter, value); }
} }
public CSharpTokenNode RParToken { public CSharpTokenNode RParToken {
@ -65,5 +64,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitAnonymousMethodExpression (this, data); return visitor.VisitAnonymousMethodExpression (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
AnonymousMethodExpression o = other as AnonymousMethodExpression;
return o != null && this.HasParameterList == o.HasParameterList && this.Parameters.DoMatch(o.Parameters, match) && this.Body.DoMatch(o.Body, match);
}
} }
} }

11
ICSharpCode.NRefactory/CSharp/Ast/Expressions/ArgListExpression.cs

@ -1,4 +1,4 @@
// //
// ArgListExpression.cs // ArgListExpression.cs
// //
// Author: // Author:
@ -45,9 +45,8 @@ namespace ICSharpCode.NRefactory.CSharp
get { return GetChildByRole (Roles.LPar); } get { return GetChildByRole (Roles.LPar); }
} }
public IEnumerable<Expression> Arguments { public AstNodeCollection<Expression> Arguments {
get { return GetChildrenByRole(Roles.Argument); } get { return GetChildrenByRole(Roles.Argument); }
set { SetChildrenByRole(Roles.Argument, value); }
} }
public CSharpTokenNode RParToken { public CSharpTokenNode RParToken {
@ -58,6 +57,12 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitArgListExpression (this, data); return visitor.VisitArgListExpression (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
ArgListExpression o = other as ArgListExpression;
return o != null && this.IsAccess == o.IsAccess && this.Arguments.DoMatch(o.Arguments, match);
}
} }
} }

12
ICSharpCode.NRefactory/CSharp/Ast/Expressions/ArrayCreateExpression.cs

@ -16,18 +16,16 @@ namespace ICSharpCode.NRefactory.CSharp
set { SetChildByRole (Roles.Type, value); } set { SetChildByRole (Roles.Type, value); }
} }
public IEnumerable<Expression> Arguments { public AstNodeCollection<Expression> Arguments {
get { return GetChildrenByRole (Roles.Argument); } get { return GetChildrenByRole (Roles.Argument); }
set { SetChildrenByRole (Roles.Argument, value); }
} }
/// <summary> /// <summary>
/// Gets additional array ranks (those without size info). /// Gets additional array ranks (those without size info).
/// Empty for "new int[5,1]"; will contain a single element for "new int[5][]". /// Empty for "new int[5,1]"; will contain a single element for "new int[5][]".
/// </summary> /// </summary>
public IEnumerable<ArraySpecifier> AdditionalArraySpecifiers { public AstNodeCollection<ArraySpecifier> AdditionalArraySpecifiers {
get { return GetChildrenByRole(AdditionalArraySpecifierRole); } get { return GetChildrenByRole(AdditionalArraySpecifierRole); }
set { SetChildrenByRole (AdditionalArraySpecifierRole, value); }
} }
public ArrayInitializerExpression Initializer { public ArrayInitializerExpression Initializer {
@ -39,5 +37,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitArrayCreateExpression (this, data); return visitor.VisitArrayCreateExpression (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
ArrayCreateExpression o = other as ArrayCreateExpression;
return o != null && this.Type.DoMatch(o.Type, match) && this.Arguments.DoMatch(o.Arguments, match) && this.Initializer.DoMatch(o.Initializer, match);
}
} }
} }

16
ICSharpCode.NRefactory/CSharp/Ast/Expressions/ArrayInitializerExpression.cs

@ -1,4 +1,4 @@
// //
// ArrayInitializerExpression.cs // ArrayInitializerExpression.cs
// //
// Author: // Author:
@ -48,6 +48,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return default (S); return default (S);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
return other == null || other.IsNull;
}
} }
#endregion #endregion
@ -55,9 +60,8 @@ namespace ICSharpCode.NRefactory.CSharp
get { return GetChildByRole (Roles.LBrace); } get { return GetChildByRole (Roles.LBrace); }
} }
public IEnumerable<Expression> Elements { public AstNodeCollection<Expression> Elements {
get { return GetChildrenByRole(Roles.Expression); } get { return GetChildrenByRole(Roles.Expression); }
set { SetChildrenByRole(Roles.Expression, value); }
} }
public CSharpTokenNode RBraceToken { public CSharpTokenNode RBraceToken {
@ -68,6 +72,12 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitArrayInitializerExpression (this, data); return visitor.VisitArrayInitializerExpression (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
ArrayInitializerExpression o = other as ArrayInitializerExpression;
return o != null && this.Elements.DoMatch(o.Elements, match);
}
} }
} }

8
ICSharpCode.NRefactory/CSharp/Ast/Expressions/AsExpression.cs

@ -1,4 +1,4 @@
// //
// AsExpression.cs // AsExpression.cs
// //
// Author: // Author:
@ -49,6 +49,12 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitAsExpression (this, data); return visitor.VisitAsExpression (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
AsExpression o = other as AsExpression;
return o != null && this.Expression.DoMatch(o.Expression, match) && this.Type.DoMatch(o.Type, match);
}
} }
} }

12
ICSharpCode.NRefactory/CSharp/Ast/Expressions/AssignmentExpression.cs

@ -1,4 +1,4 @@
// //
// AssignmentExpression.cs // AssignmentExpression.cs
// //
// Author: // Author:
@ -72,6 +72,13 @@ namespace ICSharpCode.NRefactory.CSharp
return visitor.VisitAssignmentExpression (this, data); return visitor.VisitAssignmentExpression (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
AssignmentExpression o = other as AssignmentExpression;
return o != null && (this.Operator == AssignmentOperatorType.Any || this.Operator == o.Operator)
&& this.Left.DoMatch(o.Left, match) && this.Right.DoMatch(o.Right, match);
}
public static string GetOperatorSymbol(AssignmentOperatorType op) public static string GetOperatorSymbol(AssignmentOperatorType op)
{ {
switch (op) { switch (op) {
@ -130,5 +137,8 @@ namespace ICSharpCode.NRefactory.CSharp
BitwiseOr, BitwiseOr,
/// <summary>left ^= right</summary> /// <summary>left ^= right</summary>
ExclusiveOr, ExclusiveOr,
/// <summary>Any operator (for pattern matching)</summary>
Any
} }
} }

8
ICSharpCode.NRefactory/CSharp/Ast/Expressions/BaseReferenceExpression.cs

@ -1,4 +1,4 @@
// //
// BaseReferenceExpression.cs // BaseReferenceExpression.cs
// //
// Author: // Author:
@ -51,5 +51,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitBaseReferenceExpression (this, data); return visitor.VisitBaseReferenceExpression (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
BaseReferenceExpression o = other as BaseReferenceExpression;
return o != null;
}
} }
} }

18
ICSharpCode.NRefactory/CSharp/Ast/Expressions/BinaryOperatorExpression.cs

@ -1,6 +1,6 @@
// //
// BinaryOperatorExpression.cs // BinaryOperatorExpression.cs
// //
// Author: // Author:
// Mike Krüger <mkrueger@novell.com> // Mike Krüger <mkrueger@novell.com>
// //
@ -72,6 +72,13 @@ namespace ICSharpCode.NRefactory.CSharp
return visitor.VisitBinaryOperatorExpression (this, data); return visitor.VisitBinaryOperatorExpression (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
BinaryOperatorExpression o = other as BinaryOperatorExpression;
return o != null && (this.Operator == BinaryOperatorType.Any || this.Operator == o.Operator)
&& this.Left.DoMatch(o.Left, match) && this.Right.DoMatch(o.Right, match);
}
public static string GetOperatorSymbol(BinaryOperatorType op) public static string GetOperatorSymbol(BinaryOperatorType op)
{ {
switch (op) { switch (op) {
@ -167,6 +174,11 @@ namespace ICSharpCode.NRefactory.CSharp
ShiftRight, ShiftRight,
/// <summary>left ?? right</summary> /// <summary>left ?? right</summary>
NullCoalescing NullCoalescing,
/// <summary>
/// Any binary operator (used in pattern matching)
/// </summary>
Any
} }
} }

8
ICSharpCode.NRefactory/CSharp/Ast/Expressions/CastExpression.cs

@ -1,4 +1,4 @@
// //
// CastExpression.cs // CastExpression.cs
// //
// Author: // Author:
@ -53,6 +53,12 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitCastExpression (this, data); return visitor.VisitCastExpression (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
CastExpression o = other as CastExpression;
return o != null && this.Type.DoMatch(o.Type, match) && this.Expression.DoMatch(o.Expression, match);
}
} }
} }

8
ICSharpCode.NRefactory/CSharp/Ast/Expressions/CheckedExpression.cs

@ -1,4 +1,4 @@
// //
// CheckedExpression.cs // CheckedExpression.cs
// //
// Author: // Author:
@ -52,5 +52,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitCheckedExpression (this, data); return visitor.VisitCheckedExpression (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
CheckedExpression o = other as CheckedExpression;
return o != null && this.Expression.DoMatch(o.Expression, match);
}
} }
} }

8
ICSharpCode.NRefactory/CSharp/Ast/Expressions/ConditionalExpression.cs

@ -1,4 +1,4 @@
// //
// ConditionalExpression.cs // ConditionalExpression.cs
// //
// Author: // Author:
@ -64,5 +64,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitConditionalExpression (this, data); return visitor.VisitConditionalExpression (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
ConditionalExpression o = other as ConditionalExpression;
return o != null && this.Condition.DoMatch(o.Condition, match) && this.TrueExpression.DoMatch(o.TrueExpression, match) && this.FalseExpression.DoMatch(o.FalseExpression, match);
}
} }
} }

8
ICSharpCode.NRefactory/CSharp/Ast/Expressions/DefaultValueExpression.cs

@ -1,4 +1,4 @@
// //
// DefaultValueExpression.cs // DefaultValueExpression.cs
// //
// Author: // Author:
@ -52,6 +52,12 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitDefaultValueExpression (this, data); return visitor.VisitDefaultValueExpression (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
DefaultValueExpression o = other as DefaultValueExpression;
return o != null && this.Type.DoMatch(o.Type, match);
}
} }
} }

8
ICSharpCode.NRefactory/CSharp/Ast/Expressions/DirectionExpression.cs

@ -1,4 +1,4 @@
// //
// DirectionExpression.cs // DirectionExpression.cs
// //
// Author: // Author:
@ -56,5 +56,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitDirectionExpression (this, data); return visitor.VisitDirectionExpression (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
DirectionExpression o = other as DirectionExpression;
return o != null && this.FieldDirection == o.FieldDirection && this.Expression.DoMatch(o.Expression, match);
}
} }
} }

53
ICSharpCode.NRefactory/CSharp/Ast/Expressions/Expression.cs

@ -3,6 +3,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Linq; using System.Linq;
namespace ICSharpCode.NRefactory.CSharp namespace ICSharpCode.NRefactory.CSharp
@ -31,6 +32,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return default (S); return default (S);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
return other == null || other.IsNull;
}
} }
#endregion #endregion
@ -45,6 +51,14 @@ namespace ICSharpCode.NRefactory.CSharp
return (Expression)base.Clone(); return (Expression)base.Clone();
} }
// Make debugging easier by giving Expressions a ToString() implementation
public override string ToString()
{
StringWriter w = new StringWriter();
AcceptVisitor(new OutputVisitor(w, new CSharpFormattingPolicy()), null);
return w.ToString();
}
public Expression ReplaceWith(Func<Expression, Expression> replaceFunction) public Expression ReplaceWith(Func<Expression, Expression> replaceFunction)
{ {
if (replaceFunction == null) if (replaceFunction == null)
@ -66,7 +80,10 @@ namespace ICSharpCode.NRefactory.CSharp
/// </summary> /// </summary>
public IndexerExpression Indexer(IEnumerable<Expression> arguments) public IndexerExpression Indexer(IEnumerable<Expression> arguments)
{ {
return new IndexerExpression { Target = this, Arguments = arguments }; IndexerExpression expr = new IndexerExpression();
expr.Target = this;
expr.Arguments.AddRange(arguments);
return expr;
} }
/// <summary> /// <summary>
@ -74,7 +91,10 @@ namespace ICSharpCode.NRefactory.CSharp
/// </summary> /// </summary>
public IndexerExpression Indexer(params Expression[] arguments) public IndexerExpression Indexer(params Expression[] arguments)
{ {
return new IndexerExpression { Target = this, Arguments = arguments }; IndexerExpression expr = new IndexerExpression();
expr.Target = this;
expr.Arguments.AddRange(arguments);
return expr;
} }
/// <summary> /// <summary>
@ -98,14 +118,14 @@ namespace ICSharpCode.NRefactory.CSharp
/// </summary> /// </summary>
public InvocationExpression Invoke(string methodName, IEnumerable<AstType> typeArguments, IEnumerable<Expression> arguments) public InvocationExpression Invoke(string methodName, IEnumerable<AstType> typeArguments, IEnumerable<Expression> arguments)
{ {
return new InvocationExpression { InvocationExpression ie = new InvocationExpression();
Target = new MemberReferenceExpression { MemberReferenceExpression mre = new MemberReferenceExpression();
Target = this, mre.Target = this;
MemberName = methodName, mre.MemberName = methodName;
TypeArguments = typeArguments mre.TypeArguments.AddRange(typeArguments);
}, ie.Target = mre;
Arguments = arguments ie.Arguments.AddRange(arguments);
}; return ie;
} }
/// <summary> /// <summary>
@ -113,10 +133,10 @@ namespace ICSharpCode.NRefactory.CSharp
/// </summary> /// </summary>
public InvocationExpression Invoke(IEnumerable<Expression> arguments) public InvocationExpression Invoke(IEnumerable<Expression> arguments)
{ {
return new InvocationExpression { InvocationExpression ie = new InvocationExpression();
Target = this, ie.Target = this;
Arguments = arguments ie.Arguments.AddRange(arguments);
}; return ie;
} }
/// <summary> /// <summary>
@ -124,7 +144,10 @@ namespace ICSharpCode.NRefactory.CSharp
/// </summary> /// </summary>
public InvocationExpression Invoke(params Expression[] arguments) public InvocationExpression Invoke(params Expression[] arguments)
{ {
return Invoke(arguments.AsEnumerable()); InvocationExpression ie = new InvocationExpression();
ie.Target = this;
ie.Arguments.AddRange(arguments);
return ie;
} }
public CastExpression CastTo(AstType type) public CastExpression CastTo(AstType type)

11
ICSharpCode.NRefactory/CSharp/Ast/Expressions/IdentifierExpression.cs

@ -1,4 +1,4 @@
// //
// IdentifierExpression.cs // IdentifierExpression.cs
// //
// Author: // Author:
@ -56,14 +56,19 @@ namespace ICSharpCode.NRefactory.CSharp
} }
} }
public IEnumerable<AstType> TypeArguments { public AstNodeCollection<AstType> TypeArguments {
get { return GetChildrenByRole (Roles.TypeArgument); } get { return GetChildrenByRole (Roles.TypeArgument); }
set { SetChildrenByRole (Roles.TypeArgument, value); }
} }
public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data) public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data)
{ {
return visitor.VisitIdentifierExpression (this, data); return visitor.VisitIdentifierExpression (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
IdentifierExpression o = other as IdentifierExpression;
return o != null && MatchString(this.Identifier, o.Identifier) && this.TypeArguments.DoMatch(o.TypeArguments, match);
}
} }
} }

11
ICSharpCode.NRefactory/CSharp/Ast/Expressions/IndexerExpression.cs

@ -1,4 +1,4 @@
// //
// IndexerExpression.cs // IndexerExpression.cs
// //
// Author: // Author:
@ -42,9 +42,8 @@ namespace ICSharpCode.NRefactory.CSharp
get { return GetChildByRole (Roles.LBracket); } get { return GetChildByRole (Roles.LBracket); }
} }
public IEnumerable<Expression> Arguments { public AstNodeCollection<Expression> Arguments {
get { return GetChildrenByRole<Expression>(Roles.Argument); } get { return GetChildrenByRole<Expression>(Roles.Argument); }
set { SetChildrenByRole(Roles.Argument, value); }
} }
public CSharpTokenNode RBracketToken { public CSharpTokenNode RBracketToken {
@ -55,5 +54,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitIndexerExpression (this, data); return visitor.VisitIndexerExpression (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
IndexerExpression o = other as IndexerExpression;
return o != null && this.Target.DoMatch(o.Target, match) && this.Arguments.DoMatch(o.Arguments, match);
}
} }
} }

11
ICSharpCode.NRefactory/CSharp/Ast/Expressions/InvocationExpression.cs

@ -1,4 +1,4 @@
// //
// InvocationExpression.cs // InvocationExpression.cs
// //
// Author: // Author:
@ -42,9 +42,8 @@ namespace ICSharpCode.NRefactory.CSharp
get { return GetChildByRole (Roles.LPar); } get { return GetChildByRole (Roles.LPar); }
} }
public IEnumerable<Expression> Arguments { public AstNodeCollection<Expression> Arguments {
get { return GetChildrenByRole<Expression>(Roles.Argument); } get { return GetChildrenByRole<Expression>(Roles.Argument); }
set { SetChildrenByRole(Roles.Argument, value); }
} }
public CSharpTokenNode RParToken { public CSharpTokenNode RParToken {
@ -55,5 +54,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitInvocationExpression (this, data); return visitor.VisitInvocationExpression (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
InvocationExpression o = other as InvocationExpression;
return o != null && this.Target.DoMatch(o.Target, match) && this.Arguments.DoMatch(o.Arguments, match);
}
} }
} }

8
ICSharpCode.NRefactory/CSharp/Ast/Expressions/IsExpression.cs

@ -1,4 +1,4 @@
// //
// TypeOfIsExpression.cs // TypeOfIsExpression.cs
// //
// Author: // Author:
@ -49,6 +49,12 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitIsExpression (this, data); return visitor.VisitIsExpression (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
IsExpression o = other as IsExpression;
return o != null && this.Expression.DoMatch(o.Expression, match) && this.Type.DoMatch(o.Type, match);
}
} }
} }

11
ICSharpCode.NRefactory/CSharp/Ast/Expressions/LambdaExpression.cs

@ -1,4 +1,4 @@
// //
// LambdaExpression.cs // LambdaExpression.cs
// //
// Author: // Author:
@ -36,9 +36,8 @@ namespace ICSharpCode.NRefactory.CSharp
public readonly static Role<CSharpTokenNode> ArrowRole = new Role<CSharpTokenNode>("Arrow", CSharpTokenNode.Null); public readonly static Role<CSharpTokenNode> ArrowRole = new Role<CSharpTokenNode>("Arrow", CSharpTokenNode.Null);
public static readonly Role<AstNode> BodyRole = new Role<AstNode>("Body", AstNode.Null); public static readonly Role<AstNode> BodyRole = new Role<AstNode>("Body", AstNode.Null);
public IEnumerable<ParameterDeclaration> Parameters { public AstNodeCollection<ParameterDeclaration> Parameters {
get { return GetChildrenByRole (Roles.Parameter); } get { return GetChildrenByRole (Roles.Parameter); }
set { SetChildrenByRole (Roles.Parameter, value); }
} }
public CSharpTokenNode ArrowToken { public CSharpTokenNode ArrowToken {
@ -54,5 +53,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitLambdaExpression (this, data); return visitor.VisitLambdaExpression (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
LambdaExpression o = other as LambdaExpression;
return o != null && this.Parameters.DoMatch(o.Parameters, match) && this.Body.DoMatch(o.Body, match);
}
} }
} }

11
ICSharpCode.NRefactory/CSharp/Ast/Expressions/MemberReferenceExpression.cs

@ -1,4 +1,4 @@
// //
// MemberReferenceExpression.cs // MemberReferenceExpression.cs
// //
// Author: // Author:
@ -51,9 +51,8 @@ namespace ICSharpCode.NRefactory.CSharp
get { return GetChildByRole (Roles.LChevron); } get { return GetChildByRole (Roles.LChevron); }
} }
public IEnumerable<AstType> TypeArguments { public AstNodeCollection<AstType> TypeArguments {
get { return GetChildrenByRole (Roles.TypeArgument); } get { return GetChildrenByRole (Roles.TypeArgument); }
set { SetChildrenByRole (Roles.TypeArgument, value); }
} }
public CSharpTokenNode RChevronToken { public CSharpTokenNode RChevronToken {
@ -64,5 +63,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitMemberReferenceExpression (this, data); return visitor.VisitMemberReferenceExpression (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
MemberReferenceExpression o = other as MemberReferenceExpression;
return o != null && this.Target.DoMatch(o.Target, match) && MatchString(this.MemberName, o.MemberName) && this.TypeArguments.DoMatch(o.TypeArguments, match);
}
} }
} }

6
ICSharpCode.NRefactory/CSharp/Ast/Expressions/NamedArgumentExpression.cs

@ -28,5 +28,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitNamedArgumentExpression(this, data); return visitor.VisitNamedArgumentExpression(this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
NamedArgumentExpression o = other as NamedArgumentExpression;
return o != null && MatchString(this.Identifier, o.Identifier) && this.Expression.DoMatch(o.Expression, match);
}
} }
} }

8
ICSharpCode.NRefactory/CSharp/Ast/Expressions/NullReferenceExpression.cs

@ -1,4 +1,4 @@
// //
// NullReferenceExpression.cs // NullReferenceExpression.cs
// //
// Author: // Author:
@ -35,5 +35,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitNullReferenceExpression (this, data); return visitor.VisitNullReferenceExpression (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
NullReferenceExpression o = other as NullReferenceExpression;
return o != null;
}
} }
} }

11
ICSharpCode.NRefactory/CSharp/Ast/Expressions/ObjectCreateExpression.cs

@ -1,4 +1,4 @@
// //
// ObjectCreateExpression.cs // ObjectCreateExpression.cs
// //
// Author: // Author:
@ -48,9 +48,8 @@ namespace ICSharpCode.NRefactory.CSharp
get { return GetChildByRole (Roles.LPar); } get { return GetChildByRole (Roles.LPar); }
} }
public IEnumerable<Expression> Arguments { public AstNodeCollection<Expression> Arguments {
get { return GetChildrenByRole (Roles.Argument); } get { return GetChildrenByRole (Roles.Argument); }
set { SetChildrenByRole (Roles.Argument, value); }
} }
public CSharpTokenNode RParToken { public CSharpTokenNode RParToken {
@ -66,5 +65,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitObjectCreateExpression (this, data); return visitor.VisitObjectCreateExpression (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
ObjectCreateExpression o = other as ObjectCreateExpression;
return o != null && this.Type.DoMatch(o.Type, match) && this.Arguments.DoMatch(o.Arguments, match) && this.Initializer.DoMatch(o.Initializer, match);
}
} }
} }

8
ICSharpCode.NRefactory/CSharp/Ast/Expressions/ParenthesizedExpression.cs

@ -1,4 +1,4 @@
// //
// ParenthesizedExpression.cs // ParenthesizedExpression.cs
// //
// Author: // Author:
@ -48,5 +48,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitParenthesizedExpression (this, data); return visitor.VisitParenthesizedExpression (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
ParenthesizedExpression o = other as ParenthesizedExpression;
return o != null && this.Expression.DoMatch(o.Expression, match);
}
} }
} }

11
ICSharpCode.NRefactory/CSharp/Ast/Expressions/PointerReferenceExpression.cs

@ -1,4 +1,4 @@
// //
// PointerReferenceExpression.cs // PointerReferenceExpression.cs
// //
// Author: // Author:
@ -49,14 +49,19 @@ namespace ICSharpCode.NRefactory.CSharp
} }
} }
public IEnumerable<AstType> TypeArguments { public AstNodeCollection<AstType> TypeArguments {
get { return GetChildrenByRole (Roles.TypeArgument); } get { return GetChildrenByRole (Roles.TypeArgument); }
set { SetChildrenByRole (Roles.TypeArgument, value); }
} }
public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data) public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data)
{ {
return visitor.VisitPointerReferenceExpression (this, data); return visitor.VisitPointerReferenceExpression (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
PointerReferenceExpression o = other as PointerReferenceExpression;
return o != null && MatchString(this.MemberName, o.MemberName) && this.TypeArguments.DoMatch(o.TypeArguments, match);
}
} }
} }

10
ICSharpCode.NRefactory/CSharp/Ast/Expressions/PrimitiveExpression.cs

@ -1,4 +1,4 @@
// //
// PrimitiveExpression.cs // PrimitiveExpression.cs
// //
// Author: // Author:
@ -31,6 +31,8 @@ namespace ICSharpCode.NRefactory.CSharp
/// </summary> /// </summary>
public class PrimitiveExpression : Expression public class PrimitiveExpression : Expression
{ {
public static readonly object AnyValue = new object();
AstLocation startLocation; AstLocation startLocation;
public override AstLocation StartLocation { public override AstLocation StartLocation {
get { get {
@ -66,5 +68,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitPrimitiveExpression (this, data); return visitor.VisitPrimitiveExpression (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
PrimitiveExpression o = other as PrimitiveExpression;
return o != null && (this.Value == AnyValue || object.Equals(this.Value, o.Value));
}
} }
} }

29
ICSharpCode.NRefactory/CSharp/Ast/Expressions/QueryExpression.cs

@ -25,18 +25,28 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return default (S); return default (S);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
return other == null || other.IsNull;
}
} }
#endregion #endregion
public IEnumerable<QueryClause> Clauses { public AstNodeCollection<QueryClause> Clauses {
get { return GetChildrenByRole(ClauseRole); } get { return GetChildrenByRole(ClauseRole); }
set { SetChildrenByRole(ClauseRole, value); }
} }
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data) public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{ {
return visitor.VisitQueryExpression (this, data); return visitor.VisitQueryExpression (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
QueryExpression o = other as QueryExpression;
return o != null && this.Clauses.DoMatch(o.Clauses, match);
}
} }
public abstract class QueryClause : AstNode public abstract class QueryClause : AstNode
@ -44,6 +54,12 @@ namespace ICSharpCode.NRefactory.CSharp
public override NodeType NodeType { public override NodeType NodeType {
get { return NodeType.QueryClause; } get { return NodeType.QueryClause; }
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
QueryClause o = other as QueryClause;
throw new NotImplementedException();
}
} }
/// <summary> /// <summary>
@ -260,9 +276,8 @@ namespace ICSharpCode.NRefactory.CSharp
get { return GetChildByRole (Roles.Keyword); } get { return GetChildByRole (Roles.Keyword); }
} }
public IEnumerable<QueryOrdering> Orderings { public AstNodeCollection<QueryOrdering> Orderings {
get { return GetChildrenByRole (OrderingRole); } get { return GetChildrenByRole (OrderingRole); }
set { SetChildrenByRole (OrderingRole, value); }
} }
public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data) public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data)
@ -295,6 +310,12 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitQueryOrdering (this, data); return visitor.VisitQueryOrdering (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
QueryOrdering o = other as QueryOrdering;
return o != null && this.Direction == o.Direction && this.Expression.DoMatch(o.Expression, match);
}
} }
public enum QueryOrderingDirection public enum QueryOrderingDirection

8
ICSharpCode.NRefactory/CSharp/Ast/Expressions/SizeOfExpression.cs

@ -1,4 +1,4 @@
// //
// SizeOfExpression.cs // SizeOfExpression.cs
// //
// Author: // Author:
@ -52,5 +52,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitSizeOfExpression (this, data); return visitor.VisitSizeOfExpression (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
SizeOfExpression o = other as SizeOfExpression;
return o != null && this.Type.DoMatch(o.Type, match);
}
} }
} }

8
ICSharpCode.NRefactory/CSharp/Ast/Expressions/StackAllocExpression.cs

@ -1,4 +1,4 @@
// //
// StackAllocExpression.cs // StackAllocExpression.cs
// //
// Author: // Author:
@ -57,5 +57,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitStackAllocExpression (this, data); return visitor.VisitStackAllocExpression (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
StackAllocExpression o = other as StackAllocExpression;
return o != null && this.Type.DoMatch(o.Type, match) && this.CountExpression.DoMatch(o.CountExpression, match);
}
} }
} }

8
ICSharpCode.NRefactory/CSharp/Ast/Expressions/ThisReferenceExpression.cs

@ -1,4 +1,4 @@
// //
// ThisReferenceExpression.cs // ThisReferenceExpression.cs
// //
// Author: // Author:
@ -51,5 +51,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitThisReferenceExpression (this, data); return visitor.VisitThisReferenceExpression (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
ThisReferenceExpression o = other as ThisReferenceExpression;
return o != null;
}
} }
} }

8
ICSharpCode.NRefactory/CSharp/Ast/Expressions/TypeOfExpression.cs

@ -1,4 +1,4 @@
// //
// TypeOfExpression.cs // TypeOfExpression.cs
// //
// Author: // Author:
@ -53,5 +53,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitTypeOfExpression (this, data); return visitor.VisitTypeOfExpression (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
TypeOfExpression o = other as TypeOfExpression;
return o != null && this.Type.DoMatch(o.Type, match);
}
} }
} }

8
ICSharpCode.NRefactory/CSharp/Ast/Expressions/TypeReferenceExpression.cs

@ -1,4 +1,4 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) // 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) // This code is distributed under MIT X11 license (for details please see \doc\license.txt)
using System; using System;
@ -20,5 +20,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitTypeReferenceExpression(this, data); return visitor.VisitTypeReferenceExpression(this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
TypeReferenceExpression o = other as TypeReferenceExpression;
return o != null && this.Type.DoMatch(o.Type, match);
}
} }
} }

8
ICSharpCode.NRefactory/CSharp/Ast/Expressions/UnaryOperatorExpression.cs

@ -1,4 +1,4 @@
// //
// UnaryOperatorExpression.cs // UnaryOperatorExpression.cs
// //
// Author: // Author:
@ -64,6 +64,12 @@ namespace ICSharpCode.NRefactory.CSharp
return visitor.VisitUnaryOperatorExpression (this, data); return visitor.VisitUnaryOperatorExpression (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
UnaryOperatorExpression o = other as UnaryOperatorExpression;
return o != null && this.Operator == o.Operator && this.Expression.DoMatch(o.Expression, match);
}
public static string GetOperatorSymbol(UnaryOperatorType op) public static string GetOperatorSymbol(UnaryOperatorType op)
{ {
switch (op) { switch (op) {

8
ICSharpCode.NRefactory/CSharp/Ast/Expressions/UncheckedExpression.cs

@ -1,4 +1,4 @@
// //
// UncheckedExpression.cs // UncheckedExpression.cs
// //
// Author: // Author:
@ -52,5 +52,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitUncheckedExpression (this, data); return visitor.VisitUncheckedExpression (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
UncheckedExpression o = other as UncheckedExpression;
return o != null && this.Expression.DoMatch(o.Expression, match);
}
} }
} }

11
ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/Attribute.cs

@ -1,4 +1,4 @@
// //
// Attribute.cs // Attribute.cs
// //
// Author: // Author:
@ -44,14 +44,19 @@ namespace ICSharpCode.NRefactory.CSharp
set { SetChildByRole (Roles.Type, value); } set { SetChildByRole (Roles.Type, value); }
} }
public IEnumerable<Expression> Arguments { public AstNodeCollection<Expression> Arguments {
get { return base.GetChildrenByRole (Roles.Argument); } get { return base.GetChildrenByRole (Roles.Argument); }
set { SetChildrenByRole (Roles.Argument, value); }
} }
public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data) public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data)
{ {
return visitor.VisitAttribute (this, data); return visitor.VisitAttribute (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
Attribute o = other as Attribute;
return o != null && this.Type.DoMatch(o.Type, match) && this.Arguments.DoMatch(o.Arguments, match);
}
} }
} }

11
ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/AttributeSection.cs

@ -1,4 +1,4 @@
// //
// AttributeSection.cs // AttributeSection.cs
// //
// Author: // Author:
@ -49,9 +49,8 @@ namespace ICSharpCode.NRefactory.CSharp
set; set;
} }
public IEnumerable<Attribute> Attributes { public AstNodeCollection<Attribute> Attributes {
get { return base.GetChildrenByRole (AttributeRole); } get { return base.GetChildrenByRole (AttributeRole); }
set { SetChildrenByRole (AttributeRole, value); }
} }
public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data) public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data)
@ -59,6 +58,12 @@ namespace ICSharpCode.NRefactory.CSharp
return visitor.VisitAttributeSection (this, data); return visitor.VisitAttributeSection (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
AttributeSection o = other as AttributeSection;
return o != null && this.AttributeTarget == o.AttributeTarget && this.Attributes.DoMatch(o.Attributes, match);
}
public static string GetAttributeTargetName(AttributeTarget attributeTarget) public static string GetAttributeTargetName(AttributeTarget attributeTarget)
{ {
switch (attributeTarget) { switch (attributeTarget) {

8
ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/Comment.cs

@ -1,4 +1,4 @@
// //
// Comment.cs // Comment.cs
// //
// Author: // Author:
@ -86,6 +86,12 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitComment (this, data); return visitor.VisitComment (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
Comment o = other as Comment;
return o != null && this.CommentType == o.CommentType && MatchString(this.Content, o.Content);
}
} }
} }

11
ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/Constraint.cs

@ -1,4 +1,4 @@
// //
// Constraint.cs // Constraint.cs
// //
// Author: // Author:
@ -53,15 +53,20 @@ namespace ICSharpCode.NRefactory.CSharp
// TODO: what about new(), struct and class constraints? // TODO: what about new(), struct and class constraints?
public IEnumerable<AstType> BaseTypes { public AstNodeCollection<AstType> BaseTypes {
get { return GetChildrenByRole (BaseTypeRole); } get { return GetChildrenByRole (BaseTypeRole); }
set { SetChildrenByRole (BaseTypeRole, value); }
} }
public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data) public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data)
{ {
return visitor.VisitConstraint (this, data); return visitor.VisitConstraint (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
Constraint o = other as Constraint;
return o != null && MatchString(this.TypeParameter, o.TypeParameter) && this.BaseTypes.DoMatch(o.BaseTypes, match);
}
} }
} }

11
ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/DelegateDeclaration.cs

@ -1,4 +1,4 @@
// //
// DelegateDeclaration.cs // DelegateDeclaration.cs
// //
// Author: // Author:
@ -54,27 +54,24 @@ namespace ICSharpCode.NRefactory.CSharp
set { SetChildByRole (Roles.Type, value); } set { SetChildByRole (Roles.Type, value); }
} }
public IEnumerable<TypeParameterDeclaration> TypeParameters { public AstNodeCollection<TypeParameterDeclaration> TypeParameters {
get { return GetChildrenByRole (Roles.TypeParameter); } get { return GetChildrenByRole (Roles.TypeParameter); }
set { SetChildrenByRole (Roles.TypeParameter, value); }
} }
public CSharpTokenNode LParToken { public CSharpTokenNode LParToken {
get { return GetChildByRole (Roles.LPar); } get { return GetChildByRole (Roles.LPar); }
} }
public IEnumerable<ParameterDeclaration> Parameters { public AstNodeCollection<ParameterDeclaration> Parameters {
get { return GetChildrenByRole (Roles.Parameter); } get { return GetChildrenByRole (Roles.Parameter); }
set { SetChildrenByRole (Roles.Parameter, value); }
} }
public CSharpTokenNode RParToken { public CSharpTokenNode RParToken {
get { return GetChildByRole (Roles.RPar); } get { return GetChildByRole (Roles.RPar); }
} }
public IEnumerable<Constraint> Constraints { public AstNodeCollection<Constraint> Constraints {
get { return GetChildrenByRole (Roles.Constraint); } get { return GetChildrenByRole (Roles.Constraint); }
set { SetChildrenByRole (Roles.Constraint, value); }
} }
public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data) public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data)

16
ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/NamespaceDeclaration.cs

@ -1,4 +1,4 @@
// //
// NamespaceDeclaration.cs // NamespaceDeclaration.cs
// //
// Author: // Author:
@ -54,13 +54,12 @@ namespace ICSharpCode.NRefactory.CSharp
return builder.ToString (); return builder.ToString ();
} }
set { set {
SetChildrenByRole (Roles.Identifier, value.Split('.').Select(ident => new Identifier(ident, AstLocation.Empty))); GetChildrenByRole(Roles.Identifier).ReplaceWith(value.Split('.').Select(ident => new Identifier(ident, AstLocation.Empty)));
} }
} }
public IEnumerable<Identifier> Identifiers { public AstNodeCollection<Identifier> Identifiers {
get { return GetChildrenByRole (Roles.Identifier); } get { return GetChildrenByRole (Roles.Identifier); }
set { SetChildrenByRole (Roles.Identifier, value); }
} }
/// <summary> /// <summary>
@ -79,9 +78,8 @@ namespace ICSharpCode.NRefactory.CSharp
get { return GetChildByRole (Roles.LBrace); } get { return GetChildByRole (Roles.LBrace); }
} }
public IEnumerable<AstNode> Members { public AstNodeCollection<AstNode> Members {
get { return GetChildrenByRole(MemberRole); } get { return GetChildrenByRole(MemberRole); }
set { SetChildrenByRole(MemberRole, value); }
} }
public CSharpTokenNode RBraceToken { public CSharpTokenNode RBraceToken {
@ -102,5 +100,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitNamespaceDeclaration (this, data); return visitor.VisitNamespaceDeclaration (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
NamespaceDeclaration o = other as NamespaceDeclaration;
return o != null && MatchString(this.Name, o.Name) && this.Members.DoMatch(o.Members, match);
}
} }
}; };

14
ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/TypeDeclaration.cs

@ -1,4 +1,4 @@
// //
// TypeDeclaration.cs // TypeDeclaration.cs
// //
// Author: // Author:
@ -59,28 +59,24 @@ namespace ICSharpCode.NRefactory.CSharp
} }
} }
public IEnumerable<TypeParameterDeclaration> TypeParameters { public AstNodeCollection<TypeParameterDeclaration> TypeParameters {
get { return GetChildrenByRole (Roles.TypeParameter); } get { return GetChildrenByRole (Roles.TypeParameter); }
set { SetChildrenByRole (Roles.TypeParameter, value); }
} }
public IEnumerable<AstType> BaseTypes { public AstNodeCollection<AstType> BaseTypes {
get { return GetChildrenByRole (BaseTypeRole); } get { return GetChildrenByRole (BaseTypeRole); }
set { SetChildrenByRole (BaseTypeRole, value); }
} }
public IEnumerable<Constraint> Constraints { public AstNodeCollection<Constraint> Constraints {
get { return GetChildrenByRole (Roles.Constraint); } get { return GetChildrenByRole (Roles.Constraint); }
set { SetChildrenByRole (Roles.Constraint, value); }
} }
public CSharpTokenNode LBraceToken { public CSharpTokenNode LBraceToken {
get { return GetChildByRole (Roles.LBrace); } get { return GetChildByRole (Roles.LBrace); }
} }
public IEnumerable<AttributedNode> Members { public AstNodeCollection<AttributedNode> Members {
get { return GetChildrenByRole (MemberRole); } get { return GetChildrenByRole (MemberRole); }
set { SetChildrenByRole (MemberRole, value); }
} }
public CSharpTokenNode RBraceToken { public CSharpTokenNode RBraceToken {

6
ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/TypeParameterDeclaration.cs

@ -38,5 +38,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitTypeParameterDeclaration(this, data); return visitor.VisitTypeParameterDeclaration(this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
TypeParameterDeclaration o = other as TypeParameterDeclaration;
return o != null && this.Variance == o.Variance && MatchString(this.Name, o.Name);
}
} }
} }

8
ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/UsingAliasDeclaration.cs

@ -1,4 +1,4 @@
// //
// UsingAliasDeclaration.cs // UsingAliasDeclaration.cs
// //
// Author: // Author:
@ -70,5 +70,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitUsingAliasDeclaration (this, data); return visitor.VisitUsingAliasDeclaration (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
UsingAliasDeclaration o = other as UsingAliasDeclaration;
return o != null && MatchString(this.Alias, o.Alias) && this.Import.DoMatch(o.Import, match);
}
} }
} }

8
ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/UsingDeclaration.cs

@ -1,4 +1,4 @@
// //
// UsingDeclaration.cs // UsingDeclaration.cs
// //
// Author: // Author:
@ -64,5 +64,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitUsingDeclaration (this, data); return visitor.VisitUsingDeclaration (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
UsingDeclaration o = other as UsingDeclaration;
return o != null && this.Import.DoMatch(o.Import, match);
}
} }
} }

8
ICSharpCode.NRefactory/CSharp/Ast/Identifier.cs

@ -1,4 +1,4 @@
// //
// Identifier.cs // Identifier.cs
// //
// Author: // Author:
@ -91,5 +91,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitIdentifier (this, data); return visitor.VisitIdentifier (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
Identifier o = other as Identifier;
return o != null && MatchString(this.Name, o.Name);
}
} }
} }

11
ICSharpCode.NRefactory/CSharp/Ast/MemberType.cs

@ -1,4 +1,4 @@
// //
// FullTypeName.cs // FullTypeName.cs
// //
// Author: // Author:
@ -51,9 +51,8 @@ namespace ICSharpCode.NRefactory.CSharp
} }
} }
public IEnumerable<AstType> TypeArguments { public AstNodeCollection<AstType> TypeArguments {
get { return GetChildrenByRole (Roles.TypeArgument); } get { return GetChildrenByRole (Roles.TypeArgument); }
set { SetChildrenByRole (Roles.TypeArgument, value); }
} }
public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data) public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data)
@ -61,6 +60,12 @@ namespace ICSharpCode.NRefactory.CSharp
return visitor.VisitMemberType (this, data); return visitor.VisitMemberType (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
MemberType o = other as MemberType;
return o != null && this.IsDoubleColon == o.IsDoubleColon && MatchString(this.MemberName, o.MemberName) && this.Target.DoMatch(o.Target, match);
}
public override string ToString() public override string ToString()
{ {
StringBuilder b = new StringBuilder(); StringBuilder b = new StringBuilder();

4
ICSharpCode.NRefactory/CSharp/Ast/NodeType.cs

@ -43,7 +43,9 @@ namespace ICSharpCode.NRefactory.CSharp
Statement, Statement,
Expression, Expression,
Token, Token,
QueryClause QueryClause,
Pattern,
Placeholder
} }
} }

35
ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/AnyNode.cs

@ -0,0 +1,35 @@
// 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;
namespace ICSharpCode.NRefactory.CSharp.PatternMatching
{
/// <summary>
/// Matches any node.
/// </summary>
public class AnyNode : Pattern
{
readonly string groupName;
public string GroupName {
get { return groupName; }
}
public AnyNode(string groupName = null)
{
this.groupName = groupName;
}
protected internal override bool DoMatch(AstNode other, Match match)
{
match.Add(this.groupName, other);
return other != null && !other.IsNull;
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return ((IPatternAstVisitor<T, S>)visitor).VisitAnyNode(this, data);
}
}
}

70
ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Backreference.cs

@ -0,0 +1,70 @@
// 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;
namespace ICSharpCode.NRefactory.CSharp.PatternMatching
{
/// <summary>
/// Matches the last entry in the specified named group.
/// </summary>
public class Backreference : Pattern
{
readonly string referencedGroupName;
public string ReferencedGroupName {
get { return referencedGroupName; }
}
public Backreference(string referencedGroupName)
{
if (referencedGroupName == null)
throw new ArgumentNullException("referencedGroupName");
this.referencedGroupName = referencedGroupName;
}
protected internal override bool DoMatch(AstNode other, Match match)
{
return match.Get(referencedGroupName).Last().Match(other) != null;
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return ((IPatternAstVisitor<T, S>)visitor).VisitBackreference(this, data);
}
}
/// <summary>
/// Matches identifier expressions that have the same identifier as the referenced variable/type definition/method definition.
/// </summary>
public class IdentifierExpressionBackreference : Pattern
{
readonly string referencedGroupName;
public string ReferencedGroupName {
get { return referencedGroupName; }
}
public IdentifierExpressionBackreference(string referencedGroupName)
{
if (referencedGroupName == null)
throw new ArgumentNullException("referencedGroupName");
this.referencedGroupName = referencedGroupName;
}
protected internal override bool DoMatch(AstNode other, Match match)
{
IdentifierExpression ident = other as IdentifierExpression;
if (ident == null || ident.TypeArguments.Any())
return false;
AstNode referenced = match.Get(referencedGroupName).Last();
return ident.Identifier == referenced.GetChildByRole(AstNode.Roles.Identifier).Name;
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return ((IPatternAstVisitor<T, S>)visitor).VisitIdentifierExpressionBackreference(this, data);
}
}
}

54
ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Choice.cs

@ -0,0 +1,54 @@
// 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.Collections.Generic;
namespace ICSharpCode.NRefactory.CSharp.PatternMatching
{
/// <summary>
/// Matches one of several alternatives.
/// </summary>
public class Choice : Pattern, IEnumerable<AstNode>
{
public static readonly Role<AstNode> AlternativeRole = new Role<AstNode>("Alternative", AstNode.Null);
public void Add(string name, AstNode alternative)
{
AddChild(new NamedNode(name, alternative), AlternativeRole);
}
public void Add(AstNode alternative)
{
AddChild(alternative, AlternativeRole);
}
protected internal override bool DoMatch(AstNode other, Match match)
{
var checkPoint = match.CheckPoint();
foreach (AstNode alt in GetChildrenByRole(AlternativeRole)) {
if (alt.DoMatch(other, match))
return true;
else
match.RestoreCheckPoint(checkPoint);
}
return false;
}
IEnumerator<AstNode> IEnumerable<AstNode>.GetEnumerator()
{
return GetChildrenByRole(AlternativeRole).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetChildrenByRole(AlternativeRole).GetEnumerator();
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return ((IPatternAstVisitor<T, S>)visitor).VisitChoice(this, data);
}
}
}

22
ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/IPatternAstVisitor.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;
namespace ICSharpCode.NRefactory.CSharp.PatternMatching
{
/// <summary>
/// Extended AST visitor that works for patterns.
/// </summary>
public interface IPatternAstVisitor<in T, out S> : IAstVisitor<T, S>
{
S VisitPlaceholder(AstNode placeholder, AstNode child, T data);
S VisitAnyNode(AnyNode anyNode, T data);
S VisitBackreference(Backreference backreference, T data);
S VisitChoice(Choice choice, T data);
S VisitNamedNode(NamedNode namedNode, T data);
S VisitRepeat(Repeat repeat, T data);
S VisitIdentifierExpressionBackreference(IdentifierExpressionBackreference identifierExpressionBackreference, T data);
}
}

59
ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Match.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)
using System;
using System.Collections.Generic;
using System.Linq;
namespace ICSharpCode.NRefactory.CSharp.PatternMatching
{
/// <summary>
/// Represents the result of a pattern matching operation.
/// </summary>
public sealed class Match
{
List<KeyValuePair<string, AstNode>> results = new List<KeyValuePair<string, AstNode>>();
internal int CheckPoint()
{
return results.Count;
}
internal void RestoreCheckPoint(int checkPoint)
{
results.RemoveRange(checkPoint, results.Count - checkPoint);
}
public IEnumerable<AstNode> Get(string groupName)
{
foreach (var pair in results) {
if (pair.Key == groupName)
yield return pair.Value;
}
}
public IEnumerable<T> Get<T>(string groupName) where T : AstNode
{
foreach (var pair in results) {
if (pair.Key == groupName)
yield return (T)pair.Value;
}
}
public bool Has(string groupName)
{
foreach (var pair in results) {
if (pair.Key == groupName)
return true;
}
return false;
}
public void Add(string groupName, AstNode node)
{
if (groupName != null && node != null) {
results.Add(new KeyValuePair<string, AstNode>(groupName, node));
}
}
}
}

38
ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/NamedNode.cs

@ -0,0 +1,38 @@
// 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;
namespace ICSharpCode.NRefactory.CSharp.PatternMatching
{
/// <summary>
/// Represents a named node within a pattern.
/// </summary>
public class NamedNode : Pattern
{
public static readonly Role<AstNode> ElementRole = new Role<AstNode>("Element", AstNode.Null);
readonly string groupName;
public string GroupName {
get { return groupName; }
}
public NamedNode(string groupName, AstNode childNode)
{
this.groupName = groupName;
AddChild(childNode, ElementRole);
}
protected internal override bool DoMatch(AstNode other, Match match)
{
match.Add(this.groupName, other);
return GetChildByRole(ElementRole).DoMatch(other, match);
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return ((IPatternAstVisitor<T, S>)visitor).VisitNamedNode(this, data);
}
}
}

70
ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Pattern.cs

@ -0,0 +1,70 @@
// 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.IO;
namespace ICSharpCode.NRefactory.CSharp.PatternMatching
{
/// <summary>
/// Base class for all patterns.
/// </summary>
public abstract class Pattern : AstNode
{
public override NodeType NodeType {
get { return NodeType.Pattern; }
}
internal struct PossibleMatch
{
public readonly AstNode NextOther; // next node after the last matched node
public readonly int Checkpoint; // checkpoint
public PossibleMatch(AstNode nextOther, int checkpoint)
{
this.NextOther = nextOther;
this.Checkpoint = checkpoint;
}
}
internal virtual bool DoMatchCollection(Role role, AstNode pos, Match match, Stack<PossibleMatch> backtrackingStack)
{
return DoMatch(pos, match);
}
public AstType ToType()
{
return new TypePlaceholder(this);
}
public Expression ToExpression()
{
return new ExpressionPlaceholder(this);
}
public Statement ToStatement()
{
return new StatementPlaceholder(this);
}
public BlockStatement ToBlock()
{
return new BlockStatementPlaceholder(this);
}
public VariableInitializer ToVariable()
{
return new VariablePlaceholder(this);
}
// Make debugging easier by giving Patterns a ToString() implementation
public override string ToString()
{
StringWriter w = new StringWriter();
AcceptVisitor(new OutputVisitor(w, new CSharpFormattingPolicy()), null);
return w.ToString();
}
}
}

119
ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Placeholder.cs

@ -0,0 +1,119 @@
// 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;
namespace ICSharpCode.NRefactory.CSharp.PatternMatching
{
sealed class TypePlaceholder : AstType
{
public static readonly Role<AstNode> ChildRole = new Role<AstNode>("Child", AstNode.Null);
public TypePlaceholder(AstNode child)
{
AddChild(child, TypePlaceholder.ChildRole);
}
public override NodeType NodeType {
get { return NodeType.Placeholder; }
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return ((IPatternAstVisitor<T, S>)visitor).VisitPlaceholder(this, GetChildByRole(TypePlaceholder.ChildRole), data);
}
protected internal override bool DoMatch(AstNode other, Match match)
{
return GetChildByRole(TypePlaceholder.ChildRole).DoMatch(other, match);
}
}
sealed class ExpressionPlaceholder : Expression
{
public ExpressionPlaceholder(AstNode child)
{
AddChild(child, TypePlaceholder.ChildRole);
}
public override NodeType NodeType {
get { return NodeType.Placeholder; }
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return ((IPatternAstVisitor<T, S>)visitor).VisitPlaceholder(this, GetChildByRole(TypePlaceholder.ChildRole), data);
}
protected internal override bool DoMatch(AstNode other, Match match)
{
return GetChildByRole(TypePlaceholder.ChildRole).DoMatch(other, match);
}
}
sealed class StatementPlaceholder : Statement
{
public StatementPlaceholder(AstNode child)
{
AddChild(child, TypePlaceholder.ChildRole);
}
public override NodeType NodeType {
get { return NodeType.Placeholder; }
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return ((IPatternAstVisitor<T, S>)visitor).VisitPlaceholder(this, GetChildByRole(TypePlaceholder.ChildRole), data);
}
protected internal override bool DoMatch(AstNode other, Match match)
{
return GetChildByRole(TypePlaceholder.ChildRole).DoMatch(other, match);
}
}
sealed class BlockStatementPlaceholder : BlockStatement
{
public BlockStatementPlaceholder(AstNode child)
{
AddChild(child, TypePlaceholder.ChildRole);
}
public override NodeType NodeType {
get { return NodeType.Placeholder; }
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return ((IPatternAstVisitor<T, S>)visitor).VisitPlaceholder(this, GetChildByRole(TypePlaceholder.ChildRole), data);
}
protected internal override bool DoMatch(AstNode other, Match match)
{
return GetChildByRole(TypePlaceholder.ChildRole).DoMatch(other, match);
}
}
sealed class VariablePlaceholder : VariableInitializer
{
public VariablePlaceholder(AstNode child)
{
AddChild(child, TypePlaceholder.ChildRole);
}
public override NodeType NodeType {
get { return NodeType.Placeholder; }
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return ((IPatternAstVisitor<T, S>)visitor).VisitPlaceholder(this, GetChildByRole(TypePlaceholder.ChildRole), data);
}
protected internal override bool DoMatch(AstNode other, Match match)
{
return GetChildByRole(TypePlaceholder.ChildRole).DoMatch(other, match);
}
}
}

55
ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Repeat.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 X11 license (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using System.Diagnostics;
namespace ICSharpCode.NRefactory.CSharp.PatternMatching
{
/// <summary>
/// Represents an optional node.
/// </summary>
public class Repeat : Pattern
{
public static readonly Role<AstNode> ElementRole = new Role<AstNode>("Element", AstNode.Null);
public int MinCount;
public int MaxCount = int.MaxValue;
public Repeat(AstNode childNode)
{
AddChild(childNode, ElementRole);
}
internal override bool DoMatchCollection(Role role, AstNode pos, Match match, Stack<Pattern.PossibleMatch> backtrackingStack)
{
Debug.Assert(pos == null || pos.Role == role);
int matchCount = 0;
if (this.MinCount <= 0)
backtrackingStack.Push(new PossibleMatch(pos, match.CheckPoint()));
AstNode element = GetChildByRole(ElementRole);
while (matchCount < this.MaxCount && pos != null && element.DoMatch(pos, match)) {
matchCount++;
do {
pos = pos.NextSibling;
} while (pos != null && pos.Role != role);
if (matchCount >= this.MinCount)
backtrackingStack.Push(new PossibleMatch(pos, match.CheckPoint()));
}
return false; // never do a normal (single-element) match; always make the caller look at the results on the back-tracking stack.
}
protected internal override bool DoMatch(AstNode other, Match match)
{
if (other == null || other.IsNull)
return this.MinCount <= 0;
else
return this.MaxCount >= 1 && GetChildByRole(ElementRole).DoMatch(other, match);
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return ((IPatternAstVisitor<T, S>)visitor).VisitRepeat(this, data);
}
}
}

8
ICSharpCode.NRefactory/CSharp/Ast/PrimitiveType.cs

@ -1,4 +1,4 @@
// //
// FullTypeName.cs // FullTypeName.cs
// //
// Author: // Author:
@ -65,6 +65,12 @@ namespace ICSharpCode.NRefactory.CSharp
return visitor.VisitPrimitiveType (this, data); return visitor.VisitPrimitiveType (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
PrimitiveType o = other as PrimitiveType;
return o != null && MatchString(this.Keyword, o.Keyword);
}
public override string ToString() public override string ToString()
{ {
return Keyword ?? base.ToString(); return Keyword ?? base.ToString();

11
ICSharpCode.NRefactory/CSharp/Ast/SimpleType.cs

@ -1,4 +1,4 @@
// //
// FullTypeName.cs // FullTypeName.cs
// //
// Author: // Author:
@ -56,9 +56,8 @@ namespace ICSharpCode.NRefactory.CSharp
} }
} }
public IEnumerable<AstType> TypeArguments { public AstNodeCollection<AstType> TypeArguments {
get { return GetChildrenByRole (Roles.TypeArgument); } get { return GetChildrenByRole (Roles.TypeArgument); }
set { SetChildrenByRole (Roles.TypeArgument, value); }
} }
public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data) public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data)
@ -66,6 +65,12 @@ namespace ICSharpCode.NRefactory.CSharp
return visitor.VisitSimpleType (this, data); return visitor.VisitSimpleType (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
SimpleType o = other as SimpleType;
return o != null && MatchString(this.Identifier, o.Identifier) && this.TypeArguments.DoMatch(o.TypeArguments, match);
}
public override string ToString() public override string ToString()
{ {
StringBuilder b = new StringBuilder(this.Identifier); StringBuilder b = new StringBuilder(this.Identifier);

38
ICSharpCode.NRefactory/CSharp/Ast/Statements/BlockStatement.cs

@ -1,4 +1,4 @@
// //
// BlockStatement.cs // BlockStatement.cs
// //
// Author: // Author:
@ -31,7 +31,7 @@ namespace ICSharpCode.NRefactory.CSharp
/// <summary> /// <summary>
/// { Statements } /// { Statements }
/// </summary> /// </summary>
public class BlockStatement : Statement public class BlockStatement : Statement, IEnumerable<Statement>
{ {
public static readonly Role<Statement> StatementRole = new Role<Statement>("Statement", Statement.Null); public static readonly Role<Statement> StatementRole = new Role<Statement>("Statement", Statement.Null);
@ -49,6 +49,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return default (S); return default (S);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
return other == null || other.IsNull;
}
} }
#endregion #endregion
@ -56,9 +61,8 @@ namespace ICSharpCode.NRefactory.CSharp
get { return GetChildByRole (Roles.LBrace); } get { return GetChildByRole (Roles.LBrace); }
} }
public IEnumerable<Statement> Statements { public AstNodeCollection<Statement> Statements {
get { return GetChildrenByRole (StatementRole); } get { return GetChildrenByRole (StatementRole); }
set { SetChildrenByRole (StatementRole, value); }
} }
public CSharpTokenNode RBraceToken { public CSharpTokenNode RBraceToken {
@ -70,18 +74,24 @@ namespace ICSharpCode.NRefactory.CSharp
return visitor.VisitBlockStatement (this, data); return visitor.VisitBlockStatement (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
BlockStatement o = other as BlockStatement;
return o != null && this.Statements.DoMatch(o.Statements, match);
}
#region Builder methods #region Builder methods
public void AddStatement(Statement statement) public void Add(Statement statement)
{ {
AddChild(statement, StatementRole); AddChild(statement, StatementRole);
} }
public void AddStatement(Expression expression) public void Add(Expression expression)
{ {
AddChild(new ExpressionStatement { Expression = expression }, StatementRole); AddChild(new ExpressionStatement { Expression = expression }, StatementRole);
} }
public void AddStatements(IEnumerable<Statement> statements) public void AddRange(IEnumerable<Statement> statements)
{ {
foreach (Statement st in statements) foreach (Statement st in statements)
AddChild(st, StatementRole); AddChild(st, StatementRole);
@ -89,13 +99,23 @@ namespace ICSharpCode.NRefactory.CSharp
public void AddAssignment(Expression left, Expression right) public void AddAssignment(Expression left, Expression right)
{ {
AddStatement(new AssignmentExpression { Left = left, Operator = AssignmentOperatorType.Assign, Right = right }); Add(new AssignmentExpression { Left = left, Operator = AssignmentOperatorType.Assign, Right = right });
} }
public void AddReturnStatement(Expression expression) public void AddReturnStatement(Expression expression)
{ {
AddStatement(new ReturnStatement { Expression = expression }); Add(new ReturnStatement { Expression = expression });
} }
#endregion #endregion
IEnumerator<Statement> IEnumerable<Statement>.GetEnumerator()
{
return this.Statements.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return this.Statements.GetEnumerator();
}
} }
} }

10
ICSharpCode.NRefactory/CSharp/Ast/Statements/BreakStatement.cs

@ -1,6 +1,6 @@
// //
// BreakStatement.cs // BreakStatement.cs
// //
// Author: // Author:
// Mike Krüger <mkrueger@novell.com> // Mike Krüger <mkrueger@novell.com>
// //
@ -39,5 +39,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitBreakStatement (this, data); return visitor.VisitBreakStatement (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
BreakStatement o = other as BreakStatement;
return o != null;
}
} }
} }

8
ICSharpCode.NRefactory/CSharp/Ast/Statements/CheckedStatement.cs

@ -1,4 +1,4 @@
// //
// CheckedStatement.cs // CheckedStatement.cs
// //
// Author: // Author:
@ -44,5 +44,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitCheckedStatement (this, data); return visitor.VisitCheckedStatement (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
CheckedStatement o = other as CheckedStatement;
return o != null && this.Body.DoMatch(o.Body, match);
}
} }
} }

8
ICSharpCode.NRefactory/CSharp/Ast/Statements/ContinueStatement.cs

@ -1,4 +1,4 @@
// //
// ContinueStatement.cs // ContinueStatement.cs
// //
// Author: // Author:
@ -39,5 +39,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitContinueStatement (this, data); return visitor.VisitContinueStatement (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
ContinueStatement o = other as ContinueStatement;
return o != null;
}
} }
} }

8
ICSharpCode.NRefactory/CSharp/Ast/Statements/DoWhileStatement.cs

@ -1,4 +1,4 @@
// //
// DoWhileStatement.cs // DoWhileStatement.cs
// //
// Author: // Author:
@ -68,6 +68,12 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitDoWhileStatement (this, data); return visitor.VisitDoWhileStatement (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
DoWhileStatement o = other as DoWhileStatement;
return o != null && this.EmbeddedStatement.DoMatch(o.EmbeddedStatement, match) && this.Condition.DoMatch(o.Condition, match);
}
} }
} }

8
ICSharpCode.NRefactory/CSharp/Ast/Statements/EmptyStatement.cs

@ -1,4 +1,4 @@
// //
// EmptyStatement.cs // EmptyStatement.cs
// //
// Author: // Author:
@ -52,5 +52,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitEmptyStatement (this, data); return visitor.VisitEmptyStatement (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
EmptyStatement o = other as EmptyStatement;
return o != null;
}
} }
} }

17
ICSharpCode.NRefactory/CSharp/Ast/Statements/ExpressionStatement.cs

@ -1,4 +1,4 @@
// //
// ExpressionStatement.cs // ExpressionStatement.cs
// //
// Author: // Author:
@ -44,5 +44,20 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitExpressionStatement (this, data); return visitor.VisitExpressionStatement (this, data);
} }
public ExpressionStatement()
{
}
public ExpressionStatement(Expression expression)
{
this.Expression = expression;
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
ExpressionStatement o = other as ExpressionStatement;
return o != null && this.Expression.DoMatch(o.Expression, match);
}
} }
} }

11
ICSharpCode.NRefactory/CSharp/Ast/Statements/FixedStatement.cs

@ -1,4 +1,4 @@
// //
// FixedStatement.cs // FixedStatement.cs
// //
// Author: // Author:
@ -46,9 +46,8 @@ namespace ICSharpCode.NRefactory.CSharp
set { SetChildByRole (Roles.Type, value); } set { SetChildByRole (Roles.Type, value); }
} }
public IEnumerable<VariableInitializer> Variables { public AstNodeCollection<VariableInitializer> Variables {
get { return GetChildrenByRole (Roles.Variable); } get { return GetChildrenByRole (Roles.Variable); }
set { SetChildrenByRole (Roles.Variable, value); }
} }
public CSharpTokenNode RParToken { public CSharpTokenNode RParToken {
@ -64,5 +63,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitFixedStatement (this, data); return visitor.VisitFixedStatement (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
FixedStatement o = other as FixedStatement;
return o != null && this.Variables.DoMatch(o.Variables, match) && this.EmbeddedStatement.DoMatch(o.EmbeddedStatement, match);
}
} }
} }

17
ICSharpCode.NRefactory/CSharp/Ast/Statements/ForStatement.cs

@ -1,6 +1,6 @@
// //
// ForStatement.cs // ForStatement.cs
// //
// Author: // Author:
// Mike Krüger <mkrueger@novell.com> // Mike Krüger <mkrueger@novell.com>
// //
@ -49,9 +49,8 @@ namespace ICSharpCode.NRefactory.CSharp
/// Note: this contains multiple statements for "for (a = 2, b = 1; a > b; a--)", but contains /// Note: this contains multiple statements for "for (a = 2, b = 1; a > b; a--)", but contains
/// only a single statement for "for (int a = 2, b = 1; a > b; a--)" (a single VariableDeclarationStatement with two variables) /// only a single statement for "for (int a = 2, b = 1; a > b; a--)" (a single VariableDeclarationStatement with two variables)
/// </summary> /// </summary>
public IEnumerable<Statement> Initializers { public AstNodeCollection<Statement> Initializers {
get { return GetChildrenByRole (InitializerRole); } get { return GetChildrenByRole (InitializerRole); }
set { SetChildrenByRole (InitializerRole, value); }
} }
public Expression Condition { public Expression Condition {
@ -59,9 +58,8 @@ namespace ICSharpCode.NRefactory.CSharp
set { SetChildByRole (Roles.Condition, value); } set { SetChildByRole (Roles.Condition, value); }
} }
public IEnumerable<Statement> Iterators { public AstNodeCollection<Statement> Iterators {
get { return GetChildrenByRole (IteratorRole); } get { return GetChildrenByRole (IteratorRole); }
set { SetChildrenByRole (IteratorRole, value); }
} }
public CSharpTokenNode RParToken { public CSharpTokenNode RParToken {
@ -77,5 +75,12 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitForStatement (this, data); return visitor.VisitForStatement (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
ForStatement o = other as ForStatement;
return o != null && this.Initializers.DoMatch(o.Initializers, match) && this.Condition.DoMatch(o.Condition, match)
&& this.Iterators.DoMatch(o.Iterators, match) && this.EmbeddedStatement.DoMatch(o.EmbeddedStatement, match);
}
} }
} }

9
ICSharpCode.NRefactory/CSharp/Ast/Statements/ForeachStatement.cs

@ -1,4 +1,4 @@
// //
// ForeachStatement.cs // ForeachStatement.cs
// //
// Author: // Author:
@ -75,5 +75,12 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitForeachStatement (this, data); return visitor.VisitForeachStatement (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
ForeachStatement o = other as ForeachStatement;
return o != null && this.VariableType.DoMatch(o.VariableType, match) && MatchString(this.VariableName, o.VariableName)
&& this.InExpression.DoMatch(o.InExpression, match) && this.EmbeddedStatement.DoMatch(o.EmbeddedStatement, match);
}
} }
} }

38
ICSharpCode.NRefactory/CSharp/Ast/Statements/GotoStatement.cs

@ -56,14 +56,6 @@ namespace ICSharpCode.NRefactory.CSharp
} }
} }
/// <summary>
/// Used for "goto case LabelExpression;"
/// </summary>
public Expression LabelExpression {
get { return GetChildByRole (Roles.Expression); }
set { SetChildByRole (Roles.Expression, value); }
}
public CSharpTokenNode SemicolonToken { public CSharpTokenNode SemicolonToken {
get { return GetChildByRole (Roles.Semicolon); } get { return GetChildByRole (Roles.Semicolon); }
} }
@ -72,6 +64,12 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitGotoStatement (this, data); return visitor.VisitGotoStatement (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
GotoStatement o = other as GotoStatement;
return o != null && MatchString(this.Label, o.Label);
}
} }
/// <summary> /// <summary>
@ -89,18 +87,6 @@ namespace ICSharpCode.NRefactory.CSharp
get { return GetChildByRole (CaseKeywordRole); } get { return GetChildByRole (CaseKeywordRole); }
} }
public string Label {
get {
return GetChildByRole (Roles.Identifier).Name;
}
set {
if (string.IsNullOrEmpty(value))
SetChildByRole(Roles.Identifier, null);
else
SetChildByRole(Roles.Identifier, new Identifier(value, AstLocation.Empty));
}
}
/// <summary> /// <summary>
/// Used for "goto case LabelExpression;" /// Used for "goto case LabelExpression;"
/// </summary> /// </summary>
@ -117,6 +103,12 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitGotoCaseStatement (this, data); return visitor.VisitGotoCaseStatement (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
GotoCaseStatement o = other as GotoCaseStatement;
return o != null && this.LabelExpression.DoMatch(o.LabelExpression, match);
}
} }
/// <summary> /// <summary>
@ -142,5 +134,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitGotoDefaultStatement (this, data); return visitor.VisitGotoDefaultStatement (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
GotoDefaultStatement o = other as GotoDefaultStatement;
return o != null;
}
} }
} }

8
ICSharpCode.NRefactory/CSharp/Ast/Statements/IfElseStatement.cs

@ -1,4 +1,4 @@
// //
// IfElseStatement.cs // IfElseStatement.cs
// //
// Author: // Author:
@ -74,6 +74,12 @@ namespace ICSharpCode.NRefactory.CSharp
return visitor.VisitIfElseStatement (this, data); return visitor.VisitIfElseStatement (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
IfElseStatement o = other as IfElseStatement;
return o != null && this.Condition.DoMatch(o.Condition, match) && this.TrueStatement.DoMatch(o.TrueStatement, match) && this.FalseStatement.DoMatch(o.FalseStatement, match);
}
public IfElseStatement() public IfElseStatement()
{ {
} }

12
ICSharpCode.NRefactory/CSharp/Ast/Statements/LabelStatement.cs

@ -1,4 +1,4 @@
// //
// LabelStatement.cs // LabelStatement.cs
// //
// Author: // Author:
@ -40,9 +40,19 @@ namespace ICSharpCode.NRefactory.CSharp
} }
} }
public CSharpTokenNode Colon {
get { return GetChildByRole (Roles.Colon); }
}
public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data) public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data)
{ {
return visitor.VisitLabelStatement (this, data); return visitor.VisitLabelStatement (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
LabelStatement o = other as LabelStatement;
return o != null && MatchString(this.Label, o.Label);
}
} }
} }

8
ICSharpCode.NRefactory/CSharp/Ast/Statements/LockStatement.cs

@ -1,4 +1,4 @@
// //
// LockStatement.cs // LockStatement.cs
// //
// Author: // Author:
@ -57,5 +57,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitLockStatement (this, data); return visitor.VisitLockStatement (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
LockStatement o = other as LockStatement;
return o != null && this.Expression.DoMatch(o.Expression, match) && this.EmbeddedStatement.DoMatch(o.EmbeddedStatement, match);
}
} }
} }

8
ICSharpCode.NRefactory/CSharp/Ast/Statements/ReturnStatement.cs

@ -1,4 +1,4 @@
// //
// ReturnStatement.cs // ReturnStatement.cs
// //
// Author: // Author:
@ -48,5 +48,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitReturnStatement (this, data); return visitor.VisitReturnStatement (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
ReturnStatement o = other as ReturnStatement;
return o != null && this.Expression.DoMatch(o.Expression, match);
}
} }
} }

5
ICSharpCode.NRefactory/CSharp/Ast/Statements/Statement.cs

@ -29,6 +29,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return default (S); return default (S);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
return other == null || other.IsNull;
}
} }
#endregion #endregion

29
ICSharpCode.NRefactory/CSharp/Ast/Statements/SwitchStatement.cs

@ -1,4 +1,4 @@
// //
// SwitchStatement.cs // SwitchStatement.cs
// //
// Author: // Author:
@ -57,9 +57,8 @@ namespace ICSharpCode.NRefactory.CSharp
get { return GetChildByRole (Roles.LBrace); } get { return GetChildByRole (Roles.LBrace); }
} }
public IEnumerable<SwitchSection> SwitchSections { public AstNodeCollection<SwitchSection> SwitchSections {
get { return GetChildrenByRole (SwitchSectionRole); } get { return GetChildrenByRole (SwitchSectionRole); }
set { SetChildrenByRole (SwitchSectionRole, value); }
} }
public CSharpTokenNode RBraceToken { public CSharpTokenNode RBraceToken {
@ -70,6 +69,12 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitSwitchStatement (this, data); return visitor.VisitSwitchStatement (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
SwitchStatement o = other as SwitchStatement;
return o != null && this.Expression.DoMatch(o.Expression, match) && this.SwitchSections.DoMatch(o.SwitchSections, match);
}
} }
public class SwitchSection : AstNode public class SwitchSection : AstNode
@ -82,20 +87,24 @@ namespace ICSharpCode.NRefactory.CSharp
} }
} }
public IEnumerable<CaseLabel> CaseLabels { public AstNodeCollection<CaseLabel> CaseLabels {
get { return GetChildrenByRole (CaseLabelRole); } get { return GetChildrenByRole (CaseLabelRole); }
set { SetChildrenByRole (CaseLabelRole, value); }
} }
public IEnumerable<Statement> Statements { public AstNodeCollection<Statement> Statements {
get { return GetChildrenByRole (Roles.EmbeddedStatement); } get { return GetChildrenByRole (Roles.EmbeddedStatement); }
set { SetChildrenByRole (Roles.EmbeddedStatement, value); }
} }
public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data) public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data)
{ {
return visitor.VisitSwitchSection (this, data); return visitor.VisitSwitchSection (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
SwitchSection o = other as SwitchSection;
return o != null && this.CaseLabels.DoMatch(o.CaseLabels, match) && this.Statements.DoMatch(o.Statements, match);
}
} }
public class CaseLabel : AstNode public class CaseLabel : AstNode
@ -115,5 +124,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitCaseLabel (this, data); return visitor.VisitCaseLabel (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
CaseLabel o = other as CaseLabel;
return o != null && this.Expression.DoMatch(o.Expression, match);
}
} }
} }

8
ICSharpCode.NRefactory/CSharp/Ast/Statements/ThrowStatement.cs

@ -1,4 +1,4 @@
// //
// ThrowStatement.cs // ThrowStatement.cs
// //
// Author: // Author:
@ -48,5 +48,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitThrowStatement (this, data); return visitor.VisitThrowStatement (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
ThrowStatement o = other as ThrowStatement;
return o != null && this.Expression.DoMatch(o.Expression, match);
}
} }
} }

17
ICSharpCode.NRefactory/CSharp/Ast/Statements/TryCatchStatement.cs

@ -1,4 +1,4 @@
// //
// TryCatchStatement.cs // TryCatchStatement.cs
// //
// Author: // Author:
@ -49,9 +49,8 @@ namespace ICSharpCode.NRefactory.CSharp
set { SetChildByRole (TryBlockRole, value); } set { SetChildByRole (TryBlockRole, value); }
} }
public IEnumerable<CatchClause> CatchClauses { public AstNodeCollection<CatchClause> CatchClauses {
get { return GetChildrenByRole (CatchClauseRole); } get { return GetChildrenByRole (CatchClauseRole); }
set { SetChildrenByRole (CatchClauseRole, value); }
} }
public CSharpTokenNode FinallyToken { public CSharpTokenNode FinallyToken {
@ -67,6 +66,12 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitTryCatchStatement (this, data); return visitor.VisitTryCatchStatement (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
TryCatchStatement o = other as TryCatchStatement;
return o != null && this.TryBlock.DoMatch(o.TryBlock, match) && this.CatchClauses.DoMatch(o.CatchClauses, match) && this.FinallyBlock.DoMatch(o.FinallyBlock, match);
}
} }
/// <summary> /// <summary>
@ -116,5 +121,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitCatchClause (this, data); return visitor.VisitCatchClause (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
CatchClause o = other as CatchClause;
return o != null && this.Type.DoMatch(o.Type, match) && MatchString(this.VariableName, o.VariableName) && this.Body.DoMatch(o.Body, match);
}
} }
} }

8
ICSharpCode.NRefactory/CSharp/Ast/Statements/UncheckedStatement.cs

@ -1,4 +1,4 @@
// //
// UncheckedStatement.cs // UncheckedStatement.cs
// //
// Author: // Author:
@ -44,5 +44,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitUncheckedStatement (this, data); return visitor.VisitUncheckedStatement (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
UncheckedStatement o = other as UncheckedStatement;
return o != null && this.Body.DoMatch(o.Body, match);
}
} }
} }

8
ICSharpCode.NRefactory/CSharp/Ast/Statements/UnsafeStatement.cs

@ -1,4 +1,4 @@
// //
// UnsafeStatement.cs // UnsafeStatement.cs
// //
// Author: // Author:
@ -44,5 +44,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitUnsafeStatement (this, data); return visitor.VisitUnsafeStatement (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
UnsafeStatement o = other as UnsafeStatement;
return o != null && this.Body.DoMatch(o.Body, match);
}
} }
} }

8
ICSharpCode.NRefactory/CSharp/Ast/Statements/UsingStatement.cs

@ -1,4 +1,4 @@
// //
// UsingStatement.cs // UsingStatement.cs
// //
// Author: // Author:
@ -62,5 +62,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitUsingStatement (this, data); return visitor.VisitUsingStatement (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
UsingStatement o = other as UsingStatement;
return o != null && this.ResourceAcquisition.DoMatch(o.ResourceAcquisition, match) && this.EmbeddedStatement.DoMatch(o.EmbeddedStatement, match);
}
} }
} }

21
ICSharpCode.NRefactory/CSharp/Ast/Statements/VariableDeclarationStatement.cs

@ -1,4 +1,4 @@
// //
// VariableDeclarationStatement.cs // VariableDeclarationStatement.cs
// //
// Author: // Author:
@ -33,6 +33,16 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
public static readonly Role<CSharpModifierToken> ModifierRole = AttributedNode.ModifierRole; public static readonly Role<CSharpModifierToken> ModifierRole = AttributedNode.ModifierRole;
public VariableDeclarationStatement()
{
}
public VariableDeclarationStatement(AstType type, string name, Expression initializer = null)
{
this.Type = type;
this.Variables.Add(new VariableInitializer(name, initializer));
}
public Modifiers Modifiers { public Modifiers Modifiers {
get { return AttributedNode.GetModifiers(this); } get { return AttributedNode.GetModifiers(this); }
set { AttributedNode.SetModifiers(this, value); } set { AttributedNode.SetModifiers(this, value); }
@ -43,9 +53,8 @@ namespace ICSharpCode.NRefactory.CSharp
set { SetChildByRole (Roles.Type, value); } set { SetChildByRole (Roles.Type, value); }
} }
public IEnumerable<VariableInitializer> Variables { public AstNodeCollection<VariableInitializer> Variables {
get { return GetChildrenByRole (Roles.Variable); } get { return GetChildrenByRole (Roles.Variable); }
set { SetChildrenByRole (Roles.Variable, value); }
} }
public CSharpTokenNode SemicolonToken { public CSharpTokenNode SemicolonToken {
@ -56,5 +65,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitVariableDeclarationStatement (this, data); return visitor.VisitVariableDeclarationStatement (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
VariableDeclarationStatement o = other as VariableDeclarationStatement;
return o != null && this.Modifiers == o.Modifiers && this.Type.DoMatch(o.Type, match) && this.Variables.DoMatch(o.Variables, match);
}
} }
} }

8
ICSharpCode.NRefactory/CSharp/Ast/Statements/WhileStatement.cs

@ -1,4 +1,4 @@
// //
// WhileStatement.cs // WhileStatement.cs
// //
// Author: // Author:
@ -59,5 +59,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitWhileStatement (this, data); return visitor.VisitWhileStatement (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
WhileStatement o = other as WhileStatement;
return o != null && this.Condition.DoMatch(o.Condition, match) && this.EmbeddedStatement.DoMatch(o.EmbeddedStatement, match);
}
} }
} }

8
ICSharpCode.NRefactory/CSharp/Ast/Statements/YieldBreakStatement.cs

@ -1,4 +1,4 @@
// //
// YieldBreakStatement.cs // YieldBreakStatement.cs
// //
// Author: // Author:
@ -50,5 +50,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitYieldBreakStatement (this, data); return visitor.VisitYieldBreakStatement (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
YieldBreakStatement o = other as YieldBreakStatement;
return o != null;
}
} }
} }

8
ICSharpCode.NRefactory/CSharp/Ast/Statements/YieldStatement.cs

@ -1,4 +1,4 @@
// //
// YieldStatement.cs // YieldStatement.cs
// //
// Author: // Author:
@ -55,5 +55,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitYieldStatement (this, data); return visitor.VisitYieldStatement (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
YieldStatement o = other as YieldStatement;
return o != null && this.Expression.DoMatch(o.Expression, match);
}
} }
} }

9
ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/Accessor.cs

@ -1,4 +1,4 @@
// //
// PropertyDeclaration.cs // PropertyDeclaration.cs
// //
// Author: // Author:
@ -24,6 +24,8 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
using System;
namespace ICSharpCode.NRefactory.CSharp namespace ICSharpCode.NRefactory.CSharp
{ {
/// <summary> /// <summary>
@ -59,5 +61,10 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitAccessor (this, data); return visitor.VisitAccessor (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
throw new NotImplementedException();
}
} }
} }

13
ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/AttributedNode.cs

@ -1,6 +1,7 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) // 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) // This code is distributed under MIT X11 license (for details please see \doc\license.txt)
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@ -11,9 +12,8 @@ namespace ICSharpCode.NRefactory.CSharp
public static readonly Role<AttributeSection> AttributeRole = new Role<AttributeSection>("Attribute"); public static readonly Role<AttributeSection> AttributeRole = new Role<AttributeSection>("Attribute");
public static readonly Role<CSharpModifierToken> ModifierRole = new Role<CSharpModifierToken>("Modifier"); public static readonly Role<CSharpModifierToken> ModifierRole = new Role<CSharpModifierToken>("Modifier");
public IEnumerable<AttributeSection> Attributes { public AstNodeCollection<AttributeSection> Attributes {
get { return base.GetChildrenByRole (AttributeRole); } get { return base.GetChildrenByRole (AttributeRole); }
set { SetChildrenByRole (AttributeRole, value); }
} }
public Modifiers Modifiers { public Modifiers Modifiers {
@ -42,7 +42,9 @@ namespace ICSharpCode.NRefactory.CSharp
if ((m & newValue) != 0) { if ((m & newValue) != 0) {
if ((m & oldValue) == 0) { if ((m & oldValue) == 0) {
// Modifier was added // Modifier was added
node.InsertChildAfter(insertionPos, new CSharpModifierToken(AstLocation.Empty, m), ModifierRole); var newToken = new CSharpModifierToken(AstLocation.Empty, m);
node.InsertChildAfter(insertionPos, newToken, ModifierRole);
insertionPos = newToken;
} else { } else {
// Modifier already exists // Modifier already exists
insertionPos = node.GetChildrenByRole(ModifierRole).First(t => t.Modifier == m); insertionPos = node.GetChildrenByRole(ModifierRole).First(t => t.Modifier == m);
@ -55,5 +57,10 @@ namespace ICSharpCode.NRefactory.CSharp
} }
} }
} }
protected internal override bool DoMatch(AstNode other, ICSharpCode.NRefactory.CSharp.PatternMatching.Match match)
{
throw new NotImplementedException();
}
} }
} }

21
ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/ConstructorDeclaration.cs

@ -1,4 +1,4 @@
// //
// ConstructorDeclaration.cs // ConstructorDeclaration.cs
// //
// Author: // Author:
@ -33,13 +33,19 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
public static readonly Role<ConstructorInitializer> InitializerRole = new Role<ConstructorInitializer>("Initializer", ConstructorInitializer.Null); public static readonly Role<ConstructorInitializer> InitializerRole = new Role<ConstructorInitializer>("Initializer", ConstructorInitializer.Null);
/// <summary>
/// Gets/Sets the name of the class containing the constructor.
/// This property can be used to inform the output visitor about the class name when writing a constructor declaration
/// without writing the complete type declaration. It is ignored when the constructor has a type declaration as parent.
/// </summary>
public string Name { get; set; }
public CSharpTokenNode LParToken { public CSharpTokenNode LParToken {
get { return GetChildByRole (Roles.LPar); } get { return GetChildByRole (Roles.LPar); }
} }
public IEnumerable<ParameterDeclaration> Parameters { public AstNodeCollection<ParameterDeclaration> Parameters {
get { return GetChildrenByRole (Roles.Parameter); } get { return GetChildrenByRole (Roles.Parameter); }
set { SetChildrenByRole (Roles.Parameter, value); }
} }
public CSharpTokenNode RParToken { public CSharpTokenNode RParToken {
@ -105,14 +111,19 @@ namespace ICSharpCode.NRefactory.CSharp
set; set;
} }
public IEnumerable<Expression> Arguments { public AstNodeCollection<Expression> Arguments {
get { return GetChildrenByRole (Roles.Argument); } get { return GetChildrenByRole (Roles.Argument); }
set { SetChildrenByRole (Roles.Argument, value); }
} }
public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data) public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data)
{ {
return visitor.VisitConstructorInitializer (this, data); return visitor.VisitConstructorInitializer (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
ConstructorInitializer o = other as ConstructorInitializer;
return o != null && this.ConstructorInitializerType == o.ConstructorInitializerType && this.Arguments.DoMatch(o.Arguments, match);
}
} }
} }

9
ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/DestructorDeclaration.cs

@ -1,4 +1,4 @@
// //
// DestructorDeclaration.cs // DestructorDeclaration.cs
// //
// Author: // Author:
@ -34,6 +34,13 @@ namespace ICSharpCode.NRefactory.CSharp
get { return GetChildByRole (TildeRole); } get { return GetChildByRole (TildeRole); }
} }
/// <summary>
/// Gets/Sets the name of the class containing the destructor.
/// This property can be used to inform the output visitor about the class name when writing a destructor declaration
/// without writing the complete type declaration. It is ignored when the destructor has a type declaration as parent.
/// </summary>
public string Name { get; set; }
public CSharpTokenNode LParToken { public CSharpTokenNode LParToken {
get { return GetChildByRole (Roles.LPar); } get { return GetChildByRole (Roles.LPar); }
} }

5
ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/EventDeclaration.cs

@ -1,4 +1,4 @@
// //
// EventDeclaration.cs // EventDeclaration.cs
// //
// Author: // Author:
@ -30,9 +30,8 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
public class EventDeclaration : MemberDeclaration public class EventDeclaration : MemberDeclaration
{ {
public IEnumerable<VariableInitializer> Variables { public AstNodeCollection<VariableInitializer> Variables {
get { return GetChildrenByRole (Roles.Variable); } get { return GetChildrenByRole (Roles.Variable); }
set { SetChildrenByRole (Roles.Variable, value); }
} }
public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data) public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data)

5
ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/FieldDeclaration.cs

@ -1,4 +1,4 @@
// //
// FieldDeclaration.cs // FieldDeclaration.cs
// //
// Author: // Author:
@ -31,9 +31,8 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
public class FieldDeclaration : MemberDeclaration public class FieldDeclaration : MemberDeclaration
{ {
public IEnumerable<VariableInitializer> Variables { public AstNodeCollection<VariableInitializer> Variables {
get { return GetChildrenByRole (Roles.Variable); } get { return GetChildrenByRole (Roles.Variable); }
set { SetChildrenByRole (Roles.Variable, value); }
} }
public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data) public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data)

5
ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/IndexerDeclaration.cs

@ -1,4 +1,4 @@
// //
// IndexerDeclaration.cs // IndexerDeclaration.cs
// //
// Author: // Author:
@ -35,9 +35,8 @@ namespace ICSharpCode.NRefactory.CSharp
get { return GetChildByRole (Roles.LBracket); } get { return GetChildByRole (Roles.LBracket); }
} }
public IEnumerable<ParameterDeclaration> Parameters { public AstNodeCollection<ParameterDeclaration> Parameters {
get { return GetChildrenByRole (Roles.Parameter); } get { return GetChildrenByRole (Roles.Parameter); }
set { SetChildrenByRole (Roles.Parameter, value); }
} }
public CSharpTokenNode RBracketToken { public CSharpTokenNode RBracketToken {

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save