Browse Source

Fixed forum-8572: scoping of query continuation variables (thanks to Joseph Albahari)

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/3.0@3629 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 17 years ago
parent
commit
d64c3db0da
  1. 69
      src/Libraries/NRefactory/Project/Src/Visitors/LookupTableVisitor.cs
  2. 24
      src/Main/Base/Test/NRefactoryResolverTests.cs

69
src/Libraries/NRefactory/Project/Src/Visitors/LookupTableVisitor.cs

@ -140,49 +140,72 @@ namespace ICSharpCode.NRefactory.Visitors @@ -140,49 +140,72 @@ namespace ICSharpCode.NRefactory.Visitors
return base.VisitLambdaExpression(lambdaExpression, data);
}
public override object VisitQueryExpression(QueryExpression queryExpression, object data)
{
endLocationStack.Push(GetQueryVariableEndScope(queryExpression));
base.VisitQueryExpression(queryExpression, data);
endLocationStack.Pop();
return null;
}
Location GetQueryVariableEndScope(QueryExpression queryExpression)
{
return queryExpression.IntoClause.IsNull
? queryExpression.EndLocation
: queryExpression.IntoClause.StartLocation;
}
public override object VisitQueryExpressionFromClause(QueryExpressionFromClause fromClause, object data)
{
QueryExpression parentExpression = fromClause.Parent as QueryExpression;
AddVariable(fromClause.Type, fromClause.Identifier,
fromClause.StartLocation, CurrentEndLocation,
false, true, fromClause.InExpression, null);
return base.VisitQueryExpressionFromClause(fromClause, data);
}
public override object VisitQueryExpressionIntoClause(QueryExpressionIntoClause intoClause, object data)
{
QueryExpression parentExpression = intoClause.Parent as QueryExpression;
if (parentExpression != null) {
AddVariable(fromClause.Type, fromClause.Identifier,
parentExpression.StartLocation, parentExpression.EndLocation,
false, true, fromClause.InExpression, null);
Expression initializer = null;
var selectClause = parentExpression.SelectOrGroupClause as QueryExpressionSelectClause;
if (selectClause != null) {
initializer = selectClause.Projection;
} else {
var groupByClause = parentExpression.SelectOrGroupClause as QueryExpressionGroupClause;
if (groupByClause != null)
initializer = groupByClause.Projection;
}
AddVariable(null, intoClause.IntoIdentifier,
intoClause.StartLocation, GetQueryVariableEndScope(intoClause.ContinuedQuery),
false, false, initializer, null);
}
return base.VisitQueryExpressionFromClause(fromClause, data);
return base.VisitQueryExpressionIntoClause(intoClause, data);
}
public override object VisitQueryExpressionJoinClause(QueryExpressionJoinClause joinClause, object data)
{
if (string.IsNullOrEmpty(joinClause.IntoIdentifier)) {
QueryExpression parentExpression = joinClause.Parent as QueryExpression;
if (parentExpression != null) {
AddVariable(joinClause.Type, joinClause.Identifier,
parentExpression.StartLocation, parentExpression.EndLocation,
false, true, joinClause.InExpression, null);
}
AddVariable(joinClause.Type, joinClause.Identifier,
joinClause.StartLocation, CurrentEndLocation,
false, true, joinClause.InExpression, null);
} else {
AddVariable(joinClause.Type, joinClause.Identifier,
joinClause.StartLocation, joinClause.EndLocation,
false, true, joinClause.InExpression, null);
QueryExpression parentExpression = joinClause.Parent as QueryExpression;
if (parentExpression != null) {
AddVariable(joinClause.Type, joinClause.IntoIdentifier,
parentExpression.StartLocation, parentExpression.EndLocation,
false, false, joinClause.InExpression, null);
}
AddVariable(joinClause.Type, joinClause.IntoIdentifier,
joinClause.StartLocation, CurrentEndLocation,
false, false, joinClause.InExpression, null);
}
return base.VisitQueryExpressionJoinClause(joinClause, data);
}
public override object VisitQueryExpressionLetClause(QueryExpressionLetClause letClause, object data)
{
QueryExpression parentExpression = letClause.Parent as QueryExpression;
if (parentExpression != null) {
AddVariable(null, letClause.Identifier,
parentExpression.StartLocation, parentExpression.EndLocation,
false, false, letClause.Expression, null);
}
AddVariable(null, letClause.Identifier,
letClause.StartLocation, CurrentEndLocation,
false, false, letClause.Expression, null);
return base.VisitQueryExpressionLetClause(letClause, data);
}

24
src/Main/Base/Test/NRefactoryResolverTests.cs

@ -1886,6 +1886,30 @@ public class MyCollectionType : System.Collections.IEnumerable @@ -1886,6 +1886,30 @@ public class MyCollectionType : System.Collections.IEnumerable
Assert.IsNotNull(mrr);
Assert.AreEqual("Point.X", mrr.ResolvedMember.FullyQualifiedName);
}
[Test]
public void LinqQueryContinuationTest()
{
string program = @"using System;
class TestClass {
void Test(string[] input) {
var r = from x in input
select x.GetHashCode() into x
where x == 42
select x * x;
}
}
";
LocalResolveResult lrr = Resolve<LocalResolveResult>(program, "x", 5, 11, ExpressionContext.Default);
Assert.AreEqual("System.String", lrr.ResolvedType.FullyQualifiedName);
lrr = Resolve<LocalResolveResult>(program, "x", 6, 10, ExpressionContext.Default);
Assert.AreEqual("System.Int32", lrr.ResolvedType.FullyQualifiedName);
lrr = Resolve<LocalResolveResult>(program, "r", 8);
Assert.AreEqual("System.Collections.Generic.IEnumerable", lrr.ResolvedType.FullyQualifiedName);
Assert.AreEqual("System.Int32", lrr.ResolvedType.CastToConstructedReturnType().TypeArguments[0].FullyQualifiedName);
}
#endregion
[Test]

Loading…
Cancel
Save