Browse Source

Fixed Issue #38: Parser Regression in ObjectCreate initialization

newNRvisualizers
Mike Krüger 14 years ago
parent
commit
7a69c6544b
  1. 131
      ICSharpCode.NRefactory.CSharp/Parser/CSharpParser.cs
  2. 789
      ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-parser.cs
  3. 7
      ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-parser.jay
  4. 9
      ICSharpCode.NRefactory.CSharp/Parser/mcs/expression.cs
  5. 4
      ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/ArrayCreateExpressionTests.cs
  6. 66
      ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/ObjectCreateExpressionTests.cs
  7. 1
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/LambdaTests.cs
  8. 2
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/ObjectCreationTests.cs

131
ICSharpCode.NRefactory.CSharp/Parser/CSharpParser.cs

@ -2721,74 +2721,77 @@ namespace ICSharpCode.NRefactory.CSharp @@ -2721,74 +2721,77 @@ namespace ICSharpCode.NRefactory.CSharp
}
void AddConvertCollectionOrObjectInitializers(Expression init, CollectionOrObjectInitializers minit)
{
var initLoc = LocationsBag.GetLocations(minit);
var commaLoc = LocationsBag.GetLocations(minit.Initializers);
int curComma = 0;
if (initLoc != null)
init.AddChild(new CSharpTokenNode(Convert(initLoc[0])), Roles.LBrace);
foreach (var expr in minit.Initializers)
{
var collectionInit = expr as CollectionElementInitializer;
if (collectionInit != null)
{
var parent = new ArrayInitializerExpression();
var braceLocs = LocationsBag.GetLocations(expr);
if (braceLocs != null)
parent.AddChild(new CSharpTokenNode(Convert(braceLocs[0])), Roles.LBrace);
for (int i = 0; i < collectionInit.Arguments.Count; i++)
{
var arg = collectionInit.Arguments[i] as CollectionElementInitializer.ElementInitializerArgument;
if (arg == null)
continue;
parent.AddChild((ICSharpCode.NRefactory.CSharp.Expression)arg.Expr.Accept(this), Roles.Expression);
}
{
var initLoc = LocationsBag.GetLocations(minit);
var commaLoc = LocationsBag.GetLocations(minit.Initializers);
int curComma = 0;
if (initLoc != null)
init.AddChild(new CSharpTokenNode(Convert(initLoc [0])), Roles.LBrace);
foreach (var expr in minit.Initializers) {
var collectionInit = expr as CollectionElementInitializer;
if (collectionInit != null) {
AstNode parent;
Console.WriteLine("single:" + collectionInit.IsSingle);
if (!collectionInit.IsSingle) {
parent = new ArrayInitializerExpression();
parent.AddChild(new CSharpTokenNode(Convert(collectionInit.Location)), Roles.LBrace);
} else {
parent = init;
}
for (int i = 0; i < collectionInit.Arguments.Count; i++) {
var arg = collectionInit.Arguments [i] as CollectionElementInitializer.ElementInitializerArgument;
if (arg == null)
continue;
parent.AddChild(
(ICSharpCode.NRefactory.CSharp.Expression)arg.Expr.Accept(this),
Roles.Expression
);
}
if (braceLocs != null && braceLocs.Count > 1)
parent.AddChild(new CSharpTokenNode(Convert(braceLocs[1])), Roles.RBrace);
if (!collectionInit.IsSingle) {
var braceLocs = LocationsBag.GetLocations(expr);
if (braceLocs != null)
parent.AddChild(new CSharpTokenNode(Convert(braceLocs [0])), Roles.RBrace);
init.AddChild((ArrayInitializerExpression)parent, Roles.Expression);
}
} else {
var eleInit = expr as ElementInitializer;
if (eleInit != null) {
var nexpr = new NamedExpression();
nexpr.AddChild(
Identifier.Create(eleInit.Name, Convert(eleInit.Location)),
Roles.Identifier
);
var assignLoc = LocationsBag.GetLocations(eleInit);
if (assignLoc != null)
nexpr.AddChild(new CSharpTokenNode(Convert(assignLoc [0])), Roles.Assign);
if (eleInit.Source != null) {
if (eleInit.Source is CollectionOrObjectInitializers) {
var arrInit = new ArrayInitializerExpression();
AddConvertCollectionOrObjectInitializers(
arrInit,
eleInit.Source as CollectionOrObjectInitializers
);
nexpr.AddChild(arrInit, Roles.Expression);
} else {
nexpr.AddChild((Expression)eleInit.Source.Accept(this), Roles.Expression);
}
}
init.AddChild(parent, Roles.Expression);
}
else
{
var eleInit = expr as ElementInitializer;
if (eleInit != null)
{
var nexpr = new NamedExpression();
nexpr.AddChild(Identifier.Create(eleInit.Name, Convert(eleInit.Location)), Roles.Identifier);
var assignLoc = LocationsBag.GetLocations(eleInit);
if (assignLoc != null)
nexpr.AddChild(new CSharpTokenNode(Convert(assignLoc[0])), Roles.Assign);
if (eleInit.Source != null)
{
if (eleInit.Source is CollectionOrObjectInitializers)
{
var arrInit = new ArrayInitializerExpression();
AddConvertCollectionOrObjectInitializers(arrInit, eleInit.Source as CollectionOrObjectInitializers);
nexpr.AddChild(arrInit, Roles.Expression);
}
else
{
nexpr.AddChild((Expression)eleInit.Source.Accept(this), Roles.Expression);
}
}
init.AddChild(nexpr, Roles.Expression);
}
}
if (commaLoc != null && curComma < commaLoc.Count)
init.AddChild(new CSharpTokenNode(Convert(commaLoc [curComma++])), Roles.Comma);
init.AddChild(nexpr, Roles.Expression);
}
}
if (commaLoc != null && curComma < commaLoc.Count)
init.AddChild(new CSharpTokenNode(Convert(commaLoc[curComma++])), Roles.Comma);
}
if (initLoc != null) {
if (initLoc.Count == 3) // optional comma
init.AddChild(new CSharpTokenNode(Convert(initLoc [1])), Roles.Comma);
init.AddChild(new CSharpTokenNode(Convert(initLoc [initLoc.Count - 1])), Roles.RBrace);
}
}
}
if (initLoc != null)
{
if (initLoc.Count == 3) // optional comma
init.AddChild(new CSharpTokenNode(Convert(initLoc[1])), Roles.Comma);
init.AddChild(new CSharpTokenNode(Convert(initLoc[initLoc.Count - 1])), Roles.RBrace);
}
}
public override object Visit (NewInitialize newInitializeExpression)
{

789
ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-parser.cs

File diff suppressed because it is too large Load Diff

7
ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-parser.jay

@ -3207,8 +3207,8 @@ object_or_collection_initializer @@ -3207,8 +3207,8 @@ object_or_collection_initializer
: OPEN_BRACE opt_member_initializer_list close_brace_or_complete_completion
{
if ($2 == null) {
$$ = CollectionOrObjectInitializers.Empty;
// TODO: lbag
$$ = new CollectionOrObjectInitializers (new List<Expression> (), GetLocation ($1));
lbag.AddLocation ($$, GetLocation ($1), GetLocation ($3));
} else {
$$ = new CollectionOrObjectInitializers ((List<Expression>) $2, GetLocation ($1));
lbag.AddLocation ($$, GetLocation ($1), GetLocation ($3));
@ -3279,7 +3279,8 @@ member_initializer @@ -3279,7 +3279,8 @@ member_initializer
| OPEN_BRACE CLOSE_BRACE
{
report.Error (1920, GetLocation ($1), "An element initializer cannot be empty");
$$ = null;
$$ = new CollectionElementInitializer (new List<Expression> (), GetLocation ($1));
lbag.AddLocation ($$, GetLocation ($2));
}
;

9
ICSharpCode.NRefactory.CSharp/Parser/mcs/expression.cs

@ -9843,6 +9843,9 @@ namespace Mono.CSharp @@ -9843,6 +9843,9 @@ namespace Mono.CSharp
//
class CollectionElementInitializer : Invocation
{
public readonly bool IsSingle;
public class ElementInitializerArgument : Argument
{
public ElementInitializerArgument (Expression e)
@ -9867,16 +9870,18 @@ namespace Mono.CSharp @@ -9867,16 +9870,18 @@ namespace Mono.CSharp
}
}
public CollectionElementInitializer (Expression argument)
public CollectionElementInitializer(Expression argument)
: base (null, new Arguments (1))
{
IsSingle = true;
base.arguments.Add (new ElementInitializerArgument (argument));
this.loc = argument.Location;
}
public CollectionElementInitializer (List<Expression> arguments, Location loc)
public CollectionElementInitializer(List<Expression> arguments, Location loc)
: base (null, new Arguments (arguments.Count))
{
IsSingle = false;
foreach (Expression e in arguments)
base.arguments.Add (new ElementInitializerArgument (e));

4
ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/ArrayCreateExpressionTests.cs

@ -101,7 +101,8 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Expression @@ -101,7 +101,8 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
new PrimitiveExpression(100),
new PrimitiveExpression(1000)
}
}});
}}
);
}
[Test]
@ -157,7 +158,6 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Expression @@ -157,7 +158,6 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
}, ace.Initializer.Children.Select(c => c.Role).ToArray());
}
[Test, Ignore("Parser bug")]
public void ArrayInitializerWithCommaAtEnd()
{

66
ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/ObjectCreateExpressionTests.cs

@ -163,13 +163,13 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Expression @@ -163,13 +163,13 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
Type = new SimpleType("List", new PrimitiveType("int")),
Initializer = new ArrayInitializerExpression {
Elements = {
new ArrayInitializerExpression(new PrimitiveExpression(0)),
new ArrayInitializerExpression(new PrimitiveExpression(1)),
new ArrayInitializerExpression(new PrimitiveExpression(2))
}}});
new PrimitiveExpression(0),
new PrimitiveExpression(1),
new PrimitiveExpression(2)
}}}
);
}
[Test]
public void DictionaryInitializer()
{
@ -205,31 +205,35 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Expression @@ -205,31 +205,35 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
new ObjectCreateExpression {
Type = new SimpleType("List", new SimpleType("Contact")),
Initializer = new ArrayInitializerExpression(
new ArrayInitializerExpression(
new ObjectCreateExpression {
Type = new SimpleType("Contact"),
Initializer = new ArrayInitializerExpression {
Elements = {
new NamedExpression("Name", new PrimitiveExpression("Chris")),
new NamedExpression("PhoneNumbers", new ArrayInitializerExpression () {
Elements = { new ArrayInitializerExpression(new PrimitiveExpression("206-555-0101")) }
})
}}}),
new ArrayInitializerExpression(
new ObjectCreateExpression {
Type = new SimpleType("Contact"),
Arguments = { new IdentifierExpression("additionalParameter") },
Initializer = new ArrayInitializerExpression {
Elements = {
new NamedExpression("Name", new PrimitiveExpression("Bob")),
new NamedExpression("PhoneNumbers", new ArrayInitializerExpression () {
Elements = {
new ArrayInitializerExpression(new PrimitiveExpression("650-555-0199")),
new ArrayInitializerExpression(new PrimitiveExpression("425-882-8080"))
}
})
}}})
)});
new ObjectCreateExpression {
Type = new SimpleType("Contact"),
Initializer = new ArrayInitializerExpression {
Elements = {
new NamedExpression("Name", new PrimitiveExpression("Chris")),
new NamedExpression("PhoneNumbers", new ArrayInitializerExpression () {
Elements = { new PrimitiveExpression("206-555-0101") }
})
}
}
},
new ObjectCreateExpression {
Type = new SimpleType("Contact"),
Arguments = { new IdentifierExpression("additionalParameter") },
Initializer = new ArrayInitializerExpression {
Elements = {
new NamedExpression("Name", new PrimitiveExpression("Bob")),
new NamedExpression("PhoneNumbers", new ArrayInitializerExpression () {
Elements = {
new PrimitiveExpression("650-555-0199"),
new PrimitiveExpression("425-882-8080")
}
})
}
}
}
)
}
);
}
[Test]

1
ICSharpCode.NRefactory.Tests/CSharp/Resolver/LambdaTests.cs

@ -165,6 +165,7 @@ class TestClass { @@ -165,6 +165,7 @@ class TestClass {
#endregion
#region Lambda In Collection Initializer
[Ignore("Got broken due to ArrayInitializer fix (the AST is now correct)")]
[Test]
public void LambdaInCollectionInitializer1()
{

2
ICSharpCode.NRefactory.Tests/CSharp/Resolver/ObjectCreationTests.cs

@ -260,7 +260,7 @@ class Test { @@ -260,7 +260,7 @@ class Test {
Assert.IsFalse(rr.IsError);
Assert.AreEqual("Test..ctor", rr.Member.FullName);
Assert.AreEqual("Test", rr.Type.ReflectionName);
Assert.AreEqual(5, rr.InitializerStatements.Count);
Assert.AreEqual(3, rr.InitializerStatements.Count);
}
[Test]

Loading…
Cancel
Save