Browse Source

r7313@daniel-notebook (orig r3344): daniel | 2008-08-14 11:22:02 +0200

Fixed SD2-1400: Lambda type inference fails when using lambda in collection initializer


git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@3346 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 18 years ago
parent
commit
c1c5eb636d
  1. 1380
      src/Libraries/NRefactory/Project/Src/Parser/CSharp/Parser.cs
  2. 23
      src/Libraries/NRefactory/Project/Src/Parser/CSharp/cs.ATG
  3. 76
      src/Main/Base/Test/NRefactoryResolverTests.cs
  4. 5
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/ElementReturnType.cs
  5. 36
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/NRefactoryResolver.cs

1380
src/Libraries/NRefactory/Project/Src/Parser/CSharp/Parser.cs

File diff suppressed because it is too large Load Diff

23
src/Libraries/NRefactory/Project/Src/Parser/CSharp/cs.ATG

@ -916,23 +916,23 @@ StructMemberDecl<ModifierList m, List<AttributeSection> attributes>
fd.StartLocation = m.GetDeclarationLocation(startPos); fd.StartLocation = m.GetDeclarationLocation(startPos);
.) .)
( IF (m.Contains(Modifiers.Fixed)) ( IF (m.Contains(Modifiers.Fixed))
VariableDeclarator<variableDeclarators> VariableDeclarator<fd>
"[" "["
Expr<out expr> (. if (variableDeclarators.Count > 0) Expr<out expr> (. if (variableDeclarators.Count > 0)
variableDeclarators[variableDeclarators.Count-1].FixedArrayInitialization = expr; .) variableDeclarators[variableDeclarators.Count-1].FixedArrayInitialization = expr; .)
"]" "]"
{ "," { ","
VariableDeclarator<variableDeclarators> VariableDeclarator<fd>
"[" "["
Expr<out expr> (. if (variableDeclarators.Count > 0) Expr<out expr> (. if (variableDeclarators.Count > 0)
variableDeclarators[variableDeclarators.Count-1].FixedArrayInitialization = expr; .) variableDeclarators[variableDeclarators.Count-1].FixedArrayInitialization = expr; .)
"]" "]"
} }
| /* non-fixed field */ | /* non-fixed field */
VariableDeclarator<variableDeclarators> VariableDeclarator<fd>
{ "," VariableDeclarator<variableDeclarators> } { "," VariableDeclarator<fd> }
) )
";" (. fd.EndLocation = t.EndLocation; fd.Fields = variableDeclarators; compilationUnit.AddChild(fd); .) ";" (. fd.EndLocation = t.EndLocation; compilationUnit.AddChild(fd); .)
/*--- unqualified indexer declaration (without interface name): */ /*--- unqualified indexer declaration (without interface name): */
| (. m.Check(Modifiers.Indexers); .) | (. m.Check(Modifiers.Indexers); .)
@ -1241,11 +1241,12 @@ InterfaceAccessors<out PropertyGetRegion getBlock, out PropertySetRegion setBloc
] ]
. .
VariableDeclarator<List<VariableDeclaration> fieldDeclaration> VariableDeclarator<FieldDeclaration parentFieldDeclaration>
(. Expression expr = null; .) (. Expression expr = null; .)
= =
Identifier (. VariableDeclaration f = new VariableDeclaration(t.val); .) Identifier (. VariableDeclaration f = new VariableDeclaration(t.val); .)
[ "=" VariableInitializer<out expr> (. f.Initializer = expr; .) ] (. fieldDeclaration.Add(f); .) [ "=" VariableInitializer<out expr> (. f.Initializer = expr; .) ]
(. SafeAdd(parentFieldDeclaration, parentFieldDeclaration.Fields, f); .)
. .
Block<out Statement stmt> /* not BlockStatement because of EmbeddedStatement */ Block<out Statement stmt> /* not BlockStatement because of EmbeddedStatement */
@ -1370,10 +1371,10 @@ CollectionInitializer<out Expression outExpr>
= =
"{" (. initializer.StartLocation = t.Location; .) "{" (. initializer.StartLocation = t.Location; .)
[ VariableInitializer<out expr> [ VariableInitializer<out expr>
(. if (expr != null) { initializer.CreateExpressions.Add(expr); } .) (. SafeAdd(initializer, initializer.CreateExpressions, expr); .)
{ IF (NotFinalComma()) { IF (NotFinalComma())
"," VariableInitializer<out expr> "," VariableInitializer<out expr>
(. if (expr != null) { initializer.CreateExpressions.Add(expr); } .) (. SafeAdd(initializer, initializer.CreateExpressions, expr); .)
} }
[ "," ] [ "," ]
] ]
@ -1388,10 +1389,10 @@ CollectionOrObjectInitializer<out Expression outExpr>
= =
"{" (. initializer.StartLocation = t.Location; .) "{" (. initializer.StartLocation = t.Location; .)
[ ObjectPropertyInitializerOrVariableInitializer<out expr> [ ObjectPropertyInitializerOrVariableInitializer<out expr>
(. if (expr != null) { initializer.CreateExpressions.Add(expr); } .) (. SafeAdd(initializer, initializer.CreateExpressions, expr); .)
{ IF (NotFinalComma()) { IF (NotFinalComma())
"," ObjectPropertyInitializerOrVariableInitializer<out expr> "," ObjectPropertyInitializerOrVariableInitializer<out expr>
(. if (expr != null) { initializer.CreateExpressions.Add(expr); } .) (. SafeAdd(initializer, initializer.CreateExpressions, expr); .)
} }
[ "," ] [ "," ]
] ]

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

