Browse Source

Fix parsing of query continuations for queries with multiple from clauses.

newNRvisualizers
Daniel Grunwald 15 years ago
parent
commit
90542d2ea2
  1. 61
      ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/QueryExpressionTests.cs
  2. 5
      ICSharpCode.NRefactory/CSharp/Ast/AstNode.cs
  3. 3
      ICSharpCode.NRefactory/CSharp/Ast/Expressions/QueryExpression.cs
  4. 33
      ICSharpCode.NRefactory/CSharp/Parser/CSharpParser.cs

61
ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/QueryExpressionTests.cs

@ -219,5 +219,66 @@ select new { c.Name, o.OrderID, o.Total }", @@ -219,5 +219,66 @@ select new { c.Name, o.OrderID, o.Total }",
}
);
}
[Test]
public void QueryContinuationWithMultipleFrom()
{
ParseUtilCSharp.AssertExpression(
"from a in b from c in d select e into f select g",
new QueryExpression {
Clauses = {
new QueryContinuationClause {
PrecedingQuery = new QueryExpression {
Clauses = {
new QueryFromClause {
Identifier = "a",
Expression = new IdentifierExpression("b")
},
new QueryFromClause {
Identifier = "c",
Expression = new IdentifierExpression("d")
},
new QuerySelectClause { Expression = new IdentifierExpression("e") }
}
},
Identifier = "f"
},
new QuerySelectClause { Expression = new IdentifierExpression("g") }
}
}
);
}
[Test]
public void MultipleQueryContinuation()
{
ParseUtilCSharp.AssertExpression(
"from a in b select c into d select e into f select g",
new QueryExpression {
Clauses = {
new QueryContinuationClause {
PrecedingQuery = new QueryExpression {
Clauses = {
new QueryContinuationClause {
PrecedingQuery = new QueryExpression {
Clauses = {
new QueryFromClause {
Identifier = "a",
Expression = new IdentifierExpression("b")
},
new QuerySelectClause { Expression = new IdentifierExpression("c") }
}
},
Identifier = "d"
},
new QuerySelectClause { Expression = new IdentifierExpression("e") }
}
},
Identifier = "f"
},
new QuerySelectClause { Expression = new IdentifierExpression("g") }
}});
}
}
}

5
ICSharpCode.NRefactory/CSharp/Ast/AstNode.cs

@ -137,7 +137,6 @@ namespace ICSharpCode.NRefactory.CSharp @@ -137,7 +137,6 @@ namespace ICSharpCode.NRefactory.CSharp
public AstNode Parent {
get { return parent; }
set { parent = value; }
}
public Role Role {
@ -146,22 +145,18 @@ namespace ICSharpCode.NRefactory.CSharp @@ -146,22 +145,18 @@ namespace ICSharpCode.NRefactory.CSharp
public AstNode NextSibling {
get { return nextSibling; }
set { nextSibling = value; }
}
public AstNode PrevSibling {
get { return prevSibling; }
set { prevSibling = value; }
}
public AstNode FirstChild {
get { return firstChild; }
set { firstChild = value; }
}
public AstNode LastChild {
get { return lastChild; }
set { lastChild = value; }
}
public IEnumerable<AstNode> Children {

3
ICSharpCode.NRefactory/CSharp/Ast/Expressions/QueryExpression.cs

@ -101,9 +101,6 @@ namespace ICSharpCode.NRefactory.CSharp @@ -101,9 +101,6 @@ namespace ICSharpCode.NRefactory.CSharp
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
QueryContinuationClause o = other as QueryContinuationClause;
Console.WriteLine ("other: " + other);
Console.WriteLine (MatchString(this.Identifier, o.Identifier));
Console.WriteLine (this.PrecedingQuery.DoMatch(o.PrecedingQuery, match));
return o != null && MatchString(this.Identifier, o.Identifier) && this.PrecedingQuery.DoMatch(o.PrecedingQuery, match);
}
}

33
ICSharpCode.NRefactory/CSharp/Parser/CSharpParser.cs

@ -2564,38 +2564,15 @@ namespace ICSharpCode.NRefactory.CSharp @@ -2564,38 +2564,15 @@ namespace ICSharpCode.NRefactory.CSharp
var result = new QueryExpression ();
var currentClause = queryExpression.next;
var queryStarts = new Stack<QueryClause> ();
while (currentClause != null) {
Console.WriteLine (currentClause);
QueryClause clause = (QueryClause)currentClause.Accept (this);
if (clause is QueryFromClause) {
queryStarts.Push (clause);
} else if (clause is QueryContinuationClause) {
var lastStart = queryStarts.Pop ();
var precedingQuery = new QueryExpression ();
List<AstNode> children = new List<AstNode> ();
AstNode node = lastStart;
while (node != null) {
children.Add (node);
node = node.NextSibling;
}
result.LastChild = lastStart.PrevSibling;
if (lastStart.PrevSibling != null) {
lastStart.PrevSibling.NextSibling = null;
lastStart.PrevSibling = null;
} else {
// lastStart == FirstChild
result.FirstChild = null;
}
children.ForEach (c => c.Parent = precedingQuery);
precedingQuery.FirstChild = children.First ();
precedingQuery.LastChild = children.Last ();
((QueryContinuationClause)clause).PrecedingQuery = precedingQuery;
queryStarts.Push (clause);
if (clause is QueryContinuationClause) {
// insert preceding query at beginning of QueryContinuationClause
clause.InsertChildAfter(null, result, QueryContinuationClause.PrecedingQueryRole);
// create a new QueryExpression for the remaining query
result = new QueryExpression();
}
result.AddChild (clause, QueryExpression.ClauseRole);
currentClause = currentClause.next;

Loading…
Cancel
Save