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
break; break;
Pattern pattern = cur1 as Pattern; 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; pattern = cur1.GetChildByRole(TypePlaceholder.ChildRole) as Pattern;
if (pattern != null) { if (pattern != null) {
Debug.Assert(stack.Count == patternStack.Count); Debug.Assert(stack.Count == patternStack.Count);

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

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

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

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

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

@ -12,6 +12,10 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching
{ {
readonly string groupName; readonly string groupName;
public string GroupName {
get { return groupName; }
}
public AnyNode(string groupName = null) public AnyNode(string groupName = null)
{ {
this.groupName = groupName; this.groupName = groupName;
@ -22,5 +26,10 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching
match.Add(this.groupName, other); match.Add(this.groupName, other);
return other != null && !other.IsNull; 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
{ {
readonly string referencedGroupName; readonly string referencedGroupName;
public string ReferencedGroupName {
get { return referencedGroupName; }
}
public Backreference(string referencedGroupName) public Backreference(string referencedGroupName)
{ {
if (referencedGroupName == null) if (referencedGroupName == null)
@ -24,6 +28,11 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching
{ {
return match.Get(referencedGroupName).Last().Match(other) != null; 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> /// <summary>
@ -33,6 +42,10 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching
{ {
readonly string referencedGroupName; readonly string referencedGroupName;
public string ReferencedGroupName {
get { return referencedGroupName; }
}
public IdentifierExpressionBackreference(string referencedGroupName) public IdentifierExpressionBackreference(string referencedGroupName)
{ {
if (referencedGroupName == null) if (referencedGroupName == null)
@ -48,5 +61,10 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching
AstNode referenced = match.Get(referencedGroupName).Last(); AstNode referenced = match.Get(referencedGroupName).Last();
return ident.Identifier == referenced.GetChildByRole(AstNode.Roles.Identifier).Name; 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 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic;
namespace ICSharpCode.NRefactory.CSharp.PatternMatching namespace ICSharpCode.NRefactory.CSharp.PatternMatching
{ {
/// <summary> /// <summary>
/// Matches one of several alternatives. /// Matches one of several alternatives.
/// </summary> /// </summary>
public class Choice : Pattern, IEnumerable public class Choice : Pattern, IEnumerable<AstNode>
{ {
public static readonly Role<AstNode> AlternativeRole = new Role<AstNode>("Alternative", AstNode.Null); public static readonly Role<AstNode> AlternativeRole = new Role<AstNode>("Alternative", AstNode.Null);
@ -35,9 +36,19 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching
return false; return false;
} }
IEnumerator<AstNode> IEnumerable<AstNode>.GetEnumerator()
{
return GetChildrenByRole(AlternativeRole).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator() IEnumerator IEnumerable.GetEnumerator()
{ {
return GetChildrenByRole(AlternativeRole).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 @@
// 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
readonly string groupName; readonly string groupName;
public string GroupName {
get { return groupName; }
}
public NamedNode(string groupName, AstNode childNode) public NamedNode(string groupName, AstNode childNode)
{ {
this.groupName = groupName; this.groupName = groupName;
@ -25,5 +29,10 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching
match.Add(this.groupName, other); match.Add(this.groupName, other);
return GetChildByRole(ElementRole).DoMatch(other, match); 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 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.IO;
namespace ICSharpCode.NRefactory.CSharp.PatternMatching namespace ICSharpCode.NRefactory.CSharp.PatternMatching
{ {
@ -33,11 +34,6 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching
return DoMatch(pos, match); return DoMatch(pos, match);
} }
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return default(S);
}
public AstType ToType() public AstType ToType()
{ {
return new TypePlaceholder(this); return new TypePlaceholder(this);
@ -62,5 +58,13 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching
{ {
return new VariablePlaceholder(this); 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
} }
public override NodeType NodeType { 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) 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) protected internal override bool DoMatch(AstNode other, Match match)
@ -37,12 +37,12 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching
} }
public override NodeType NodeType { 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) 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) protected internal override bool DoMatch(AstNode other, Match match)
@ -59,12 +59,12 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching
} }
public override NodeType NodeType { 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) 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) protected internal override bool DoMatch(AstNode other, Match match)
@ -81,12 +81,12 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching
} }
public override NodeType NodeType { 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) 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) protected internal override bool DoMatch(AstNode other, Match match)
@ -103,12 +103,12 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching
} }
public override NodeType NodeType { 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) 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) 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
else else
return this.MaxCount >= 1 && GetChildByRole(ElementRole).DoMatch(other, match); 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;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using ICSharpCode.NRefactory.CSharp.PatternMatching;
using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.NRefactory.TypeSystem;
namespace ICSharpCode.NRefactory.CSharp namespace ICSharpCode.NRefactory.CSharp
@ -15,7 +17,7 @@ namespace ICSharpCode.NRefactory.CSharp
/// <summary> /// <summary>
/// Outputs the AST. /// Outputs the AST.
/// </summary> /// </summary>
public class OutputVisitor : IAstVisitor<object, object> public class OutputVisitor : IPatternAstVisitor<object, object>
{ {
readonly IOutputFormatter formatter; readonly IOutputFormatter formatter;
readonly CSharpFormattingPolicy policy; readonly CSharpFormattingPolicy policy;
@ -1989,5 +1991,91 @@ namespace ICSharpCode.NRefactory.CSharp
return EndNode(identifier); return EndNode(identifier);
} }
#endregion #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 @@
<Compile Include="CSharp\Ast\PatternMatching\Choice.cs" /> <Compile Include="CSharp\Ast\PatternMatching\Choice.cs" />
<Compile Include="CSharp\Ast\PatternMatching\AnyNode.cs" /> <Compile Include="CSharp\Ast\PatternMatching\AnyNode.cs" />
<Compile Include="CSharp\Ast\PatternMatching\Backreference.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\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\Repeat.cs" />
<Compile Include="CSharp\Ast\PatternMatching\Pattern.cs" /> <Compile Include="CSharp\Ast\PatternMatching\Pattern.cs" />
<Compile Include="CSharp\Ast\PatternMatching\Placeholder.cs" /> <Compile Include="CSharp\Ast\PatternMatching\Placeholder.cs" />

Loading…
Cancel
Save