diff --git a/ICSharpCode.NRefactory/CSharp/Ast/AstNode.cs b/ICSharpCode.NRefactory/CSharp/Ast/AstNode.cs
index 2dab5a5ad9..dafcdc2533 100644
--- a/ICSharpCode.NRefactory/CSharp/Ast/AstNode.cs
+++ b/ICSharpCode.NRefactory/CSharp/Ast/AstNode.cs
@@ -157,6 +157,15 @@ namespace ICSharpCode.NRefactory.CSharp
}
}
+ ///
+ /// Gets all descendants of this node (including this node itself).
+ ///
+ public IEnumerable DescendantsAndSelf {
+ get {
+ return Utils.TreeTraversal.PreOrder(this, n => n.Children);
+ }
+ }
+
///
/// Gets the first child with the specified role.
/// Returns the role's null object if the child is not found.
diff --git a/ICSharpCode.NRefactory/CSharp/Ast/AstType.cs b/ICSharpCode.NRefactory/CSharp/Ast/AstType.cs
index a35204e3cd..5582b9012e 100644
--- a/ICSharpCode.NRefactory/CSharp/Ast/AstType.cs
+++ b/ICSharpCode.NRefactory/CSharp/Ast/AstType.cs
@@ -53,6 +53,30 @@ namespace ICSharpCode.NRefactory.CSharp
return new TypeReferenceExpression { Type = this }.Member(memberName);
}
+ ///
+ /// Builds an invocation expression using this type as target.
+ ///
+ public InvocationExpression Invoke(string methodName, IEnumerable arguments)
+ {
+ return new TypeReferenceExpression { Type = this }.Invoke(methodName, arguments);
+ }
+
+ ///
+ /// Builds an invocation expression using this type as target.
+ ///
+ public InvocationExpression Invoke(string methodName, params Expression[] arguments)
+ {
+ return new TypeReferenceExpression { Type = this }.Invoke(methodName, arguments);
+ }
+
+ ///
+ /// Builds an invocation expression using this type as target.
+ ///
+ public InvocationExpression Invoke(string methodName, IEnumerable typeArguments, IEnumerable arguments)
+ {
+ return new TypeReferenceExpression { Type = this }.Invoke(methodName, typeArguments, arguments);
+ }
+
public static AstType Create(Type type)
{
switch (Type.GetTypeCode(type)) {
diff --git a/ICSharpCode.NRefactory/CSharp/Ast/CSharpModifierToken.cs b/ICSharpCode.NRefactory/CSharp/Ast/CSharpModifierToken.cs
index ec0a85705c..3fc7fa2912 100644
--- a/ICSharpCode.NRefactory/CSharp/Ast/CSharpModifierToken.cs
+++ b/ICSharpCode.NRefactory/CSharp/Ast/CSharpModifierToken.cs
@@ -72,7 +72,10 @@ namespace ICSharpCode.NRefactory.CSharp
new KeyValuePair(Modifiers.Volatile, "volatile".Length),
new KeyValuePair(Modifiers.Extern, "extern".Length),
new KeyValuePair(Modifiers.Partial, "partial".Length),
- new KeyValuePair(Modifiers.Const, "const".Length)
+ new KeyValuePair(Modifiers.Const, "const".Length),
+
+ // even though it's used for patterns only, it needs to be in this table to be usable in the AST
+ new KeyValuePair(Modifiers.Any, "any".Length)
};
public static IEnumerable AllModifiers {
diff --git a/ICSharpCode.NRefactory/CSharp/Ast/Modifiers.cs b/ICSharpCode.NRefactory/CSharp/Ast/Modifiers.cs
index a05a817aaf..700a3c04d1 100644
--- a/ICSharpCode.NRefactory/CSharp/Ast/Modifiers.cs
+++ b/ICSharpCode.NRefactory/CSharp/Ast/Modifiers.cs
@@ -66,4 +66,9 @@ namespace ICSharpCode.NRefactory.CSharp
//Final = 0x400000,
//Literal = 0x800000,
VisibilityMask = Private | Internal | Protected | Public,
+
+ ///
+ /// Special value used to match any modifiers during pattern matching.
+ ///
+ Any = unchecked((int)0x80000000)
}}
diff --git a/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Pattern.cs b/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Pattern.cs
index 23f5c2ea58..ed2122d19a 100644
--- a/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Pattern.cs
+++ b/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Pattern.cs
@@ -34,6 +34,11 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching
return p != null ? new TypePlaceholder(p) : null;
}
+ public AstType ToType()
+ {
+ return new TypePlaceholder(this);
+ }
+
public static implicit operator Expression(Pattern p)
{
return p != null ? new ExpressionPlaceholder(p) : null;
@@ -64,6 +69,11 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching
return p != null ? new VariablePlaceholder(p) : null;
}
+ public static implicit operator AttributeSection(Pattern p)
+ {
+ return p != null ? new AttributeSectionPlaceholder(p) : null;
+ }
+
// Make debugging easier by giving Patterns a ToString() implementation
public override string ToString()
{
diff --git a/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Placeholder.cs b/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Placeholder.cs
index f68feb443d..67987595f9 100644
--- a/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Placeholder.cs
+++ b/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Placeholder.cs
@@ -152,4 +152,33 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching
return child.DoMatchCollection(role, pos, match, backtrackingStack);
}
}
+
+ sealed class AttributeSectionPlaceholder : AttributeSection
+ {
+ readonly AstNode child;
+
+ public AttributeSectionPlaceholder(AstNode child)
+ {
+ this.child = child;
+ }
+
+ public override NodeType NodeType {
+ get { return NodeType.Placeholder; }
+ }
+
+ public override S AcceptVisitor(IAstVisitor visitor, T data)
+ {
+ return ((IPatternAstVisitor)visitor).VisitPlaceholder(this, child, data);
+ }
+
+ protected internal override bool DoMatch(AstNode other, Match match)
+ {
+ return child.DoMatch(other, match);
+ }
+
+ internal override bool DoMatchCollection(Role role, AstNode pos, Match match, Stack backtrackingStack)
+ {
+ return child.DoMatchCollection(role, pos, match, backtrackingStack);
+ }
+ }
}
diff --git a/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/Accessor.cs b/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/Accessor.cs
index c487032ebc..cc5651d871 100644
--- a/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/Accessor.cs
+++ b/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/Accessor.cs
@@ -56,8 +56,12 @@ namespace ICSharpCode.NRefactory.CSharp
get { return GetChildByRole (Roles.Body); }
set { SetChildByRole (Roles.Body, value); }
}
-
- public override S AcceptVisitor (IAstVisitor visitor, T data)
+
+ public AstNodeCollection Parameters {
+ get { return GetChildrenByRole(Roles.Parameter); }
+ }
+
+ public override S AcceptVisitor(IAstVisitor visitor, T data)
{
return visitor.VisitAccessor (this, data);
}
diff --git a/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/AttributedNode.cs b/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/AttributedNode.cs
index 41eec380d1..af5e584dc4 100644
--- a/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/AttributedNode.cs
+++ b/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/AttributedNode.cs
@@ -60,7 +60,7 @@ namespace ICSharpCode.NRefactory.CSharp
protected bool MatchAttributesAndModifiers(AttributedNode o, PatternMatching.Match match)
{
- return this.Modifiers == o.Modifiers && this.Attributes.DoMatch(o.Attributes, match);
+ return (this.Modifiers == Modifiers.Any || this.Modifiers == o.Modifiers) && this.Attributes.DoMatch(o.Attributes, match);
}
}
}
diff --git a/ICSharpCode.NRefactory/CSharp/OutputVisitor/OutputVisitor.cs b/ICSharpCode.NRefactory/CSharp/OutputVisitor/OutputVisitor.cs
index da02c47d5f..bcab463d7a 100644
--- a/ICSharpCode.NRefactory/CSharp/OutputVisitor/OutputVisitor.cs
+++ b/ICSharpCode.NRefactory/CSharp/OutputVisitor/OutputVisitor.cs
@@ -202,8 +202,20 @@ namespace ICSharpCode.NRefactory.CSharp
{
WriteCommaSeparatedListInParenthesis(list.SafeCast(), spaceWithin);
}
+
#endif
-
+
+ void WriteCommaSeparatedListInBrackets(IEnumerable list, bool spaceWithin)
+ {
+ WriteToken("[", AstNode.Roles.LBracket);
+ if (list.Any()) {
+ Space(spaceWithin);
+ WriteCommaSeparatedList(list.SafeCast());
+ Space(spaceWithin);
+ }
+ WriteToken("]", AstNode.Roles.RBracket);
+ }
+
void WriteCommaSeparatedListInBrackets(IEnumerable list)
{
WriteToken("[", AstNode.Roles.LBracket);
@@ -1815,7 +1827,7 @@ namespace ICSharpCode.NRefactory.CSharp
WritePrivateImplementationType(indexerDeclaration.PrivateImplementationType);
WriteKeyword("this");
Space(policy.BeforeMethodDeclarationParentheses);
- WriteCommaSeparatedListInParenthesis(indexerDeclaration.Parameters, policy.WithinMethodDeclarationParentheses);
+ WriteCommaSeparatedListInBrackets(indexerDeclaration.Parameters, policy.WithinMethodDeclarationParentheses);
OpenBrace(policy.PropertyBraceStyle);
// output get/set in their original order
foreach (AstNode node in indexerDeclaration.Children) {