Browse Source

Fixed resolving LINQ queries that involve transparent identifiers.

newNRvisualizers
Daniel Grunwald 14 years ago
parent
commit
f2011680e9
  1. 14
      ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs
  2. 46
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/LinqTests.cs

14
ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs

@ -58,7 +58,6 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -58,7 +58,6 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
// The ResolveVisitor is also responsible for handling lambda expressions.
static readonly ResolveResult errorResult = ErrorResolveResult.UnknownError;
static readonly ResolveResult transparentIdentifierResolveResult = new ResolveResult(SpecialType.UnboundTypeArgument);
readonly ResolveResult voidResult;
CSharpResolver resolver;
@ -3241,6 +3240,11 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -3241,6 +3240,11 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return GetElementTypeFromIEnumerable(type, resolver.Compilation, false);
}
ResolveResult MakeTransparentIdentifierResolveResult()
{
return new ResolveResult(new AnonymousType(resolver.Compilation, EmptyList<IUnresolvedProperty>.Instance));
}
sealed class QueryExpressionLambdaConversion : Conversion
{
internal readonly IType[] ParameterTypes;
@ -3368,7 +3372,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -3368,7 +3372,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
selectResult = Resolve(selectClause.Expression);
} else {
// from .. from ... ... - introduce a transparent identifier
selectResult = transparentIdentifierResolveResult;
selectResult = MakeTransparentIdentifierResolveResult();
}
ResolveResult methodGroup = resolver.ResolveMemberAccess(currentQueryResult, "SelectMany", EmptyList<IType>.Instance, true);
ResolveResult[] arguments = {
@ -3401,7 +3405,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -3401,7 +3405,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
if (resolverEnabled && currentQueryResult != null) {
// resolve the .Select() call
ResolveResult methodGroup = resolver.ResolveMemberAccess(currentQueryResult, "Select", EmptyList<IType>.Instance, true);
ResolveResult[] arguments = { new QueryExpressionLambda(1, transparentIdentifierResolveResult) };
ResolveResult[] arguments = { new QueryExpressionLambda(1, MakeTransparentIdentifierResolveResult()) };
return resolver.ResolveInvocation(methodGroup, arguments);
} else {
return null;
@ -3454,7 +3458,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -3454,7 +3458,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
selectResult = Resolve(selectClause.Expression);
} else {
// from .. join ... ... - introduce a transparent identifier
selectResult = transparentIdentifierResolveResult;
selectResult = MakeTransparentIdentifierResolveResult();
}
var methodGroup = resolver.ResolveMemberAccess(currentQueryResult, "Join", EmptyList<IType>.Instance);
@ -3493,7 +3497,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -3493,7 +3497,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
groupJoinLambda = new ImplicitlyTypedLambda(selectClause, selectLambdaParameters, this);
} else {
// from .. join ... ... - introduce a transparent identifier
groupJoinLambda = new QueryExpressionLambda(2, transparentIdentifierResolveResult);
groupJoinLambda = new QueryExpressionLambda(2, MakeTransparentIdentifierResolveResult());
}
ResolveResult[] arguments = {

46
ICSharpCode.NRefactory.Tests/CSharp/Resolver/LinqTests.cs

@ -17,8 +17,10 @@ @@ -17,8 +17,10 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Linq;
using ICSharpCode.NRefactory.Semantics;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
using NUnit.Framework;
namespace ICSharpCode.NRefactory.CSharp.Resolver
@ -333,5 +335,49 @@ class TestClass @@ -333,5 +335,49 @@ class TestClass
var rr = Resolve<LocalResolveResult>(program);
Assert.AreEqual("System.String", rr.Type.FullName);
}
[Test]
public void SelectManyInvocation()
{
string program = @"using System; using System.Linq;
class TestClass
{
static void M(string[] args)
{
var query = from w in args $from c in w$ select c - '0';
}
}";
var rr = Resolve<CSharpInvocationResolveResult>(program);
Assert.IsFalse(rr.IsError);
Assert.AreEqual("SelectMany", rr.Member.Name);
Assert.AreEqual(3, rr.Member.Parameters.Count);
var typeArguments = ((SpecializedMethod)rr.Member).TypeArguments;
Assert.AreEqual(3, typeArguments.Count);
Assert.AreEqual("System.String", typeArguments[0].ReflectionName, "TSource");
Assert.AreEqual("System.Char", typeArguments[1].ReflectionName, "TCollection");
Assert.AreEqual("System.Int32", typeArguments[2].ReflectionName, "TResult");
}
[Test]
public void SelectManyInvocationWithTransparentIdentifier()
{
string program = @"using System; using System.Linq;
class TestClass
{
static void M(string[] args)
{
var query = from w in args $from c in w$ orderby c select c - '0';
}
}";
var rr = Resolve<CSharpInvocationResolveResult>(program);
Assert.IsFalse(rr.IsError);
Assert.AreEqual("SelectMany", rr.Member.Name);
Assert.AreEqual(3, rr.Member.Parameters.Count);
var typeArguments = ((SpecializedMethod)rr.Member).TypeArguments;
Assert.AreEqual(3, typeArguments.Count);
Assert.AreEqual("System.String", typeArguments[0].ReflectionName, "TSource");
Assert.AreEqual("System.Char", typeArguments[1].ReflectionName, "TCollection");
Assert.AreEqual(TypeKind.Anonymous, typeArguments[2].Kind, "TResult");
}
}
}

Loading…
Cancel
Save