Browse Source

NRefactory AST: Add 'Repeat' pattern which matches an arbitrary number of nodes.

pull/37/head
Daniel Grunwald 15 years ago
parent
commit
0d6d4e60de
  1. 14
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/AstNodeCollection.cs
  2. 7
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Pattern.cs
  3. 51
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Repeat.cs
  4. 22
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/Statements/BlockStatement.cs
  5. 9
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/Statements/ForStatement.cs
  6. 8
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/Statements/UsingStatement.cs
  7. 1
      NRefactory/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj

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

@ -165,10 +165,18 @@ namespace ICSharpCode.NRefactory.CSharp @@ -165,10 +165,18 @@ namespace ICSharpCode.NRefactory.CSharp
cur2 = cur2.NextSibling;
if (cur1 == null || cur2 == null)
break;
if (!cur1.DoMatch(cur2, match))
return false;
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;
cur2 = cur2.NextSibling;
}
return cur1 == null && cur2 == null;
}

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

@ -14,6 +14,13 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching @@ -14,6 +14,13 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching
get { return NodeType.Pattern; }
}
protected internal virtual bool DoMatchCollection(Role role, ref AstNode other, Match match)
{
bool result = DoMatch(other, match);
other = other.NextSibling;
return result;
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return default(S);

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

@ -0,0 +1,51 @@ @@ -0,0 +1,51 @@
// 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.Diagnostics;
namespace ICSharpCode.NRefactory.CSharp.PatternMatching
{
/// <summary>
/// Represents an optional node.
/// </summary>
public class Repeat : Pattern
{
public static readonly Role<AstNode> ElementRole = new Role<AstNode>("Element", AstNode.Null);
public int MinCount;
public int MaxCount = int.MaxValue;
public Repeat(AstNode childNode)
{
AddChild(childNode, ElementRole);
}
protected internal override bool DoMatchCollection(Role role, ref AstNode other, Match match)
{
Debug.Assert(other != null && other.Role == role);
int matchCount = 0;
var lastValidCheckpoint = match.CheckPoint();
AstNode element = GetChildByRole(ElementRole);
AstNode pos = other;
while (pos != null && element.DoMatch(pos, match)) {
matchCount++;
lastValidCheckpoint = match.CheckPoint();
do {
pos = pos.NextSibling;
} while (pos != null && pos.Role != role);
// set 'other' (=pointer in collection) to the next node after the valid match
other = pos;
}
match.RestoreCheckPoint(lastValidCheckpoint); // restote old checkpoint after failed match
return matchCount >= MinCount && matchCount <= MaxCount;
}
protected internal override bool DoMatch(AstNode other, Match match)
{
if (other == null || other.IsNull)
return this.MinCount <= 0;
else
return GetChildByRole(ElementRole).DoMatch(other, match);
}
}
}

22
NRefactory/ICSharpCode.NRefactory/CSharp/Ast/Statements/BlockStatement.cs

@ -31,7 +31,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -31,7 +31,7 @@ namespace ICSharpCode.NRefactory.CSharp
/// <summary>
/// { Statements }
/// </summary>
public class BlockStatement : Statement
public class BlockStatement : Statement, IEnumerable<Statement>
{
public static readonly Role<Statement> StatementRole = new Role<Statement>("Statement", Statement.Null);
@ -81,17 +81,17 @@ namespace ICSharpCode.NRefactory.CSharp @@ -81,17 +81,17 @@ namespace ICSharpCode.NRefactory.CSharp
}
#region Builder methods
public void AddStatement(Statement statement)
public void Add(Statement statement)
{
AddChild(statement, StatementRole);
}
public void AddStatement(Expression expression)
public void Add(Expression expression)
{
AddChild(new ExpressionStatement { Expression = expression }, StatementRole);
}
public void AddStatements(IEnumerable<Statement> statements)
public void AddRange(IEnumerable<Statement> statements)
{
foreach (Statement st in statements)
AddChild(st, StatementRole);
@ -99,13 +99,23 @@ namespace ICSharpCode.NRefactory.CSharp @@ -99,13 +99,23 @@ namespace ICSharpCode.NRefactory.CSharp
public void AddAssignment(Expression left, Expression right)
{
AddStatement(new AssignmentExpression { Left = left, Operator = AssignmentOperatorType.Assign, Right = right });
Add(new AssignmentExpression { Left = left, Operator = AssignmentOperatorType.Assign, Right = right });
}
public void AddReturnStatement(Expression expression)
{
AddStatement(new ReturnStatement { Expression = expression });
Add(new ReturnStatement { Expression = expression });
}
#endregion
IEnumerator<Statement> IEnumerable<Statement>.GetEnumerator()
{
return this.Statements.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return this.Statements.GetEnumerator();
}
}
}

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

@ -1,6 +1,6 @@ @@ -1,6 +1,6 @@
//
// ForStatement.cs
//
//
// Author:
// Mike Krüger <mkrueger@novell.com>
//
@ -75,5 +75,12 @@ namespace ICSharpCode.NRefactory.CSharp @@ -75,5 +75,12 @@ namespace ICSharpCode.NRefactory.CSharp
{
return visitor.VisitForStatement (this, data);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
ForStatement o = other as ForStatement;
return o != null && this.Initializers.DoMatch(o.Initializers, match) && this.Condition.DoMatch(o.Condition, match)
&& this.Iterators.DoMatch(o.Iterators, match) && this.EmbeddedStatement.DoMatch(o.EmbeddedStatement, match);
}
}
}

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

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

1
NRefactory/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj

@ -100,6 +100,7 @@ @@ -100,6 +100,7 @@
<Compile Include="CSharp\Ast\PatternMatching\Backreference.cs" />
<Compile Include="CSharp\Ast\PatternMatching\Match.cs" />
<Compile Include="CSharp\Ast\PatternMatching\NamedGroup.cs" />
<Compile Include="CSharp\Ast\PatternMatching\Repeat.cs" />
<Compile Include="CSharp\Ast\PatternMatching\Pattern.cs" />
<Compile Include="CSharp\Ast\PatternMatching\Placeholder.cs" />
<Compile Include="CSharp\Ast\PrimitiveType.cs" />

Loading…
Cancel
Save