Browse Source

Merge branch 'master' of git://github.com/icsharpcode/ILSpy into Debugger

newNRvisualizers
Eusebiu Marcu 15 years ago
parent
commit
75a50926da
  1. 55
      ICSharpCode.NRefactory/CSharp/Ast/AstNodeCollection.cs
  2. 6
      ICSharpCode.NRefactory/CSharp/Ast/Expressions/AssignmentExpression.cs
  3. 8
      ICSharpCode.NRefactory/CSharp/Ast/Expressions/BinaryOperatorExpression.cs
  4. 9
      ICSharpCode.NRefactory/CSharp/Ast/Expressions/Expression.cs
  5. 4
      ICSharpCode.NRefactory/CSharp/Ast/Expressions/PrimitiveExpression.cs
  6. 3
      ICSharpCode.NRefactory/CSharp/Ast/NodeType.cs
  7. 9
      ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/AnyNode.cs
  8. 42
      ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Backreference.cs
  9. 13
      ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Choice.cs
  10. 22
      ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/IPatternAstVisitor.cs
  11. 9
      ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/NamedNode.cs
  12. 28
      ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Pattern.cs
  13. 20
      ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Placeholder.cs
  14. 26
      ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Repeat.cs
  15. 8
      ICSharpCode.NRefactory/CSharp/Ast/Statements/CheckedStatement.cs
  16. 8
      ICSharpCode.NRefactory/CSharp/Ast/Statements/ContinueStatement.cs
  17. 8
      ICSharpCode.NRefactory/CSharp/Ast/Statements/DoWhileStatement.cs
  18. 8
      ICSharpCode.NRefactory/CSharp/Ast/Statements/EmptyStatement.cs
  19. 6
      ICSharpCode.NRefactory/CSharp/Ast/Statements/FixedStatement.cs
  20. 9
      ICSharpCode.NRefactory/CSharp/Ast/Statements/ForeachStatement.cs
  21. 38
      ICSharpCode.NRefactory/CSharp/Ast/Statements/GotoStatement.cs
  22. 12
      ICSharpCode.NRefactory/CSharp/Ast/Statements/LabelStatement.cs
  23. 8
      ICSharpCode.NRefactory/CSharp/Ast/Statements/LockStatement.cs
  24. 8
      ICSharpCode.NRefactory/CSharp/Ast/Statements/ReturnStatement.cs
  25. 5
      ICSharpCode.NRefactory/CSharp/Ast/Statements/Statement.cs
  26. 6
      ICSharpCode.NRefactory/CSharp/Ast/Statements/SwitchStatement.cs
  27. 8
      ICSharpCode.NRefactory/CSharp/Ast/Statements/ThrowStatement.cs
  28. 8
      ICSharpCode.NRefactory/CSharp/Ast/Statements/UncheckedStatement.cs
  29. 8
      ICSharpCode.NRefactory/CSharp/Ast/Statements/UnsafeStatement.cs
  30. 8
      ICSharpCode.NRefactory/CSharp/Ast/Statements/WhileStatement.cs
  31. 8
      ICSharpCode.NRefactory/CSharp/Ast/Statements/YieldBreakStatement.cs
  32. 8
      ICSharpCode.NRefactory/CSharp/Ast/Statements/YieldStatement.cs
  33. 90
      ICSharpCode.NRefactory/CSharp/OutputVisitor/OutputVisitor.cs
  34. 3
      ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj

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

