Browse Source

Add visitor support to pattern nodes (IPatternAstVisitor). Add pattern support to output visitor (makes debugging easier if you can print out patterns)

pull/37/head
Daniel Grunwald 15 years ago
parent
commit
fe173eff59
  1. 2
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/AstNodeCollection.cs
  2. 9
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/Expressions/Expression.cs
  3. 3
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/NodeType.cs
  4. 9
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/AnyNode.cs
  5. 18
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Backreference.cs
  6. 13
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Choice.cs
  7. 22
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/IPatternAstVisitor.cs
  8. 9
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/NamedNode.cs
  9. 14
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Pattern.cs
  10. 20
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Placeholder.cs
  11. 5
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Repeat.cs
  12. 90
      NRefactory/ICSharpCode.NRefactory/CSharp/OutputVisitor/OutputVisitor.cs
  13. 3
      NRefactory/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj

2
NRefactory/ICSharpCode.NRefactory/CSharp/Ast/AstNodeCollection.cs

@ -175,7 +175,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -175,7 +175,7 @@ namespace ICSharpCode.NRefactory.CSharp
break;
Pattern pattern = cur1 as Pattern;
if (pattern == null && cur1.NodeType == NodeType.Pattern)
if (pattern == null && cur1.NodeType == NodeType.Placeholder)
pattern = cur1.GetChildByRole(TypePlaceholder.ChildRole) as Pattern;
if (pattern != null) {
Debug.Assert(stack.Count == patternStack.Count);

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

@ -3,6 +3,7 @@ @@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace ICSharpCode.NRefactory.CSharp
@ -50,6 +51,14 @@ namespace ICSharpCode.NRefactory.CSharp @@ -50,6 +51,14 @@ namespace ICSharpCode.NRefactory.CSharp
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)
{
if (replaceFunction == null)

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

@ -44,7 +44,8 @@ namespace ICSharpCode.NRefactory.CSharp @@ -44,7 +44,8 @@ namespace ICSharpCode.NRefactory.CSharp
Expression,
Token,
QueryClause,
Pattern
Pattern,
Placeholder
}
}

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

@ -12,6 +12,10 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching @@ -12,6 +12,10 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching
{
readonly string groupName;
public string GroupName {
get { return groupName; }
}
public AnyNode(string groupName = null)
{
this.groupName = groupName;
@ -22,5 +26,10 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching @@ -22,5 +26,10 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching
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);
}
}
}

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

@ -13,6 +13,10 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching @@ -13,6 +13,10 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching
{
readonly string referencedGroupName;
public string ReferencedGroupName {
get { return referencedGroupName; }
}
public Backreference(string referencedGroupName)
{
if (referencedGroupName == null)
@ -24,6 +28,11 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching @@ -24,6 +28,11 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching
{
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>
@ -33,6 +42,10 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching @@ -33,6 +42,10 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching
{
readonly string referencedGroupName;
public string ReferencedGroupName {
get { return referencedGroupName; }
}
public IdentifierExpressionBackreference(string referencedGroupName)
{
if (referencedGroupName == null)
@ -48,5 +61,10 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching @@ -48,5 +61,10 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching
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);
}
}
}

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

@ -3,13 +3,14 @@ @@ -3,13 +3,14 @@
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
public class Choice : Pattern, IEnumerable<AstNode>
{
public static readonly Role<AstNode> AlternativeRole = new Role<AstNode>("Alternative", AstNode.Null);
@ -35,9 +36,19 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching @@ -35,9 +36,19 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching
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
NRefactory/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/IPatternAstVisitor.cs

@ -0,0 +1,22 @@ @@ -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);
}
}

9
NRefactory/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/NamedGroup.cs → NRefactory/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/NamedNode.cs

@ -14,6 +14,10 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching @@ -14,6 +14,10 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching
readonly string groupName;
public string GroupName {
get { return groupName; }
}
public NamedNode(string groupName, AstNode childNode)
{
this.groupName = groupName;
@ -25,5 +29,10 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching @@ -25,5 +29,10 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching
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);
}
}
}

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