@ -2160,6 +2160,82 @@ class SomeClass<T> {
Assert.AreEqual("System.String", lrr.ResolvedType.DotNetName); Assert.AreEqual("System.String", lrr.ResolvedType.DotNetName);
} }
[Test]
public void LambdaInCollectionInitializerTest1()
{
string program = @"using System;
class TestClass {
static void Main() {
Converter<int, string>[] arr = {
i => i.ToString()
};
}
}
";
var lrr = Resolve<LocalResolveResult>(program, "i", 5, 9, ExpressionContext.Default);
Assert.AreEqual("System.Int32", lrr.ResolvedType.DotNetName);
}
[Test]
public void LambdaInCollectionInitializerTest2()
{
string program = @"using System; using System.Collections.Generic;
class TestClass {
static void Main() {
a = new List<Converter<int, string>> {
i => i.ToString()
};
}
}
";
var lrr = Resolve<LocalResolveResult>(program, "i", 5, 9, ExpressionContext.Default);
Assert.AreEqual("System.Int32", lrr.ResolvedType.DotNetName);
}
[Test]
public void LambdaInCollectionInitializerTest3()
{
string program = @"using System;
class TestClass {
static void Main() {
a = new Converter<int, string>[] {
i => i.ToString()
};
}
}
";
var lrr = Resolve<LocalResolveResult>(program, "i", 5, 9, ExpressionContext.Default);
Assert.AreEqual("System.Int32", lrr.ResolvedType.DotNetName);
}
[Test]
public void LambdaInCollectionInitializerTest4()
{
string program = @"using System;
class TestClass {
Converter<int, string>[] field = new Converter<int, string>[] {
i => i.ToString()
};
}
";
var lrr = Resolve<LocalResolveResult>(program, "i", 4, 8, ExpressionContext.Default);
Assert.AreEqual("System.Int32", lrr.ResolvedType.DotNetName);
}
[Test]
public void LambdaInCollectionInitializerTest5()
{
string program = @"using System;
class TestClass {
Converter<int, string>[] field = {
i => i.ToString()
};
}
";
var lrr = Resolve<LocalResolveResult>(program, "i", 4, 8, ExpressionContext.Default);
Assert.AreEqual("System.Int32", lrr.ResolvedType.DotNetName);
}
[Test] [Test]
public void IncompleteLambdaTest() public void IncompleteLambdaTest()
{ {

5
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/ElementReturnType.cs

@ -48,5 +48,10 @@ namespace ICSharpCode.SharpDevelop.Dom
return null; return null;
} }
} }
public override string ToString()
{
return "[ElementReturnType " + enumerableType + "]";
}
} }
} }

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

@ -1304,24 +1304,40 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
return GetExpectedTypeFromContext(expr.Parent as Expression); return GetExpectedTypeFromContext(expr.Parent as Expression);
} }
if (expr.Parent is VariableDeclaration) { if (expr.Parent is VariableDeclaration) {
TypeReference typeRef = (expr.Parent as VariableDeclaration).TypeReference; return GetTypeFromVariableDeclaration((VariableDeclaration)expr.Parent);
if (typeRef == null || typeRef.IsNull) {
LocalVariableDeclaration lvd = expr.Parent.Parent as LocalVariableDeclaration;
if (lvd != null)
typeRef = lvd.TypeReference;
FieldDeclaration fd = expr.Parent.Parent as FieldDeclaration;
if (fd != null)
typeRef = fd.TypeReference;
}
return TypeVisitor.CreateReturnType(typeRef, this);
} }
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;
} }
if (expr.Parent is CollectionInitializerExpression) {
IReturnType collectionType;
if (expr.Parent.Parent is ObjectCreateExpression)
collectionType = TypeVisitor.CreateReturnType(((ObjectCreateExpression)expr.Parent.Parent).CreateType, this);
else if (expr.Parent.Parent is ArrayCreateExpression)
collectionType = TypeVisitor.CreateReturnType(((ArrayCreateExpression)expr.Parent.Parent).CreateType, this);
else if (expr.Parent.Parent is VariableDeclaration)
collectionType = GetTypeFromVariableDeclaration((VariableDeclaration)expr.Parent.Parent);
else
collectionType = null;
if (collectionType != null)
return new ElementReturnType(projectContent, collectionType);
}
return null; return null;
} }
IReturnType GetTypeFromVariableDeclaration(VariableDeclaration varDecl)
{
TypeReference typeRef = varDecl.TypeReference;
if (typeRef == null || typeRef.IsNull) {
LocalVariableDeclaration lvd = varDecl.Parent as LocalVariableDeclaration;
if (lvd != null) typeRef = lvd.TypeReference;
FieldDeclaration fd = varDecl.Parent as FieldDeclaration;
if (fd != null) typeRef = fd.TypeReference;
}
return TypeVisitor.CreateReturnType(typeRef, this);
}
} }
} }

Loading…
Cancel
Save