diff --git a/ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs b/ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs index 04e16ab79b..67864dbde1 100644 --- a/ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs +++ b/ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs @@ -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 return GetElementTypeFromIEnumerable(type, resolver.Compilation, false); } + ResolveResult MakeTransparentIdentifierResolveResult() + { + return new ResolveResult(new AnonymousType(resolver.Compilation, EmptyList.Instance)); + } + sealed class QueryExpressionLambdaConversion : Conversion { internal readonly IType[] ParameterTypes; @@ -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.Instance, true); ResolveResult[] arguments = { @@ -3401,7 +3405,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver if (resolverEnabled && currentQueryResult != null) { // resolve the .Select() call ResolveResult methodGroup = resolver.ResolveMemberAccess(currentQueryResult, "Select", EmptyList.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 selectResult = Resolve(selectClause.Expression); } else { // from .. join ... ... - introduce a transparent identifier - selectResult = transparentIdentifierResolveResult; + selectResult = MakeTransparentIdentifierResolveResult(); } var methodGroup = resolver.ResolveMemberAccess(currentQueryResult, "Join", EmptyList.Instance); @@ -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 = { diff --git a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/LinqTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/LinqTests.cs index f25973fc89..2ef6cc1bcd 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/LinqTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/LinqTests.cs @@ -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 var rr = Resolve(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(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(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"); + } } }