diff --git a/NRefactory/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/IPatternAstVisitor.cs b/NRefactory/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/IPatternAstVisitor.cs index 7b29a00c4..6a08be6e3 100644 --- a/NRefactory/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/IPatternAstVisitor.cs +++ b/NRefactory/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/IPatternAstVisitor.cs @@ -17,6 +17,7 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching S VisitChoice(Choice choice, T data); S VisitNamedNode(NamedNode namedNode, T data); S VisitRepeat(Repeat repeat, T data); + S VisitOptionalNode(OptionalNode optionalNode, T data); S VisitIdentifierExpressionBackreference(IdentifierExpressionBackreference identifierExpressionBackreference, T data); } } diff --git a/NRefactory/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/OptionalNode.cs b/NRefactory/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/OptionalNode.cs new file mode 100644 index 000000000..349f4393d --- /dev/null +++ b/NRefactory/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/OptionalNode.cs @@ -0,0 +1,42 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using System.Diagnostics; + +namespace ICSharpCode.NRefactory.CSharp.PatternMatching +{ + public class OptionalNode : Pattern + { + public static readonly Role ElementRole = new Role("Element", AstNode.Null); + + public OptionalNode(AstNode childNode) + { + AddChild(childNode, ElementRole); + } + + public OptionalNode(string groupName, AstNode childNode) : this(new NamedNode(groupName, childNode)) + { + } + + internal override bool DoMatchCollection(Role role, AstNode pos, Match match, Stack backtrackingStack) + { + backtrackingStack.Push(new PossibleMatch(pos, match.CheckPoint())); + return GetChildByRole(ElementRole).DoMatch(pos, match); + } + + protected internal override bool DoMatch(AstNode other, Match match) + { + if (other == null || other.IsNull) + return true; + else + return GetChildByRole(ElementRole).DoMatch(other, match); + } + + public override S AcceptVisitor(IAstVisitor visitor, T data) + { + return ((IPatternAstVisitor)visitor).VisitOptionalNode(this, data); + } + } +} diff --git a/NRefactory/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Pattern.cs b/NRefactory/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Pattern.cs index ed2122d19..aa8d95fb7 100644 --- a/NRefactory/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Pattern.cs +++ b/NRefactory/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Pattern.cs @@ -74,6 +74,11 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching return p != null ? new AttributeSectionPlaceholder(p) : null; } + public static implicit operator SwitchSection(Pattern p) + { + return p != null ? new SwitchSectionPlaceholder(p) : null; + } + // Make debugging easier by giving Patterns a ToString() implementation public override string ToString() { diff --git a/NRefactory/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Placeholder.cs b/NRefactory/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Placeholder.cs index 67987595f..2e3c2b592 100644 --- a/NRefactory/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Placeholder.cs +++ b/NRefactory/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Placeholder.cs @@ -181,4 +181,33 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching return child.DoMatchCollection(role, pos, match, backtrackingStack); } } + + sealed class SwitchSectionPlaceholder : SwitchSection + { + readonly AstNode child; + + public SwitchSectionPlaceholder(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/NRefactory/ICSharpCode.NRefactory/CSharp/OutputVisitor/OutputVisitor.cs b/NRefactory/ICSharpCode.NRefactory/CSharp/OutputVisitor/OutputVisitor.cs index bcab463d7..f12d3ffac 100644 --- a/NRefactory/ICSharpCode.NRefactory/CSharp/OutputVisitor/OutputVisitor.cs +++ b/NRefactory/ICSharpCode.NRefactory/CSharp/OutputVisitor/OutputVisitor.cs @@ -2170,6 +2170,16 @@ namespace ICSharpCode.NRefactory.CSharp RPar(); return EndNode(repeat); } + + object IPatternAstVisitor.VisitOptionalNode(OptionalNode optionalNode, object data) + { + StartNode(optionalNode); + WriteKeyword("optional"); + LPar(); + optionalNode.GetChildByRole(OptionalNode.ElementRole).AcceptVisitor(this, data); + RPar(); + return EndNode(optionalNode); + } #endregion } } diff --git a/NRefactory/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj b/NRefactory/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj index 6dcddc310..b72cd1146 100644 --- a/NRefactory/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj +++ b/NRefactory/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj @@ -107,6 +107,7 @@ +