@ -4,6 +4,7 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.Linq; using System.Linq;
using ICSharpCode.NRefactory.CSharp.PatternMatching; using ICSharpCode.NRefactory.CSharp.PatternMatching;
@ -156,29 +157,45 @@ namespace ICSharpCode.NRefactory.CSharp
internal bool DoMatch(AstNodeCollection<T> other, Match match) internal bool DoMatch(AstNodeCollection<T> other, Match match)
{ {
AstNode cur1 = this.node.FirstChild; Stack<AstNode> patternStack = new Stack<AstNode>();
AstNode cur2 = other.node.FirstChild; Stack<Pattern.PossibleMatch> stack = new Stack<Pattern.PossibleMatch>();
while (true) { patternStack.Push(this.node.FirstChild);
while (cur1 != null && cur1.Role != role) stack.Push(new Pattern.PossibleMatch(other.node.FirstChild, match.CheckPoint()));
while (stack.Count > 0) {
AstNode cur1 = patternStack.Pop();
AstNode cur2 = stack.Peek().NextOther;
match.RestoreCheckPoint(stack.Pop().Checkpoint);
bool success = true;
while (cur1 != null && success) {
while (cur1 != null && cur1.Role != role)
cur1 = cur1.NextSibling;
while (cur2 != null && cur2.Role != role)
cur2 = cur2.NextSibling;
if (cur1 == null)
break;
Pattern pattern = cur1 as Pattern;
if (pattern == null && cur1.NodeType == NodeType.Placeholder)
pattern = cur1.GetChildByRole(TypePlaceholder.ChildRole) as Pattern;
if (pattern != null) {
Debug.Assert(stack.Count == patternStack.Count);
success = pattern.DoMatchCollection(role, cur2, match, stack);
Debug.Assert(stack.Count >= patternStack.Count);
while (stack.Count > patternStack.Count)
patternStack.Push(cur1.NextSibling);
} else {
success = cur1.DoMatch(cur2, match);
}
cur1 = cur1.NextSibling; cur1 = cur1.NextSibling;
if (cur2 != null)
cur2 = cur2.NextSibling;
}
while (cur2 != null && cur2.Role != role) while (cur2 != null && cur2.Role != role)
cur2 = cur2.NextSibling; cur2 = cur2.NextSibling;
if (cur1 == null || cur2 == null) if (success && cur2 == null)
break; return true;
Pattern pattern = cur1 as Pattern;
if (pattern == null && cur1.NodeType == NodeType.Pattern)
pattern = cur1.GetChildByRole(TypePlaceholder.ChildRole) as Pattern;
if (pattern != null) {
if (!pattern.DoMatchCollection(role, ref cur2, match))
return false;
} else {
if (!cur1.DoMatch(cur2, match))
return false;
cur2 = cur2.NextSibling;
}
cur1 = cur1.NextSibling;
} }
return cur1 == null && cur2 == null; return false;
} }
} }
} }

6
ICSharpCode.NRefactory/CSharp/Ast/Expressions/AssignmentExpression.cs

@ -75,7 +75,8 @@ namespace ICSharpCode.NRefactory.CSharp
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{ {
AssignmentExpression o = other as AssignmentExpression; AssignmentExpression o = other as AssignmentExpression;
return o != null && this.Left.DoMatch(o.Left, match) && this.Operator == o.Operator && this.Right.DoMatch(o.Right, match); return o != null && (this.Operator == AssignmentOperatorType.Any || this.Operator == o.Operator)
&& this.Left.DoMatch(o.Left, match) && this.Right.DoMatch(o.Right, match);
} }
public static string GetOperatorSymbol(AssignmentOperatorType op) public static string GetOperatorSymbol(AssignmentOperatorType op)
@ -136,5 +137,8 @@ namespace ICSharpCode.NRefactory.CSharp
BitwiseOr, BitwiseOr,
/// <summary>left ^= right</summary> /// <summary>left ^= right</summary>
ExclusiveOr, ExclusiveOr,
/// <summary>Any operator (for pattern matching)</summary>
Any
} }
} }

8
ICSharpCode.NRefactory/CSharp/Ast/Expressions/BinaryOperatorExpression.cs

@ -75,7 +75,8 @@ namespace ICSharpCode.NRefactory.CSharp
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{ {
BinaryOperatorExpression o = other as BinaryOperatorExpression; BinaryOperatorExpression o = other as BinaryOperatorExpression;
return o != null && this.Left.DoMatch(o.Left, match) && this.Operator == o.Operator && this.Right.DoMatch(o.Right, match); return o != null && (this.Operator == BinaryOperatorType.Any || this.Operator == o.Operator)
&& this.Left.DoMatch(o.Left, match) && this.Right.DoMatch(o.Right, match);
} }
public static string GetOperatorSymbol(BinaryOperatorType op) public static string GetOperatorSymbol(BinaryOperatorType op)
@ -175,6 +176,9 @@ namespace ICSharpCode.NRefactory.CSharp
/// <summary>left ?? right</summary> /// <summary>left ?? right</summary>
NullCoalescing, NullCoalescing,
None /// <summary>
/// Any binary operator (used in pattern matching)
/// </summary>
Any
} }
} }

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)

