Browse Source

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

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

2
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
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
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
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
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
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
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
ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/NamedGroup.cs → 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
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
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
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
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
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