Browse Source

Fixed type inference for methods with expression tree parameters.

Use the return type of .Select() or .GroupBy() as type of query expressions.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/3.0@3661 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 17 years ago
parent
commit
ce64b86579
  1. 8
      src/Main/Base/Project/Src/TextEditor/Commands/CodeGenerators/EqualsCodeGenerator.cs
  2. 2
      src/Main/Base/Project/Src/TextEditor/Gui/Editor/QuickClassBrowserPanel.cs
  3. 62
      src/Main/Base/Test/NRefactoryResolverTests.cs
  4. 4
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/LambdaReturnType.cs
  5. 42
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/ResolveVisitor.cs

8
src/Main/Base/Project/Src/TextEditor/Commands/CodeGenerators/EqualsCodeGenerator.cs

@ -35,7 +35,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Commands @@ -35,7 +35,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Commands
public override void GenerateCode(List<AbstractNode> nodes, IList items)
{
TypeReference intReference = new TypeReference("System.Int32");
TypeReference intReference = new TypeReference("System.Int32", true);
MethodDeclaration method = new MethodDeclaration {
Name = "GetHashCode",
Modifier = Modifiers.Public | Modifiers.Override,
@ -90,8 +90,8 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Commands @@ -90,8 +90,8 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Commands
method.Body.AddChild(new ReturnStatement(new IdentifierExpression(var.Name)));
nodes.Add(method);
TypeReference boolReference = new TypeReference("System.Boolean");
TypeReference objectReference = new TypeReference("System.Object");
TypeReference boolReference = new TypeReference("System.Boolean", true);
TypeReference objectReference = new TypeReference("System.Object", true);
method = new MethodDeclaration {
Name = "Equals",
@ -186,7 +186,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Commands @@ -186,7 +186,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Commands
new MemberReferenceExpression(new IdentifierExpression(other), field.Name));
} else {
InvocationExpression ie = new InvocationExpression(
new MemberReferenceExpression(new TypeReferenceExpression("System.Object"), "Equals")
new MemberReferenceExpression(new TypeReferenceExpression(new TypeReference("System.Object", true)), "Equals")
);
ie.Arguments.Add(new MemberReferenceExpression(new ThisReferenceExpression(), field.Name));
ie.Arguments.Add(new MemberReferenceExpression(new IdentifierExpression(other), field.Name));

2
src/Main/Base/Project/Src/TextEditor/Gui/Editor/QuickClassBrowserPanel.cs

@ -451,7 +451,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor @@ -451,7 +451,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
void ComboBoxSelectedIndexChanged(object sender, System.EventArgs e)
{
ComboBox comboBox = (ComboBox)sender;
if (autoselect) {
if (autoselect && comboBox.SelectedIndex >= 0) {
ComboBoxItem item = (ComboBoxItem)comboBox.Items[comboBox.SelectedIndex];
if (item.IsInCurrentPart) {
textAreaControl.ActiveTextAreaControl.CenterViewOn(

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

@ -31,6 +31,7 @@ namespace ICSharpCode.SharpDevelop.Tests @@ -31,6 +31,7 @@ namespace ICSharpCode.SharpDevelop.Tests
p.Parse();
DefaultProjectContent pc = new DefaultProjectContent();
pc.ReferencedContents.Add(projectContentRegistry.Mscorlib);
pc.ReferencedContents.Add(projectContentRegistry.GetProjectContentForReference("System.Core", "System.Core"));
pc.ReferencedContents.Add(projectContentRegistry.GetProjectContentForReference("System.Windows.Forms", "System.Windows.Forms"));
HostCallback.GetCurrentProjectContent = delegate {
return pc;
@ -1760,7 +1761,7 @@ public static class XC { @@ -1760,7 +1761,7 @@ public static class XC {
[Test]
public void SimpleLinqTest()
{
string program = @"using System;
string program = @"using System; using System.Linq;
class TestClass {
void Test(string[] input) {
var r = from e in input
@ -1780,6 +1781,46 @@ class TestClass { @@ -1780,6 +1781,46 @@ class TestClass {
Assert.AreEqual("System.String", lrr.ResolvedType.CastToConstructedReturnType().TypeArguments[0].FullyQualifiedName);
}
[Test]
public void LinqGroupTest()
{
string program = @"using System; using System.Linq;
class TestClass {
void Test(string[] input) {
var r = from e in input
group e.ToUpper() by e.Length;
}
}
";
LocalResolveResult lrr = Resolve<LocalResolveResult>(program, "r", 7);
Assert.AreEqual("System.Collections.Generic.IEnumerable", lrr.ResolvedType.FullyQualifiedName);
ConstructedReturnType rt = lrr.ResolvedType.CastToConstructedReturnType().TypeArguments[0].CastToConstructedReturnType();
Assert.AreEqual("System.Linq.IGrouping", rt.FullyQualifiedName);
Assert.AreEqual("System.Int32", rt.TypeArguments[0].FullyQualifiedName);
Assert.AreEqual("System.String", rt.TypeArguments[1].FullyQualifiedName);
}
[Test]
public void LinqQueryableGroupTest()
{
string program = @"using System; using System.Linq;
class TestClass {
void Test(IQueryable<string> input) {
var r = from e in input
group e.ToUpper() by e.Length;
}
}
";
LocalResolveResult lrr = Resolve<LocalResolveResult>(program, "r", 7);
Assert.AreEqual("System.Linq.IQueryable", lrr.ResolvedType.FullyQualifiedName);
ConstructedReturnType rt = lrr.ResolvedType.CastToConstructedReturnType().TypeArguments[0].CastToConstructedReturnType();
Assert.AreEqual("System.Linq.IGrouping", rt.FullyQualifiedName);
Assert.AreEqual("System.Int32", rt.TypeArguments[0].FullyQualifiedName);
Assert.AreEqual("System.String", rt.TypeArguments[1].FullyQualifiedName);
}
[Test]
public void ParenthesizedLinqTest()
{
@ -1798,6 +1839,23 @@ class TestClass { @@ -1798,6 +1839,23 @@ class TestClass {
Assert.AreEqual("System.Int32", rr.ResolvedType.CastToConstructedReturnType().TypeArguments[0].FullyQualifiedName);
}
[Test]
public void LinqSelectReturnTypeTest()
{
string program = @"using System;
class TestClass { static void M() {
(from a in new XYZ() select a.ToUpper())
}}
class XYZ {
public int Select<U>(Func<string, U> f) { return 42; }
}";
ResolveResult rr = Resolve(program,
"(from a in new XYZ() select a.ToUpper())",
3, 2, ExpressionContext.Default);
Assert.IsNotNull(rr);
Assert.AreEqual("System.Int32", rr.ResolvedType.FullyQualifiedName);
}
const string objectInitializerTestProgram = @"using System; using System.Threading;
class TestClass {
static void Test() {
@ -1890,7 +1948,7 @@ public class MyCollectionType : System.Collections.IEnumerable @@ -1890,7 +1948,7 @@ public class MyCollectionType : System.Collections.IEnumerable
[Test]
public void LinqQueryContinuationTest()
{
string program = @"using System;
string program = @"using System; using System.Linq;
class TestClass {
void Test(string[] input) {
var r = from x in input

4
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/LambdaReturnType.cs

@ -19,6 +19,10 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -19,6 +19,10 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
LambdaExpression lambdaExpression;
List<Expression> returnExpressions = new List<Expression>();
public override bool CanBeConvertedToExpressionTree {
get { return lambdaExpression != null; }
}
internal LambdaReturnType(LambdaExpression expression, NRefactoryResolver resolver)
: base(resolver.CompilationUnit)
{

42
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/ResolveVisitor.cs

@ -549,22 +549,40 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -549,22 +549,40 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
public override object VisitQueryExpression(QueryExpression queryExpression, object data)
{
IReturnType type = null;
QueryExpressionSelectClause selectClause = queryExpression.SelectOrGroupClause as QueryExpressionSelectClause;
QueryExpressionGroupClause groupClause = queryExpression.SelectOrGroupClause as QueryExpressionGroupClause;
if (selectClause != null) {
type = ResolveType(selectClause.Projection);
// Fake a call to 'Select'
var fakeInvocation = new InvocationExpression(new MemberReferenceExpression(
queryExpression.FromClause.InExpression, "Select"));
var selector = new LambdaExpression();
selector.Parameters.Add(new ParameterDeclarationExpression(null, "__rangeVariable"));
selector.ExpressionBody = selectClause.Projection;
selector.Parent = fakeInvocation;
fakeInvocation.Arguments.Add(selector);
return CreateResolveResult(ResolveType(fakeInvocation));
} else if (groupClause != null) {
type = new ConstructedReturnType(
new GetClassReturnType(resolver.ProjectContent, "System.Linq.IGrouping", 2),
new IReturnType[] { ResolveType(groupClause.GroupBy), ResolveType(groupClause.Projection) }
);
}
if (type != null) {
return CreateResolveResult(new ConstructedReturnType(
new GetClassReturnType(resolver.ProjectContent, "System.Collections.Generic.IEnumerable", 1),
new IReturnType[] { type }
));
// Fake a call to 'GroupBy'
var fakeInvocation = new InvocationExpression(new MemberReferenceExpression(
queryExpression.FromClause.InExpression, "GroupBy"));
var keySelector = new LambdaExpression();
keySelector.Parameters.Add(new ParameterDeclarationExpression(null, "__rangeVariable"));
keySelector.ExpressionBody = groupClause.GroupBy;
keySelector.Parent = fakeInvocation;
var elementSelector = new LambdaExpression();
elementSelector.Parameters.Add(new ParameterDeclarationExpression(null, "__rangeVariable"));
elementSelector.ExpressionBody = groupClause.Projection;
elementSelector.Parent = fakeInvocation;
fakeInvocation.Arguments.Add(keySelector);
fakeInvocation.Arguments.Add(elementSelector);
return CreateResolveResult(ResolveType(fakeInvocation));
} else {
return null;
}

Loading…
Cancel
Save