4
ICSharpCode.NRefactory/CSharp/Ast/Expressions/PrimitiveExpression.cs

@ -31,6 +31,8 @@ namespace ICSharpCode.NRefactory.CSharp
/// </summary> /// </summary>
public class PrimitiveExpression : Expression public class PrimitiveExpression : Expression
{ {
public static readonly object AnyValue = new object();
AstLocation startLocation; AstLocation startLocation;
public override AstLocation StartLocation { public override AstLocation StartLocation {
get { get {
@ -70,7 +72,7 @@ namespace ICSharpCode.NRefactory.CSharp
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{ {
PrimitiveExpression o = other as PrimitiveExpression; PrimitiveExpression o = other as PrimitiveExpression;
return o != null && object.Equals(this.Value, o.Value); return o != null && (this.Value == AnyValue || object.Equals(this.Value, o.Value));
} }
} }
} }

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);
}
} }
} }

42
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,5 +28,43 @@ 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>
/// Matches identifier expressions that have the same identifier as the referenced variable/type definition/method definition.
/// </summary>
public class IdentifierExpressionBackreference : Pattern
{
readonly string referencedGroupName;
public string ReferencedGroupName {
get { return referencedGroupName; }
}
public IdentifierExpressionBackreference(string referencedGroupName)
{
if (referencedGroupName == null)
throw new ArgumentNullException("referencedGroupName");
this.referencedGroupName = referencedGroupName;
}
protected internal override bool DoMatch(AstNode other, Match match)
{
IdentifierExpression ident = other as IdentifierExpression;
if (ident == null || ident.TypeArguments.Any())
return false;
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 @@
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);
}
} }
} }

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

@ -2,6 +2,9 @@
// This code is distributed under MIT X11 license (for details please see \doc\license.txt) // This code is distributed under MIT X11 license (for details please see \doc\license.txt)
using System; using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
namespace ICSharpCode.NRefactory.CSharp.PatternMatching namespace ICSharpCode.NRefactory.CSharp.PatternMatching
{ {
@ -14,16 +17,21 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching
get { return NodeType.Pattern; } get { return NodeType.Pattern; }
} }
protected internal virtual bool DoMatchCollection(Role role, ref AstNode other, Match match) internal struct PossibleMatch
{ {
bool result = DoMatch(other, match); public readonly AstNode NextOther; // next node after the last matched node
other = other.NextSibling; public readonly int Checkpoint; // checkpoint
return result;
public PossibleMatch(AstNode nextOther, int checkpoint)
{
this.NextOther = nextOther;
this.Checkpoint = checkpoint;
}
} }
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data) internal virtual bool DoMatchCollection(Role role, AstNode pos, Match match, Stack<PossibleMatch> backtrackingStack)
{ {
return default(S); return DoMatch(pos, match);
} }
public AstType ToType() public AstType ToType()
@ -50,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)

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