@ -4,6 +4,7 @@ @@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
namespace ICSharpCode.NRefactory.CSharp.PatternMatching
{
@ -33,11 +34,6 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching @@ -33,11 +34,6 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching
return DoMatch(pos, match);
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return default(S);
}
public AstType ToType()
{
return new TypePlaceholder(this);
@ -62,5 +58,13 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching @@ -62,5 +58,13 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching
{
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();
}
}
}

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

@ -15,12 +15,12 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching @@ -15,12 +15,12 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching
}
public override NodeType NodeType {
get { return GetChildByRole(TypePlaceholder.ChildRole).NodeType; }
get { return NodeType.Placeholder; }
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return GetChildByRole(TypePlaceholder.ChildRole).AcceptVisitor(visitor, data);
return ((IPatternAstVisitor<T, S>)visitor).VisitPlaceholder(this, GetChildByRole(TypePlaceholder.ChildRole), data);
}
protected internal override bool DoMatch(AstNode other, Match match)
@ -37,12 +37,12 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching @@ -37,12 +37,12 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching
}
public override NodeType NodeType {
get { return GetChildByRole(TypePlaceholder.ChildRole).NodeType; }
get { return NodeType.Placeholder; }
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return GetChildByRole(TypePlaceholder.ChildRole).AcceptVisitor(visitor, data);
return ((IPatternAstVisitor<T, S>)visitor).VisitPlaceholder(this, GetChildByRole(TypePlaceholder.ChildRole), data);
}
protected internal override bool DoMatch(AstNode other, Match match)
@ -59,12 +59,12 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching @@ -59,12 +59,12 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching
}
public override NodeType NodeType {
get { return GetChildByRole(TypePlaceholder.ChildRole).NodeType; }
get { return NodeType.Placeholder; }
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return GetChildByRole(TypePlaceholder.ChildRole).AcceptVisitor(visitor, data);
return ((IPatternAstVisitor<T, S>)visitor).VisitPlaceholder(this, GetChildByRole(TypePlaceholder.ChildRole), data);
}
protected internal override bool DoMatch(AstNode other, Match match)
@ -81,12 +81,12 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching @@ -81,12 +81,12 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching
}
public override NodeType NodeType {
get { return GetChildByRole(TypePlaceholder.ChildRole).NodeType; }
get { return NodeType.Placeholder; }
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return GetChildByRole(TypePlaceholder.ChildRole).AcceptVisitor(visitor, data);
return ((IPatternAstVisitor<T, S>)visitor).VisitPlaceholder(this, GetChildByRole(TypePlaceholder.ChildRole), data);
}
protected internal override bool DoMatch(AstNode other, Match match)
@ -103,12 +103,12 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching @@ -103,12 +103,12 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching
}
public override NodeType NodeType {
get { return GetChildByRole(TypePlaceholder.ChildRole).NodeType; }
get { return NodeType.Placeholder; }
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return GetChildByRole(TypePlaceholder.ChildRole).AcceptVisitor(visitor, data);
return ((IPatternAstVisitor<T, S>)visitor).VisitPlaceholder(this, GetChildByRole(TypePlaceholder.ChildRole), data);
}
protected internal override bool DoMatch(AstNode other, Match match)

5
NRefactory/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Repeat.cs

@ -46,5 +46,10 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching @@ -46,5 +46,10 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching
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);
}
}
}

90
NRefactory/ICSharpCode.NRefactory/CSharp/OutputVisitor/OutputVisitor.cs

