diff --git a/ICSharpCode.NRefactory/CSharp/Ast/AstComparer.cs b/ICSharpCode.NRefactory/CSharp/Ast/AstComparer.cs deleted file mode 100644 index 61d6fd4f1d..0000000000 --- a/ICSharpCode.NRefactory/CSharp/Ast/AstComparer.cs +++ /dev/null @@ -1,44 +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 -{ - /// - /// Compares whether two ASTs are structurally identical. - /// - public static class AstComparer - { - static HashSet nodeTypesWithoutExtraInfo = new HashSet { - 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); - child1 = child1.NextSibling; - child2 = child2.NextSibling; - } - if (nodeTypesWithoutExtraInfo.Contains(nodeType)) - return result; - if (nodeType == typeof(Identifier)) - return ((Identifier)node1).Name == ((Identifier)node2).Name; - return null; - } - } -} diff --git a/ICSharpCode.NRefactory/CSharp/Ast/AstNode.cs b/ICSharpCode.NRefactory/CSharp/Ast/AstNode.cs index bfafd16330..a5361ef4f9 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/AstNode.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/AstNode.cs @@ -25,11 +25,14 @@ // THE SOFTWARE. using System; +using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading; +using ICSharpCode.NRefactory.CSharp.PatternMatching; + namespace ICSharpCode.NRefactory.CSharp { public abstract class AstNode @@ -55,6 +58,11 @@ namespace ICSharpCode.NRefactory.CSharp { return default (S); } + + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + { + return other == null || other.IsNull; + } } #endregion @@ -569,6 +577,37 @@ namespace ICSharpCode.NRefactory.CSharp public abstract S AcceptVisitor (IAstVisitor visitor, T data); + #region Pattern Matching + /// + /// Performs a pattern matching operation. + /// this is the pattern, is the AST that is being matched. + /// + /// + /// If successful, a match object containing the matched groups. + /// If the match failed, returns null. + /// + /// + /// 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 null if the ASTs are not identical. + /// + 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 static readonly Role RootRole = new Role("Root"); diff --git a/ICSharpCode.NRefactory/CSharp/Ast/AstNodeCollection.cs b/ICSharpCode.NRefactory/CSharp/Ast/AstNodeCollection.cs index 89556dca8f..6eca8d993c 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/AstNodeCollection.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/AstNodeCollection.cs @@ -5,13 +5,14 @@ using System; using System.Collections; using System.Collections.Generic; using System.Linq; +using ICSharpCode.NRefactory.CSharp.PatternMatching; namespace ICSharpCode.NRefactory.CSharp { /// /// Represents the children of an AstNode that have a specific role. /// - public struct AstNodeCollection : ICollection where T : AstNode + public class AstNodeCollection : ICollection where T : AstNode { readonly AstNode node; readonly Role role; @@ -152,5 +153,24 @@ namespace ICSharpCode.NRefactory.CSharp return !(left.role == right.role && left.node == right.node); } #endregion + + internal bool DoMatch(AstNodeCollection other, Match match) + { + AstNode cur1 = this.node.FirstChild; + AstNode cur2 = other.node.FirstChild; + while (true) { + while (cur1 != null && cur1.Role != role) + cur1 = cur1.NextSibling; + while (cur2 != null && cur2.Role != role) + cur2 = cur2.NextSibling; + if (cur1 == null || cur2 == null) + break; + if (!cur1.DoMatch(cur2, match)) + return false; + cur1 = cur1.NextSibling; + cur2 = cur2.NextSibling; + } + return cur1 == null && cur2 == null; + } } } diff --git a/ICSharpCode.NRefactory/CSharp/Ast/AstType.cs b/ICSharpCode.NRefactory/CSharp/Ast/AstType.cs index 2c4af725a0..08bf473d4b 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/AstType.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/AstType.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; namespace ICSharpCode.NRefactory.CSharp { @@ -22,6 +23,11 @@ namespace ICSharpCode.NRefactory.CSharp { return default (S); } + + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + { + return other == null || other.IsNull; + } } #endregion diff --git a/ICSharpCode.NRefactory/CSharp/Ast/CSharpTokenNode.cs b/ICSharpCode.NRefactory/CSharp/Ast/CSharpTokenNode.cs index 659875dec6..4e62889636 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/CSharpTokenNode.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/CSharpTokenNode.cs @@ -1,4 +1,4 @@ -// +// // TokenNode.cs // // Author: @@ -46,6 +46,11 @@ namespace ICSharpCode.NRefactory.CSharp { 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); } + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + { + CSharpTokenNode o = other as CSharpTokenNode; + return o != null; + } + public override string ToString () { return string.Format ("[CSharpTokenNode: StartLocation={0}, EndLocation={1}, Role={2}]", StartLocation, EndLocation, Role); diff --git a/ICSharpCode.NRefactory/CSharp/Ast/CompilationUnit.cs b/ICSharpCode.NRefactory/CSharp/Ast/CompilationUnit.cs index 3756d594b2..9a50477191 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/CompilationUnit.cs +++ b/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) { return GetNodeAt (new AstLocation (line, column)); @@ -99,7 +105,6 @@ namespace ICSharpCode.NRefactory.CSharp { return visitor.VisitCompilationUnit (this, data); } - } } diff --git a/ICSharpCode.NRefactory/CSharp/Ast/ComposedType.cs b/ICSharpCode.NRefactory/CSharp/Ast/ComposedType.cs index e4316de30a..ce8ad9879c 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/ComposedType.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/ComposedType.cs @@ -76,6 +76,12 @@ namespace ICSharpCode.NRefactory.CSharp 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() { StringBuilder b = new StringBuilder(); @@ -156,6 +162,12 @@ namespace ICSharpCode.NRefactory.CSharp 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() { return "[" + new string(',', this.Dimensions - 1) + "]"; diff --git a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/AnonymousMethodExpression.cs b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/AnonymousMethodExpression.cs index 324bbff885..b586d91570 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/AnonymousMethodExpression.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/AnonymousMethodExpression.cs @@ -64,5 +64,11 @@ namespace ICSharpCode.NRefactory.CSharp { 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); + } } } diff --git a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/ArgListExpression.cs b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/ArgListExpression.cs index d18d543f18..c84f87389f 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/ArgListExpression.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/ArgListExpression.cs @@ -57,6 +57,12 @@ namespace ICSharpCode.NRefactory.CSharp { 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); + } } } diff --git a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/ArrayCreateExpression.cs b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/ArrayCreateExpression.cs index e4122170e5..6578c58269 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/ArrayCreateExpression.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/ArrayCreateExpression.cs @@ -37,5 +37,11 @@ namespace ICSharpCode.NRefactory.CSharp { 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); + } } } diff --git a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/ArrayInitializerExpression.cs b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/ArrayInitializerExpression.cs index a654ecff7b..3c33d4d7b1 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/ArrayInitializerExpression.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/ArrayInitializerExpression.cs @@ -48,6 +48,11 @@ namespace ICSharpCode.NRefactory.CSharp { return default (S); } + + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + { + return other == null || other.IsNull; + } } #endregion @@ -67,6 +72,12 @@ namespace ICSharpCode.NRefactory.CSharp { 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); + } } } diff --git a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/AsExpression.cs b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/AsExpression.cs index 9880a0f285..b08ecd08dd 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/AsExpression.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/AsExpression.cs @@ -1,4 +1,4 @@ -// +// // AsExpression.cs // // Author: @@ -49,6 +49,12 @@ namespace ICSharpCode.NRefactory.CSharp { 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); + } } } diff --git a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/AssignmentExpression.cs b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/AssignmentExpression.cs index fd0ff5c3cd..f3b31a7508 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/AssignmentExpression.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/AssignmentExpression.cs @@ -1,4 +1,4 @@ -// +// // AssignmentExpression.cs // // Author: @@ -72,6 +72,12 @@ namespace ICSharpCode.NRefactory.CSharp return visitor.VisitAssignmentExpression (this, data); } + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + { + AssignmentExpression o = other as AssignmentExpression; + return o != null && this.Left.DoMatch(o.Left, match) && this.Operator == o.Operator && this.Right.DoMatch(o.Right, match); + } + public static string GetOperatorSymbol(AssignmentOperatorType op) { switch (op) { diff --git a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/BaseReferenceExpression.cs b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/BaseReferenceExpression.cs index ca3f5df240..b75fb95344 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/BaseReferenceExpression.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/BaseReferenceExpression.cs @@ -1,4 +1,4 @@ -// +// // BaseReferenceExpression.cs // // Author: @@ -51,5 +51,11 @@ namespace ICSharpCode.NRefactory.CSharp { return visitor.VisitBaseReferenceExpression (this, data); } + + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + { + BaseReferenceExpression o = other as BaseReferenceExpression; + return o != null; + } } } diff --git a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/BinaryOperatorExpression.cs b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/BinaryOperatorExpression.cs index 551a42001b..ab50392b65 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/BinaryOperatorExpression.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/BinaryOperatorExpression.cs @@ -1,4 +1,4 @@ -// +// // BinaryOperatorExpression.cs // // Author: @@ -72,6 +72,12 @@ namespace ICSharpCode.NRefactory.CSharp return visitor.VisitBinaryOperatorExpression (this, data); } + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + { + BinaryOperatorExpression o = other as BinaryOperatorExpression; + return o != null && this.Left.DoMatch(o.Left, match) && this.Operator == o.Operator && this.Right.DoMatch(o.Right, match); + } + public static string GetOperatorSymbol(BinaryOperatorType op) { switch (op) { diff --git a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/CastExpression.cs b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/CastExpression.cs index 7a737aeaa5..049376d134 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/CastExpression.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/CastExpression.cs @@ -1,4 +1,4 @@ -// +// // CastExpression.cs // // Author: @@ -53,6 +53,12 @@ namespace ICSharpCode.NRefactory.CSharp { 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); + } } } diff --git a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/CheckedExpression.cs b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/CheckedExpression.cs index edb52b3f4c..02b2296445 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/CheckedExpression.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/CheckedExpression.cs @@ -1,4 +1,4 @@ -// +// // CheckedExpression.cs // // Author: @@ -52,5 +52,11 @@ namespace ICSharpCode.NRefactory.CSharp { 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); + } } } diff --git a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/ConditionalExpression.cs b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/ConditionalExpression.cs index 502a56676a..d0c1ddc5d9 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/ConditionalExpression.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/ConditionalExpression.cs @@ -1,4 +1,4 @@ -// +// // ConditionalExpression.cs // // Author: @@ -64,5 +64,11 @@ namespace ICSharpCode.NRefactory.CSharp { 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); + } } } diff --git a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/DefaultValueExpression.cs b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/DefaultValueExpression.cs index 7fa19eea39..d171f86b75 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/DefaultValueExpression.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/DefaultValueExpression.cs @@ -1,4 +1,4 @@ -// +// // DefaultValueExpression.cs // // Author: @@ -52,6 +52,12 @@ namespace ICSharpCode.NRefactory.CSharp { 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); + } } } diff --git a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/DirectionExpression.cs b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/DirectionExpression.cs index f815c45791..5ba19bd6bc 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/DirectionExpression.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/DirectionExpression.cs @@ -1,4 +1,4 @@ -// +// // DirectionExpression.cs // // Author: @@ -56,5 +56,11 @@ namespace ICSharpCode.NRefactory.CSharp { 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); + } } } diff --git a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/Expression.cs b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/Expression.cs index b82530464b..c83e740c2f 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/Expression.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/Expression.cs @@ -31,6 +31,11 @@ namespace ICSharpCode.NRefactory.CSharp { return default (S); } + + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + { + return other == null || other.IsNull; + } } #endregion diff --git a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/IdentifierExpression.cs b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/IdentifierExpression.cs index fce5f9c808..bbc6898c1d 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/IdentifierExpression.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/IdentifierExpression.cs @@ -64,5 +64,11 @@ namespace ICSharpCode.NRefactory.CSharp { 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); + } } } diff --git a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/IndexerExpression.cs b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/IndexerExpression.cs index a5950bb0d6..89ee4ec8bd 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/IndexerExpression.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/IndexerExpression.cs @@ -54,5 +54,11 @@ namespace ICSharpCode.NRefactory.CSharp { 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); + } } } diff --git a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/InvocationExpression.cs b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/InvocationExpression.cs index 7b69440dd2..47f66ac4ec 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/InvocationExpression.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/InvocationExpression.cs @@ -54,5 +54,11 @@ namespace ICSharpCode.NRefactory.CSharp { 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); + } } } diff --git a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/IsExpression.cs b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/IsExpression.cs index fc325d8840..a8c7b0e002 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/IsExpression.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/IsExpression.cs @@ -1,4 +1,4 @@ -// +// // TypeOfIsExpression.cs // // Author: @@ -49,6 +49,12 @@ namespace ICSharpCode.NRefactory.CSharp { 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); + } } } diff --git a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/LambdaExpression.cs b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/LambdaExpression.cs index dff50f074e..774bd6c4a3 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/LambdaExpression.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/LambdaExpression.cs @@ -53,5 +53,11 @@ namespace ICSharpCode.NRefactory.CSharp { 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); + } } } diff --git a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/MemberReferenceExpression.cs b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/MemberReferenceExpression.cs index 43fa24714e..bcc7a71e6f 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/MemberReferenceExpression.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/MemberReferenceExpression.cs @@ -63,5 +63,11 @@ namespace ICSharpCode.NRefactory.CSharp { 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); + } } } diff --git a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/NamedArgumentExpression.cs b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/NamedArgumentExpression.cs index 60152c5334..a390e33ee4 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/NamedArgumentExpression.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/NamedArgumentExpression.cs @@ -28,5 +28,11 @@ namespace ICSharpCode.NRefactory.CSharp { 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); + } } } diff --git a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/NullReferenceExpression.cs b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/NullReferenceExpression.cs index de409e297a..afd309d186 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/NullReferenceExpression.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/NullReferenceExpression.cs @@ -1,4 +1,4 @@ -// +// // NullReferenceExpression.cs // // Author: @@ -35,5 +35,11 @@ namespace ICSharpCode.NRefactory.CSharp { return visitor.VisitNullReferenceExpression (this, data); } + + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + { + NullReferenceExpression o = other as NullReferenceExpression; + return o != null; + } } } diff --git a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/ObjectCreateExpression.cs b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/ObjectCreateExpression.cs index 9b935ce48a..fa113d5301 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/ObjectCreateExpression.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/ObjectCreateExpression.cs @@ -65,5 +65,11 @@ namespace ICSharpCode.NRefactory.CSharp { 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); + } } } diff --git a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/ParenthesizedExpression.cs b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/ParenthesizedExpression.cs index 88a5613272..94219bb8a7 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/ParenthesizedExpression.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/ParenthesizedExpression.cs @@ -1,4 +1,4 @@ -// +// // ParenthesizedExpression.cs // // Author: @@ -48,5 +48,11 @@ namespace ICSharpCode.NRefactory.CSharp { 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); + } } } diff --git a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/PointerReferenceExpression.cs b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/PointerReferenceExpression.cs index e1ee936696..3ac10d3874 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/PointerReferenceExpression.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/PointerReferenceExpression.cs @@ -57,5 +57,11 @@ namespace ICSharpCode.NRefactory.CSharp { 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); + } } } diff --git a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/PrimitiveExpression.cs b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/PrimitiveExpression.cs index 427906cbda..ca1b274434 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/PrimitiveExpression.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/PrimitiveExpression.cs @@ -1,4 +1,4 @@ -// +// // PrimitiveExpression.cs // // Author: @@ -66,5 +66,11 @@ namespace ICSharpCode.NRefactory.CSharp { return visitor.VisitPrimitiveExpression (this, data); } + + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + { + PrimitiveExpression o = other as PrimitiveExpression; + return o != null && object.Equals(this.Value, o.Value); + } } } diff --git a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/QueryExpression.cs b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/QueryExpression.cs index b7f01a473a..79a357e87b 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/QueryExpression.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/QueryExpression.cs @@ -25,6 +25,11 @@ namespace ICSharpCode.NRefactory.CSharp { return default (S); } + + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + { + return other == null || other.IsNull; + } } #endregion @@ -36,6 +41,12 @@ namespace ICSharpCode.NRefactory.CSharp { 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 @@ -43,6 +54,12 @@ namespace ICSharpCode.NRefactory.CSharp public override NodeType NodeType { get { return NodeType.QueryClause; } } + + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + { + QueryClause o = other as QueryClause; + throw new NotImplementedException(); + } } /// @@ -293,6 +310,12 @@ namespace ICSharpCode.NRefactory.CSharp { 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 diff --git a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/SizeOfExpression.cs b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/SizeOfExpression.cs index 5e50627589..2a6e22034a 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/SizeOfExpression.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/SizeOfExpression.cs @@ -1,4 +1,4 @@ -// +// // SizeOfExpression.cs // // Author: @@ -52,5 +52,11 @@ namespace ICSharpCode.NRefactory.CSharp { 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); + } } } diff --git a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/StackAllocExpression.cs b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/StackAllocExpression.cs index ddb7ede92b..ad7fc1a7ef 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/StackAllocExpression.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/StackAllocExpression.cs @@ -1,4 +1,4 @@ -// +// // StackAllocExpression.cs // // Author: @@ -57,5 +57,11 @@ namespace ICSharpCode.NRefactory.CSharp { 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); + } } } diff --git a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/ThisReferenceExpression.cs b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/ThisReferenceExpression.cs index 8c6374d298..5428cf04b9 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/ThisReferenceExpression.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/ThisReferenceExpression.cs @@ -1,4 +1,4 @@ -// +// // ThisReferenceExpression.cs // // Author: @@ -51,5 +51,11 @@ namespace ICSharpCode.NRefactory.CSharp { return visitor.VisitThisReferenceExpression (this, data); } + + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + { + ThisReferenceExpression o = other as ThisReferenceExpression; + return o != null; + } } } diff --git a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/TypeOfExpression.cs b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/TypeOfExpression.cs index c18e5f4747..e6e7c97dcd 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/TypeOfExpression.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/TypeOfExpression.cs @@ -1,4 +1,4 @@ -// +// // TypeOfExpression.cs // // Author: @@ -53,5 +53,11 @@ namespace ICSharpCode.NRefactory.CSharp { 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); + } } } diff --git a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/TypeReferenceExpression.cs b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/TypeReferenceExpression.cs index a543a94ee0..5818340a41 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/TypeReferenceExpression.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/TypeReferenceExpression.cs @@ -20,5 +20,11 @@ namespace ICSharpCode.NRefactory.CSharp { 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); + } } } diff --git a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/UnaryOperatorExpression.cs b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/UnaryOperatorExpression.cs index df36a6ab9a..fe0b2d2648 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/UnaryOperatorExpression.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/UnaryOperatorExpression.cs @@ -1,4 +1,4 @@ -// +// // UnaryOperatorExpression.cs // // Author: @@ -64,6 +64,12 @@ namespace ICSharpCode.NRefactory.CSharp 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) { switch (op) { diff --git a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/UncheckedExpression.cs b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/UncheckedExpression.cs index fd1c162dcc..2165437b3e 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/UncheckedExpression.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/UncheckedExpression.cs @@ -1,4 +1,4 @@ -// +// // UncheckedExpression.cs // // Author: @@ -52,5 +52,11 @@ namespace ICSharpCode.NRefactory.CSharp { 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); + } } } diff --git a/ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/Attribute.cs b/ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/Attribute.cs index 5c08c14912..877771736a 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/Attribute.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/Attribute.cs @@ -52,5 +52,11 @@ namespace ICSharpCode.NRefactory.CSharp { 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); + } } } diff --git a/ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/AttributeSection.cs b/ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/AttributeSection.cs index 17c5e2f7f6..a192718dac 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/AttributeSection.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/AttributeSection.cs @@ -58,6 +58,12 @@ namespace ICSharpCode.NRefactory.CSharp 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) { switch (attributeTarget) { diff --git a/ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/Comment.cs b/ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/Comment.cs index dc27a875aa..4f757b2640 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/Comment.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/Comment.cs @@ -1,4 +1,4 @@ -// +// // Comment.cs // // Author: @@ -86,6 +86,12 @@ namespace ICSharpCode.NRefactory.CSharp { 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); + } } } diff --git a/ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/Constraint.cs b/ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/Constraint.cs index a2de49fffb..514a411922 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/Constraint.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/Constraint.cs @@ -61,6 +61,12 @@ namespace ICSharpCode.NRefactory.CSharp { 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); + } } } diff --git a/ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/NamespaceDeclaration.cs b/ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/NamespaceDeclaration.cs index 8111b5c3dd..41cc39253f 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/NamespaceDeclaration.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/NamespaceDeclaration.cs @@ -100,5 +100,11 @@ namespace ICSharpCode.NRefactory.CSharp { 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); + } } }; diff --git a/ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/TypeParameterDeclaration.cs b/ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/TypeParameterDeclaration.cs index c089f360d2..30e2fdf2fa 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/TypeParameterDeclaration.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/TypeParameterDeclaration.cs @@ -38,5 +38,11 @@ namespace ICSharpCode.NRefactory.CSharp { 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); + } } } diff --git a/ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/UsingAliasDeclaration.cs b/ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/UsingAliasDeclaration.cs index 0445373963..41aee352d6 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/UsingAliasDeclaration.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/UsingAliasDeclaration.cs @@ -1,4 +1,4 @@ -// +// // UsingAliasDeclaration.cs // // Author: @@ -70,5 +70,11 @@ namespace ICSharpCode.NRefactory.CSharp { 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); + } } } diff --git a/ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/UsingDeclaration.cs b/ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/UsingDeclaration.cs index 68ff822b3a..12beb31bec 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/UsingDeclaration.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/UsingDeclaration.cs @@ -1,4 +1,4 @@ -// +// // UsingDeclaration.cs // // Author: @@ -64,5 +64,11 @@ namespace ICSharpCode.NRefactory.CSharp { 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); + } } } diff --git a/ICSharpCode.NRefactory/CSharp/Ast/Identifier.cs b/ICSharpCode.NRefactory/CSharp/Ast/Identifier.cs index 94656e5ab0..f63e97bf74 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/Identifier.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/Identifier.cs @@ -1,4 +1,4 @@ -// +// // Identifier.cs // // Author: @@ -91,5 +91,11 @@ namespace ICSharpCode.NRefactory.CSharp { 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); + } } } diff --git a/ICSharpCode.NRefactory/CSharp/Ast/MemberType.cs b/ICSharpCode.NRefactory/CSharp/Ast/MemberType.cs index cf5f1dd8f1..70448e56a9 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/MemberType.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/MemberType.cs @@ -60,6 +60,12 @@ namespace ICSharpCode.NRefactory.CSharp 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() { StringBuilder b = new StringBuilder(); diff --git a/ICSharpCode.NRefactory/CSharp/Ast/NodeType.cs b/ICSharpCode.NRefactory/CSharp/Ast/NodeType.cs index d5d56fb4ca..946b838d6b 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/NodeType.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/NodeType.cs @@ -43,7 +43,8 @@ namespace ICSharpCode.NRefactory.CSharp Statement, Expression, Token, - QueryClause + QueryClause, + Pattern } } diff --git a/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/AnyNode.cs b/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/AnyNode.cs new file mode 100644 index 0000000000..028e7d7fda --- /dev/null +++ b/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/AnyNode.cs @@ -0,0 +1,26 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) + +using System; + +namespace ICSharpCode.NRefactory.CSharp.PatternMatching +{ + /// + /// Matches any node. + /// + public class AnyNode : Pattern + { + readonly string 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; + } + } +} diff --git a/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Backreference.cs b/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Backreference.cs new file mode 100644 index 0000000000..c5573f01aa --- /dev/null +++ b/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Backreference.cs @@ -0,0 +1,28 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) + +using System; +using System.Linq; + +namespace ICSharpCode.NRefactory.CSharp.PatternMatching +{ + /// + /// Matches the last entry in the specified named group. + /// + public class Backreference : Pattern + { + readonly string 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[referencedGroupName].Last().Match(other) != null; + } + } +} diff --git a/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Choice.cs b/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Choice.cs new file mode 100644 index 0000000000..ba0954884d --- /dev/null +++ b/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Choice.cs @@ -0,0 +1,33 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) + +using System; + +namespace ICSharpCode.NRefactory.CSharp.PatternMatching +{ + /// + /// Matches one of several alternatives. + /// + public class Choice : Pattern + { + public static readonly Role AlternativeRole = new Role("Alternative", AstNode.Null); + + public Choice(params AstNode[] alternatives) + { + foreach (AstNode node in alternatives) + AddChild(node, 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; + } + } +} diff --git a/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Match.cs b/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Match.cs new file mode 100644 index 0000000000..4a44dc36fb --- /dev/null +++ b/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Match.cs @@ -0,0 +1,43 @@ +// 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 +{ + /// + /// Represents the result of a pattern matching operation. + /// + public sealed class Match + { + List> results = new List>(); + + internal int CheckPoint() + { + return results.Count; + } + + internal void RestoreCheckPoint(int checkPoint) + { + results.RemoveRange(checkPoint, results.Count - checkPoint); + } + + public IEnumerable this[string groupName] { + get { + foreach (var pair in results) { + if (pair.Key == groupName) + yield return pair.Value; + } + } + } + + public void Add(string groupName, AstNode node) + { + if (groupName != null && node != null) { + results.Add(new KeyValuePair(groupName, node)); + } + } + } +} diff --git a/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/NamedGroup.cs b/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/NamedGroup.cs new file mode 100644 index 0000000000..5cf361a6ec --- /dev/null +++ b/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/NamedGroup.cs @@ -0,0 +1,29 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) + +using System; + +namespace ICSharpCode.NRefactory.CSharp.PatternMatching +{ + /// + /// Represents a named node within a pattern. + /// + public class NamedNode : Pattern + { + public static readonly Role ElementRole = new Role("Element", AstNode.Null); + + readonly string 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); + } + } +} diff --git a/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Pattern.cs b/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Pattern.cs new file mode 100644 index 0000000000..794806a86a --- /dev/null +++ b/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Pattern.cs @@ -0,0 +1,42 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) + +using System; + +namespace ICSharpCode.NRefactory.CSharp.PatternMatching +{ + /// + /// Base class for all patterns. + /// + public abstract class Pattern : AstNode + { + public override NodeType NodeType { + get { return NodeType.Pattern; } + } + + public override S AcceptVisitor(IAstVisitor visitor, T data) + { + return default(S); + } + + public AstType ToType() + { + return new TypePlaceholder(this); + } + + public Expression ToExpression() + { + return new ExpressionPlaceholder(this); + } + + public BlockStatement ToBlock() + { + return new BlockStatementPlaceholder(this); + } + + public VariableInitializer ToVariable() + { + return new VariablePlaceholder(this); + } + } +} diff --git a/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Placeholder.cs b/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Placeholder.cs new file mode 100644 index 0000000000..16ca73cef0 --- /dev/null +++ b/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 PatternRole = new Role("Pattern"); + + public TypePlaceholder(Pattern pattern) + { + AddChild(pattern, TypePlaceholder.PatternRole); + } + + public override NodeType NodeType { + get { return NodeType.Pattern; } + } + + public override S AcceptVisitor(IAstVisitor visitor, T data) + { + return default(S); + } + + protected internal override bool DoMatch(AstNode other, Match match) + { + return GetChildByRole(TypePlaceholder.PatternRole).DoMatch(other, match); + } + } + + sealed class ExpressionPlaceholder : Expression + { + public ExpressionPlaceholder(Pattern pattern) + { + AddChild(pattern, TypePlaceholder.PatternRole); + } + + public override NodeType NodeType { + get { return NodeType.Pattern; } + } + + public override S AcceptVisitor(IAstVisitor visitor, T data) + { + return default(S); + } + + protected internal override bool DoMatch(AstNode other, Match match) + { + return GetChildByRole(TypePlaceholder.PatternRole).DoMatch(other, match); + } + } + + sealed class StatementPlaceholder : Statement + { + public StatementPlaceholder(Pattern pattern) + { + AddChild(pattern, TypePlaceholder.PatternRole); + } + + public override NodeType NodeType { + get { return NodeType.Pattern; } + } + + public override S AcceptVisitor(IAstVisitor visitor, T data) + { + return default(S); + } + + protected internal override bool DoMatch(AstNode other, Match match) + { + return GetChildByRole(TypePlaceholder.PatternRole).DoMatch(other, match); + } + } + + sealed class BlockStatementPlaceholder : BlockStatement + { + public BlockStatementPlaceholder(Pattern pattern) + { + AddChild(pattern, TypePlaceholder.PatternRole); + } + + public override NodeType NodeType { + get { return NodeType.Pattern; } + } + + public override S AcceptVisitor(IAstVisitor visitor, T data) + { + return default(S); + } + + protected internal override bool DoMatch(AstNode other, Match match) + { + return GetChildByRole(TypePlaceholder.PatternRole).DoMatch(other, match); + } + } + + sealed class VariablePlaceholder : VariableInitializer + { + public VariablePlaceholder(Pattern pattern) + { + AddChild(pattern, TypePlaceholder.PatternRole); + } + + public override NodeType NodeType { + get { return NodeType.Pattern; } + } + + public override S AcceptVisitor(IAstVisitor visitor, T data) + { + return default(S); + } + + protected internal override bool DoMatch(AstNode other, Match match) + { + return GetChildByRole(TypePlaceholder.PatternRole).DoMatch(other, match); + } + } +} diff --git a/ICSharpCode.NRefactory/CSharp/Ast/PrimitiveType.cs b/ICSharpCode.NRefactory/CSharp/Ast/PrimitiveType.cs index 6bc7d0f733..2a2b41dff5 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/PrimitiveType.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/PrimitiveType.cs @@ -1,4 +1,4 @@ -// +// // FullTypeName.cs // // Author: @@ -65,6 +65,12 @@ namespace ICSharpCode.NRefactory.CSharp 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() { return Keyword ?? base.ToString(); diff --git a/ICSharpCode.NRefactory/CSharp/Ast/SimpleType.cs b/ICSharpCode.NRefactory/CSharp/Ast/SimpleType.cs index ec6db27f16..55839229ce 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/SimpleType.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/SimpleType.cs @@ -65,6 +65,12 @@ namespace ICSharpCode.NRefactory.CSharp 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() { StringBuilder b = new StringBuilder(this.Identifier); diff --git a/ICSharpCode.NRefactory/CSharp/Ast/Statements/BlockStatement.cs b/ICSharpCode.NRefactory/CSharp/Ast/Statements/BlockStatement.cs index 5d02ebea77..57865e586c 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/Statements/BlockStatement.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/Statements/BlockStatement.cs @@ -49,6 +49,11 @@ namespace ICSharpCode.NRefactory.CSharp { return default (S); } + + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + { + return other == null || other.IsNull; + } } #endregion @@ -69,6 +74,12 @@ namespace ICSharpCode.NRefactory.CSharp 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 public void AddStatement(Statement statement) { diff --git a/ICSharpCode.NRefactory/CSharp/Ast/Statements/BreakStatement.cs b/ICSharpCode.NRefactory/CSharp/Ast/Statements/BreakStatement.cs index b6ce929b0b..6599b5eafc 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/Statements/BreakStatement.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/Statements/BreakStatement.cs @@ -1,6 +1,6 @@ -// +// // BreakStatement.cs -// +// // Author: // Mike Krüger // @@ -39,5 +39,11 @@ namespace ICSharpCode.NRefactory.CSharp { return visitor.VisitBreakStatement (this, data); } + + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + { + BreakStatement o = other as BreakStatement; + return o != null; + } } } diff --git a/ICSharpCode.NRefactory/CSharp/Ast/Statements/ExpressionStatement.cs b/ICSharpCode.NRefactory/CSharp/Ast/Statements/ExpressionStatement.cs index 5c6cd41d7b..4e76bd5bbe 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/Statements/ExpressionStatement.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/Statements/ExpressionStatement.cs @@ -1,4 +1,4 @@ -// +// // ExpressionStatement.cs // // Author: @@ -44,5 +44,20 @@ namespace ICSharpCode.NRefactory.CSharp { 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); + } } } diff --git a/ICSharpCode.NRefactory/CSharp/Ast/Statements/IfElseStatement.cs b/ICSharpCode.NRefactory/CSharp/Ast/Statements/IfElseStatement.cs index 85569dfac8..8fa84392d7 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/Statements/IfElseStatement.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/Statements/IfElseStatement.cs @@ -1,4 +1,4 @@ -// +// // IfElseStatement.cs // // Author: @@ -74,6 +74,12 @@ namespace ICSharpCode.NRefactory.CSharp 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() { } diff --git a/ICSharpCode.NRefactory/CSharp/Ast/Statements/Statement.cs b/ICSharpCode.NRefactory/CSharp/Ast/Statements/Statement.cs index c3341e2c5e..1725255f42 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/Statements/Statement.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/Statements/Statement.cs @@ -29,6 +29,11 @@ namespace ICSharpCode.NRefactory.CSharp { return default (S); } + + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + { + return other == null || other.IsNull; + } } #endregion @@ -47,5 +52,10 @@ namespace ICSharpCode.NRefactory.CSharp public override NodeType NodeType { get { return NodeType.Statement; } } + + protected internal override bool DoMatch(AstNode other, ICSharpCode.NRefactory.CSharp.PatternMatching.Match match) + { + throw new NotImplementedException(); + } } } diff --git a/ICSharpCode.NRefactory/CSharp/Ast/Statements/SwitchStatement.cs b/ICSharpCode.NRefactory/CSharp/Ast/Statements/SwitchStatement.cs index ed8a9df02a..f8218d507e 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/Statements/SwitchStatement.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/Statements/SwitchStatement.cs @@ -93,6 +93,12 @@ namespace ICSharpCode.NRefactory.CSharp { 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 @@ -112,5 +118,11 @@ namespace ICSharpCode.NRefactory.CSharp { 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); + } } } diff --git a/ICSharpCode.NRefactory/CSharp/Ast/Statements/TryCatchStatement.cs b/ICSharpCode.NRefactory/CSharp/Ast/Statements/TryCatchStatement.cs index a50662dd4a..bfba09de29 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/Statements/TryCatchStatement.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/Statements/TryCatchStatement.cs @@ -66,6 +66,12 @@ namespace ICSharpCode.NRefactory.CSharp { 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); + } } /// @@ -115,5 +121,11 @@ namespace ICSharpCode.NRefactory.CSharp { 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); + } } } diff --git a/ICSharpCode.NRefactory/CSharp/Ast/Statements/VariableDeclarationStatement.cs b/ICSharpCode.NRefactory/CSharp/Ast/Statements/VariableDeclarationStatement.cs index 084ea12bf5..e5066c1c31 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/Statements/VariableDeclarationStatement.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/Statements/VariableDeclarationStatement.cs @@ -65,5 +65,11 @@ namespace ICSharpCode.NRefactory.CSharp { 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); + } } } diff --git a/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/Accessor.cs b/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/Accessor.cs index 05eec5e0f2..910aec75fb 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/Accessor.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/Accessor.cs @@ -1,4 +1,4 @@ -// +// // PropertyDeclaration.cs // // Author: @@ -24,6 +24,8 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. +using System; + namespace ICSharpCode.NRefactory.CSharp { /// @@ -59,5 +61,10 @@ namespace ICSharpCode.NRefactory.CSharp { return visitor.VisitAccessor (this, data); } + + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + { + throw new NotImplementedException(); + } } } diff --git a/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/AttributedNode.cs b/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/AttributedNode.cs index 1f8db8fce2..1b878d91ce 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/AttributedNode.cs +++ b/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) // This code is distributed under MIT X11 license (for details please see \doc\license.txt) +using System; using System.Collections.Generic; using System.Linq; @@ -56,5 +57,10 @@ namespace ICSharpCode.NRefactory.CSharp } } } + + protected internal override bool DoMatch(AstNode other, ICSharpCode.NRefactory.CSharp.PatternMatching.Match match) + { + throw new NotImplementedException(); + } } } diff --git a/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/ConstructorDeclaration.cs b/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/ConstructorDeclaration.cs index ec81013909..97f808051d 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/ConstructorDeclaration.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/ConstructorDeclaration.cs @@ -33,6 +33,13 @@ namespace ICSharpCode.NRefactory.CSharp { public static readonly Role InitializerRole = new Role("Initializer", ConstructorInitializer.Null); + /// + /// 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. + /// + public string Name { get; set; } + public CSharpTokenNode LParToken { get { return GetChildByRole (Roles.LPar); } } @@ -112,5 +119,11 @@ namespace ICSharpCode.NRefactory.CSharp { 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); + } } } diff --git a/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/DestructorDeclaration.cs b/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/DestructorDeclaration.cs index 2336d46d28..2798d0660c 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/DestructorDeclaration.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/DestructorDeclaration.cs @@ -1,4 +1,4 @@ -// +// // DestructorDeclaration.cs // // Author: @@ -34,6 +34,13 @@ namespace ICSharpCode.NRefactory.CSharp get { return GetChildByRole (TildeRole); } } + /// + /// 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. + /// + public string Name { get; set; } + public CSharpTokenNode LParToken { get { return GetChildByRole (Roles.LPar); } } diff --git a/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/ParameterDeclaration.cs b/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/ParameterDeclaration.cs index 6ae4994e82..0334d2a3fb 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/ParameterDeclaration.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/ParameterDeclaration.cs @@ -81,6 +81,12 @@ namespace ICSharpCode.NRefactory.CSharp { return visitor.VisitParameterDeclaration (this, data); } + + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + { + ParameterDeclaration o = other as ParameterDeclaration; + return o != null && this.Attributes.DoMatch(o.Attributes, match) && this.ParameterModifier == o.ParameterModifier && MatchString(this.Name, o.Name) && this.DefaultExpression.DoMatch(o.DefaultExpression, match); + } } } diff --git a/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/VariableInitializer.cs b/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/VariableInitializer.cs index 745a03b7dd..860f52f36c 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/VariableInitializer.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/VariableInitializer.cs @@ -1,4 +1,4 @@ -// +// // VariableInitializer.cs // // Author: @@ -66,5 +66,11 @@ namespace ICSharpCode.NRefactory.CSharp { return visitor.VisitVariableInitializer (this, data); } + + protected internal override bool DoMatch(AstNode other, ICSharpCode.NRefactory.CSharp.PatternMatching.Match match) + { + VariableInitializer o = other as VariableInitializer; + return o != null && MatchString(this.Name, o.Name) && this.Initializer.DoMatch(o.Initializer, match); + } } } diff --git a/ICSharpCode.NRefactory/CSharp/OutputVisitor/OutputVisitor.cs b/ICSharpCode.NRefactory/CSharp/OutputVisitor/OutputVisitor.cs index 397fe30720..42f049978b 100644 --- a/ICSharpCode.NRefactory/CSharp/OutputVisitor/OutputVisitor.cs +++ b/ICSharpCode.NRefactory/CSharp/OutputVisitor/OutputVisitor.cs @@ -263,7 +263,7 @@ namespace ICSharpCode.NRefactory.CSharp /// void Semicolon() { - if (!(currentContainerNode.Parent is ForStatement)) { + if (currentContainerNode.Role != ForStatement.InitializerRole && currentContainerNode.Role != ForStatement.IteratorRole && currentContainerNode.Role != UsingStatement.ResourceAcquisitionRole) { WriteToken(";", AstNode.Roles.Semicolon); NewLine(); } @@ -1626,9 +1626,7 @@ namespace ICSharpCode.NRefactory.CSharp WriteAttributes(constructorDeclaration.Attributes); WriteModifiers(constructorDeclaration.ModifierTokens); TypeDeclaration type = constructorDeclaration.Parent as TypeDeclaration; - if (type != null) { - WriteIdentifier(type.Name); - } + WriteIdentifier(type != null ? type.Name : constructorDeclaration.Name); Space(policy.BeforeConstructorDeclarationParentheses); WriteCommaSeparatedListInParenthesis(constructorDeclaration.Parameters, policy.WithinMethodDeclarationParentheses); if (!constructorDeclaration.Initializer.IsNull) { @@ -1661,9 +1659,7 @@ namespace ICSharpCode.NRefactory.CSharp WriteModifiers(destructorDeclaration.ModifierTokens); WriteToken("~", DestructorDeclaration.TildeRole); TypeDeclaration type = destructorDeclaration.Parent as TypeDeclaration; - if (type != null) { - WriteIdentifier(type.Name); - } + WriteIdentifier(type != null ? type.Name : destructorDeclaration.Name); Space(policy.BeforeConstructorDeclarationParentheses); LPar(); RPar(); diff --git a/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj b/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj index e4a78e9376..672aa85691 100644 --- a/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj +++ b/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj @@ -55,7 +55,6 @@ - @@ -96,6 +95,13 @@ + + + + + + + @@ -336,6 +342,7 @@ +