@ -2,6 +2,7 @@
// This code is distributed under MIT X11 license (for details please see \doc\license.txt) // This code is distributed under MIT X11 license (for details please see \doc\license.txt)
using System; using System;
using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
namespace ICSharpCode.NRefactory.CSharp.PatternMatching namespace ICSharpCode.NRefactory.CSharp.PatternMatching
@ -20,24 +21,22 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching
AddChild(childNode, ElementRole); AddChild(childNode, ElementRole);
} }
protected internal override bool DoMatchCollection(Role role, ref AstNode other, Match match) internal override bool DoMatchCollection(Role role, AstNode pos, Match match, Stack<Pattern.PossibleMatch> backtrackingStack)
{ {
Debug.Assert(other != null && other.Role == role); Debug.Assert(pos == null || pos.Role == role);
int matchCount = 0; int matchCount = 0;
var lastValidCheckpoint = match.CheckPoint(); if (this.MinCount <= 0)
backtrackingStack.Push(new PossibleMatch(pos, match.CheckPoint()));
AstNode element = GetChildByRole(ElementRole); AstNode element = GetChildByRole(ElementRole);
AstNode pos = other; while (matchCount < this.MaxCount && pos != null && element.DoMatch(pos, match)) {
while (pos != null && element.DoMatch(pos, match)) {
matchCount++; matchCount++;
lastValidCheckpoint = match.CheckPoint();
do { do {
pos = pos.NextSibling; pos = pos.NextSibling;
} while (pos != null && pos.Role != role); } while (pos != null && pos.Role != role);
// set 'other' (=pointer in collection) to the next node after the valid match if (matchCount >= this.MinCount)
other = pos; backtrackingStack.Push(new PossibleMatch(pos, match.CheckPoint()));
} }
match.RestoreCheckPoint(lastValidCheckpoint); // restote old checkpoint after failed match return false; // never do a normal (single-element) match; always make the caller look at the results on the back-tracking stack.
return matchCount >= MinCount && matchCount <= MaxCount;
} }
protected internal override bool DoMatch(AstNode other, Match match) protected internal override bool DoMatch(AstNode other, Match match)
@ -45,7 +44,12 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching
if (other == null || other.IsNull) if (other == null || other.IsNull)
return this.MinCount <= 0; return this.MinCount <= 0;
else else
return 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);
} }
} }
} }

8
ICSharpCode.NRefactory/CSharp/Ast/Statements/CheckedStatement.cs

@ -1,4 +1,4 @@
// //
// CheckedStatement.cs // CheckedStatement.cs
// //
// Author: // Author:
@ -44,5 +44,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitCheckedStatement (this, data); return visitor.VisitCheckedStatement (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
CheckedStatement o = other as CheckedStatement;
return o != null && this.Body.DoMatch(o.Body, match);
}
} }
} }

8
ICSharpCode.NRefactory/CSharp/Ast/Statements/ContinueStatement.cs

@ -1,4 +1,4 @@
// //
// ContinueStatement.cs // ContinueStatement.cs
// //
// Author: // Author:
@ -39,5 +39,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitContinueStatement (this, data); return visitor.VisitContinueStatement (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
ContinueStatement o = other as ContinueStatement;
return o != null;
}
} }
} }

8
ICSharpCode.NRefactory/CSharp/Ast/Statements/DoWhileStatement.cs

@ -1,4 +1,4 @@
// //
// DoWhileStatement.cs // DoWhileStatement.cs
// //
// Author: // Author:
@ -68,6 +68,12 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitDoWhileStatement (this, data); return visitor.VisitDoWhileStatement (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
DoWhileStatement o = other as DoWhileStatement;
return o != null && this.EmbeddedStatement.DoMatch(o.EmbeddedStatement, match) && this.Condition.DoMatch(o.Condition, match);
}
} }
} }

8
ICSharpCode.NRefactory/CSharp/Ast/Statements/EmptyStatement.cs

@ -1,4 +1,4 @@
// //
// EmptyStatement.cs // EmptyStatement.cs
// //
// Author: // Author:
@ -52,5 +52,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitEmptyStatement (this, data); return visitor.VisitEmptyStatement (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
EmptyStatement o = other as EmptyStatement;
return o != null;
}
} }
} }

6
ICSharpCode.NRefactory/CSharp/Ast/Statements/FixedStatement.cs

@ -63,5 +63,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitFixedStatement (this, data); return visitor.VisitFixedStatement (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
FixedStatement o = other as FixedStatement;
return o != null && this.Variables.DoMatch(o.Variables, match) && this.EmbeddedStatement.DoMatch(o.EmbeddedStatement, match);
}
} }
} }

9
ICSharpCode.NRefactory/CSharp/Ast/Statements/ForeachStatement.cs