@ -8,6 +8,8 @@ using System.Globalization; @@ -8,6 +8,8 @@ using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using ICSharpCode.NRefactory.CSharp.PatternMatching;
using ICSharpCode.NRefactory.TypeSystem;
namespace ICSharpCode.NRefactory.CSharp
@ -15,7 +17,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -15,7 +17,7 @@ namespace ICSharpCode.NRefactory.CSharp
/// <summary>
/// Outputs the AST.
/// </summary>
public class OutputVisitor : IAstVisitor<object, object>
public class OutputVisitor : IPatternAstVisitor<object, object>
{
readonly IOutputFormatter formatter;
readonly CSharpFormattingPolicy policy;
@ -1989,5 +1991,91 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1989,5 +1991,91 @@ namespace ICSharpCode.NRefactory.CSharp
return EndNode(identifier);
}
#endregion
#region Pattern Nodes
object IPatternAstVisitor<object, object>.VisitPlaceholder(AstNode placeholder, AstNode child, object data)
{
StartNode(placeholder);
child.AcceptVisitor(this, data);
return EndNode(placeholder);
}
object IPatternAstVisitor<object, object>.VisitAnyNode(AnyNode anyNode, object data)
{
StartNode(anyNode);
if (!string.IsNullOrEmpty(anyNode.GroupName)) {
WriteIdentifier(anyNode.GroupName);
WriteToken(":", AstNode.Roles.Colon);
}
WriteKeyword("anyNode");
return EndNode(anyNode);
}
object IPatternAstVisitor<object, object>.VisitBackreference(Backreference backreference, object data)
{
StartNode(backreference);
WriteKeyword("backreference");
LPar();
WriteIdentifier(backreference.ReferencedGroupName);
RPar();
return EndNode(backreference);
}
object IPatternAstVisitor<object, object>.VisitIdentifierExpressionBackreference(IdentifierExpressionBackreference identifierExpressionBackreference, object data)
{
StartNode(identifierExpressionBackreference);
WriteKeyword("identifierBackreference");
LPar();
WriteIdentifier(identifierExpressionBackreference.ReferencedGroupName);
RPar();
return EndNode(identifierExpressionBackreference);
}
object IPatternAstVisitor<object, object>.VisitChoice(Choice choice, object data)
{
StartNode(choice);
WriteKeyword("choice");
Space();
LPar();
NewLine();
formatter.Indent();
foreach (AstNode alternative in choice) {
alternative.AcceptVisitor(this, data);
if (alternative != choice.LastChild)
WriteToken(",", AstNode.Roles.Comma);
NewLine();
}
formatter.Unindent();
RPar();
return EndNode(choice);
}
object IPatternAstVisitor<object, object>.VisitNamedNode(NamedNode namedNode, object data)
{
StartNode(namedNode);
if (!string.IsNullOrEmpty(namedNode.GroupName)) {
WriteIdentifier(namedNode.GroupName);
WriteToken(":", AstNode.Roles.Colon);
}
namedNode.GetChildByRole(NamedNode.ElementRole).AcceptVisitor(this, data);
return EndNode(namedNode);
}
object IPatternAstVisitor<object, object>.VisitRepeat(Repeat repeat, object data)
{
StartNode(repeat);
WriteKeyword("repeat");
LPar();
if (repeat.MinCount != 0 || repeat.MaxCount != int.MaxValue) {
WriteIdentifier(repeat.MinCount.ToString());
WriteToken(",", AstNode.Roles.Comma);
WriteIdentifier(repeat.MaxCount.ToString());
WriteToken(",", AstNode.Roles.Comma);
}
repeat.GetChildByRole(Repeat.ElementRole).AcceptVisitor(this, data);
RPar();
return EndNode(repeat);
}
#endregion
}
}

3
NRefactory/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj

@ -98,8 +98,9 @@ @@ -98,8 +98,9 @@
<Compile Include="CSharp\Ast\PatternMatching\Choice.cs" />
<Compile Include="CSharp\Ast\PatternMatching\AnyNode.cs" />
<Compile Include="CSharp\Ast\PatternMatching\Backreference.cs" />
<Compile Include="CSharp\Ast\PatternMatching\IPatternAstVisitor.cs" />
<Compile Include="CSharp\Ast\PatternMatching\Match.cs" />
<Compile Include="CSharp\Ast\PatternMatching\NamedGroup.cs" />
<Compile Include="CSharp\Ast\PatternMatching\NamedNode.cs" />
<Compile Include="CSharp\Ast\PatternMatching\Repeat.cs" />
<Compile Include="CSharp\Ast\PatternMatching\Pattern.cs" />
<Compile Include="CSharp\Ast\PatternMatching\Placeholder.cs" />

Loading…
Cancel
Save