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 18 years ago
parent
commit
ec1ff43533
  1. 47
      src/Main/Base/Test/NRefactoryResolverTests.cs
  2. 37
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/NRefactoryResolver.cs
  3. 7
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ProjectContent/DefaultProjectContent.cs

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

@ -2299,6 +2299,53 @@ static class TestClass {
Assert.AreEqual("System.Int32", lrr.ResolvedType.DotNetName); 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] [Test]
public void CurriedLambdaExpressionInCastExpression() public void CurriedLambdaExpressionInCastExpression()
{ {

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

@ -1305,30 +1305,35 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
ResolveResult rr = ResolveInternal((Expression)expr.Parent, ExpressionContext.Default); ResolveResult rr = ResolveInternal((Expression)expr.Parent, ExpressionContext.Default);
if (rr != null) if (rr != null)
return rr.ResolvedType; return rr.ResolvedType;
} } else if (expr.Parent is LambdaExpression) {
if (expr.Parent is LambdaExpression) {
IReturnType delegateType = GetExpectedTypeFromContext(expr.Parent as Expression); IReturnType delegateType = GetExpectedTypeFromContext(expr.Parent as Expression);
IMethod sig = CSharp.TypeInference.GetDelegateOrExpressionTreeSignature(delegateType, true); IMethod sig = CSharp.TypeInference.GetDelegateOrExpressionTreeSignature(delegateType, true);
if (sig != null) if (sig != null)
return sig.ReturnType; return sig.ReturnType;
} 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;
} }
if (expr.Parent is ParenthesizedExpression) { } else if (expr.Parent is ParenthesizedExpression) {
return GetExpectedTypeFromContext(expr.Parent as Expression); return GetExpectedTypeFromContext(expr.Parent as Expression);
} } else if (expr.Parent is VariableDeclaration) {
if (expr.Parent is VariableDeclaration) {
return GetTypeFromVariableDeclaration((VariableDeclaration)expr.Parent); return GetTypeFromVariableDeclaration((VariableDeclaration)expr.Parent);
} } else if (expr.Parent is AssignmentExpression) {
if (expr.Parent is AssignmentExpression) {
ResolveResult rr = ResolveInternal((expr.Parent as AssignmentExpression).Left, ExpressionContext.Default); ResolveResult rr = ResolveInternal((expr.Parent as AssignmentExpression).Left, ExpressionContext.Default);
if (rr != null) if (rr != null)
return rr.ResolvedType; return rr.ResolvedType;
} } else if (expr.Parent is NamedArgumentExpression) {
if (expr.Parent is NamedArgumentExpression) {
IMember m = ResolveNamedArgumentExpressionInObjectInitializer((NamedArgumentExpression)expr.Parent); IMember m = ResolveNamedArgumentExpressionInObjectInitializer((NamedArgumentExpression)expr.Parent);
if (m != null) if (m != null)
return m.ReturnType; return m.ReturnType;
} } else if (expr.Parent is CollectionInitializerExpression) {
if (expr.Parent is CollectionInitializerExpression) {
IReturnType collectionType; IReturnType collectionType;
if (expr.Parent.Parent is ObjectCreateExpression) if (expr.Parent.Parent is ObjectCreateExpression)
collectionType = TypeVisitor.CreateReturnType(((ObjectCreateExpression)expr.Parent.Parent).CreateType, this); collectionType = TypeVisitor.CreateReturnType(((ObjectCreateExpression)expr.Parent.Parent).CreateType, this);
@ -1344,6 +1349,16 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
return null; 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) IReturnType GetTypeFromVariableDeclaration(VariableDeclaration varDecl)
{ {
TypeReference typeRef = varDecl.TypeReference; TypeReference typeRef = varDecl.TypeReference;

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

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

Loading…
Cancel
Save