@ -1,4 +1,4 @@
// //
// ForeachStatement.cs // ForeachStatement.cs
// //
// Author: // Author:
@ -75,5 +75,12 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitForeachStatement (this, data); return visitor.VisitForeachStatement (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
ForeachStatement o = other as ForeachStatement;
return o != null && this.VariableType.DoMatch(o.VariableType, match) && MatchString(this.VariableName, o.VariableName)
&& this.InExpression.DoMatch(o.InExpression, match) && this.EmbeddedStatement.DoMatch(o.EmbeddedStatement, match);
}
} }
} }

38
ICSharpCode.NRefactory/CSharp/Ast/Statements/GotoStatement.cs

@ -56,14 +56,6 @@ namespace ICSharpCode.NRefactory.CSharp
} }
} }
/// <summary>
/// Used for "goto case LabelExpression;"
/// </summary>
public Expression LabelExpression {
get { return GetChildByRole (Roles.Expression); }
set { SetChildByRole (Roles.Expression, value); }
}
public CSharpTokenNode SemicolonToken { public CSharpTokenNode SemicolonToken {
get { return GetChildByRole (Roles.Semicolon); } get { return GetChildByRole (Roles.Semicolon); }
} }
@ -72,6 +64,12 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitGotoStatement (this, data); return visitor.VisitGotoStatement (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
GotoStatement o = other as GotoStatement;
return o != null && MatchString(this.Label, o.Label);
}
} }
/// <summary> /// <summary>
@ -89,18 +87,6 @@ namespace ICSharpCode.NRefactory.CSharp
get { return GetChildByRole (CaseKeywordRole); } get { return GetChildByRole (CaseKeywordRole); }
} }
public string Label {
get {
return GetChildByRole (Roles.Identifier).Name;
}
set {
if (string.IsNullOrEmpty(value))
SetChildByRole(Roles.Identifier, null);
else
SetChildByRole(Roles.Identifier, new Identifier(value, AstLocation.Empty));
}
}
/// <summary> /// <summary>
/// Used for "goto case LabelExpression;" /// Used for "goto case LabelExpression;"
/// </summary> /// </summary>
@ -117,6 +103,12 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitGotoCaseStatement (this, data); return visitor.VisitGotoCaseStatement (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
GotoCaseStatement o = other as GotoCaseStatement;
return o != null && this.LabelExpression.DoMatch(o.LabelExpression, match);
}
} }
/// <summary> /// <summary>
@ -142,5 +134,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitGotoDefaultStatement (this, data); return visitor.VisitGotoDefaultStatement (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
GotoDefaultStatement o = other as GotoDefaultStatement;
return o != null;
}
} }
} }

12
ICSharpCode.NRefactory/CSharp/Ast/Statements/LabelStatement.cs

@ -1,4 +1,4 @@
// //
// LabelStatement.cs // LabelStatement.cs
// //
// Author: // Author:
@ -40,9 +40,19 @@ namespace ICSharpCode.NRefactory.CSharp
} }
} }
public CSharpTokenNode Colon {
get { return GetChildByRole (Roles.Colon); }
}
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 visitor.VisitLabelStatement (this, data); return visitor.VisitLabelStatement (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
LabelStatement o = other as LabelStatement;
return o != null && MatchString(this.Label, o.Label);
}
} }
} }

8
ICSharpCode.NRefactory/CSharp/Ast/Statements/LockStatement.cs

@ -1,4 +1,4 @@
// //
// LockStatement.cs // LockStatement.cs
// //
// Author: // Author:
@ -57,5 +57,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitLockStatement (this, data); return visitor.VisitLockStatement (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
LockStatement o = other as LockStatement;
return o != null && this.Expression.DoMatch(o.Expression, match) && this.EmbeddedStatement.DoMatch(o.EmbeddedStatement, match);
}
} }
} }

8
ICSharpCode.NRefactory/CSharp/Ast/Statements/ReturnStatement.cs

@ -1,4 +1,4 @@
// //
// ReturnStatement.cs // ReturnStatement.cs
// //
// Author: // Author:
@ -48,5 +48,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitReturnStatement (this, data); return visitor.VisitReturnStatement (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
ReturnStatement o = other as ReturnStatement;
return o != null && this.Expression.DoMatch(o.Expression, match);
}
} }
} }

