Browse Source

r7315@daniel-notebook (orig r3346): daniel | 2008-08-14 12:12:18 +0200

Fixed SD2-1398: Lambda type inference fails when returning a lambda.


git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@3348 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 17 years ago
parent
commit
ec1ff43533
  1. 49
      src/Main/Base/Test/NRefactoryResolverTests.cs
  2. 39
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/NRefactoryResolver.cs
  3. 9
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ProjectContent/DefaultProjectContent.cs

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

@ -2239,7 +2239,7 @@ class TestClass { @@ -2239,7 +2239,7 @@ class TestClass {
[Test]
public void LambdaInObjectInitializerTest()
{
string program = @"using System;
string program = @"using System;
class X {
void SomeMethod() {
Helper h = new Helper {
@ -2299,6 +2299,53 @@ static class TestClass { @@ -2299,6 +2299,53 @@ static class TestClass {
Assert.AreEqual("System.Int32", lrr.ResolvedType.DotNetName);
}
[Test]
public void LambdaExpressionInReturnStatement()
{
string program = @"using System;
static class TestClass {
static Converter<int, string> GetToString() {
return i => i.ToString();
}
}";
var lrr = Resolve<LocalResolveResult>(program, "i", 4, 15, ExpressionContext.Default);
Assert.AreEqual("System.Int32", lrr.ResolvedType.DotNetName);
}
[Test]
public void LambdaExpressionInReturnStatementInStatementLambda()
{
string program = @"using System;
static class TestClass {
static void SomeMethod() {
Func<Func<string, string>> getStringTransformer = () => {
return s => s.ToUpper();
};
}
public delegate R Func<T, R>(T arg);
public delegate R Func<R>();
}";
var lrr = Resolve<LocalResolveResult>(program, "s", 5, 16, ExpressionContext.Default);
Assert.AreEqual("System.String", lrr.ResolvedType.DotNetName);
}
[Test]
public void LambdaExpressionInReturnStatementInAnonymousMethod()
{
string program = @"using System;
static class TestClass {
static void SomeMethod() {
Func<Func<string, string>> getStringTransformer = delegate {
return s => s.ToUpper();
};
}
public delegate R Func<T, R>(T arg);
public delegate R Func<R>();
}";
var lrr = Resolve<LocalResolveResult>(program, "s", 5, 16, ExpressionContext.Default);
Assert.AreEqual("System.String", lrr.ResolvedType.DotNetName);
}
[Test]
public void CurriedLambdaExpressionInCastExpression()
{

39
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/NRefactoryResolver.cs

@ -1305,30 +1305,35 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -1305,30 +1305,35 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
ResolveResult rr = ResolveInternal((Expression)expr.Parent, ExpressionContext.Default);
if (rr != null)
return rr.ResolvedType;
}
if (expr.Parent is LambdaExpression) {
} else if (expr.Parent is LambdaExpression) {
IReturnType delegateType = GetExpectedTypeFromContext(expr.Parent as Expression);
IMethod sig = CSharp.TypeInference.GetDelegateOrExpressionTreeSignature(delegateType, true);
if (sig != null)
return sig.ReturnType;
}
if (expr.Parent is ParenthesizedExpression) {
} else if (expr.Parent is ReturnStatement) {
Expression lambda = GetParentAnonymousMethodOrLambda(expr.Parent);
if (lambda != null) {
IReturnType delegateType = GetExpectedTypeFromContext(lambda);
IMethod sig = CSharp.TypeInference.GetDelegateOrExpressionTreeSignature(delegateType, true);
if (sig != null)
return sig.ReturnType;
} else {
if (callingMember != null)
return callingMember.ReturnType;
}
} else if (expr.Parent is ParenthesizedExpression) {
return GetExpectedTypeFromContext(expr.Parent as Expression);
}
if (expr.Parent is VariableDeclaration) {
} else if (expr.Parent is VariableDeclaration) {
return GetTypeFromVariableDeclaration((VariableDeclaration)expr.Parent);
}
if (expr.Parent is AssignmentExpression) {
} else if (expr.Parent is AssignmentExpression) {
ResolveResult rr = ResolveInternal((expr.Parent as AssignmentExpression).Left, ExpressionContext.Default);
if (rr != null)
return rr.ResolvedType;
}
if (expr.Parent is NamedArgumentExpression) {
} else if (expr.Parent is NamedArgumentExpression) {
IMember m = ResolveNamedArgumentExpressionInObjectInitializer((NamedArgumentExpression)expr.Parent);
if (m != null)
return m.ReturnType;
}
if (expr.Parent is CollectionInitializerExpression) {
} else if (expr.Parent is CollectionInitializerExpression) {
IReturnType collectionType;
if (expr.Parent.Parent is ObjectCreateExpression)
collectionType = TypeVisitor.CreateReturnType(((ObjectCreateExpression)expr.Parent.Parent).CreateType, this);
@ -1343,6 +1348,16 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -1343,6 +1348,16 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
}
return null;
}
Expression GetParentAnonymousMethodOrLambda(INode node)
{
while (node != null) {
if (node is AnonymousMethodExpression || node is LambdaExpression)
return (Expression)node;
node = node.Parent;
}
return null;
}
IReturnType GetTypeFromVariableDeclaration(VariableDeclaration varDecl)
{

9
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ProjectContent/DefaultProjectContent.cs

@ -813,8 +813,13 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -813,8 +813,13 @@ namespace ICSharpCode.SharpDevelop.Dom
foreach (IClass baseClass in request.CurrentType.ClassInheritanceTree) {
if (baseClass.ClassType == ClassType.Class) {
foreach (IClass innerClass in baseClass.InnerClasses) {
if (language.NameComparer.Equals(innerClass.Name, name))
return new SearchTypeResult(innerClass);
if (language.NameComparer.Equals(innerClass.Name, name)) {
if (innerClass.TypeParameters.Count == request.TypeParameterCount) {
return new SearchTypeResult(innerClass);
} else {
fallbackResult = new SearchTypeResult(innerClass);
}
}
}
}
}

Loading…
Cancel
Save