5
ICSharpCode.NRefactory/CSharp/Ast/Statements/Statement.cs

@ -52,10 +52,5 @@ namespace ICSharpCode.NRefactory.CSharp
public override NodeType NodeType { public override NodeType NodeType {
get { return NodeType.Statement; } get { return NodeType.Statement; }
} }
protected internal override bool DoMatch(AstNode other, ICSharpCode.NRefactory.CSharp.PatternMatching.Match match)
{
throw new NotImplementedException();
}
} }
} }

6
ICSharpCode.NRefactory/CSharp/Ast/Statements/SwitchStatement.cs

@ -69,6 +69,12 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitSwitchStatement (this, data); return visitor.VisitSwitchStatement (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
SwitchStatement o = other as SwitchStatement;
return o != null && this.Expression.DoMatch(o.Expression, match) && this.SwitchSections.DoMatch(o.SwitchSections, match);
}
} }
public class SwitchSection : AstNode public class SwitchSection : AstNode

8
ICSharpCode.NRefactory/CSharp/Ast/Statements/ThrowStatement.cs

@ -1,4 +1,4 @@
// //
// ThrowStatement.cs // ThrowStatement.cs
// //
// Author: // Author:
@ -48,5 +48,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitThrowStatement (this, data); return visitor.VisitThrowStatement (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
ThrowStatement o = other as ThrowStatement;
return o != null && this.Expression.DoMatch(o.Expression, match);
}
} }
} }

8
ICSharpCode.NRefactory/CSharp/Ast/Statements/UncheckedStatement.cs

@ -1,4 +1,4 @@
// //
// UncheckedStatement.cs // UncheckedStatement.cs
// //
// Author: // Author:
@ -44,5 +44,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitUncheckedStatement (this, data); return visitor.VisitUncheckedStatement (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
UncheckedStatement o = other as UncheckedStatement;
return o != null && this.Body.DoMatch(o.Body, match);
}
} }
} }

8
ICSharpCode.NRefactory/CSharp/Ast/Statements/UnsafeStatement.cs

@ -1,4 +1,4 @@
// //
// UnsafeStatement.cs // UnsafeStatement.cs
// //
// Author: // Author:
@ -44,5 +44,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitUnsafeStatement (this, data); return visitor.VisitUnsafeStatement (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
UnsafeStatement o = other as UnsafeStatement;
return o != null && this.Body.DoMatch(o.Body, match);
}
} }
} }

8
ICSharpCode.NRefactory/CSharp/Ast/Statements/WhileStatement.cs

@ -1,4 +1,4 @@
// //
// WhileStatement.cs // WhileStatement.cs
// //
// Author: // Author:
@ -59,5 +59,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitWhileStatement (this, data); return visitor.VisitWhileStatement (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
WhileStatement o = other as WhileStatement;
return o != null && this.Condition.DoMatch(o.Condition, match) && this.EmbeddedStatement.DoMatch(o.EmbeddedStatement, match);
}
} }
} }

8
ICSharpCode.NRefactory/CSharp/Ast/Statements/YieldBreakStatement.cs

@ -1,4 +1,4 @@
// //
// YieldBreakStatement.cs // YieldBreakStatement.cs
// //
// Author: // Author:
@ -50,5 +50,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitYieldBreakStatement (this, data); return visitor.VisitYieldBreakStatement (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
YieldBreakStatement o = other as YieldBreakStatement;
return o != null;
}
} }
} }

8
ICSharpCode.NRefactory/CSharp/Ast/Statements/YieldStatement.cs

@ -1,4 +1,4 @@
// //
// YieldStatement.cs // YieldStatement.cs
// //
// Author: // Author:
@ -55,5 +55,11 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
return visitor.VisitYieldStatement (this, data); return visitor.VisitYieldStatement (this, data);
} }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
YieldStatement o = other as YieldStatement;
return o != null && this.Expression.DoMatch(o.Expression, match);
}
} }
} }

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