From f30490c2a58f577597ae2152450ad875515e549a Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Fri, 8 Apr 2011 21:33:25 +0200 Subject: [PATCH] Add some parser unit tests. --- .../GeneralScope/AttributeSectionTests.cs | 57 ++++-- .../Parser/Statements/FixedStatementTests.cs | 28 ++- .../Parser/Statements/UsingStatementTests.cs | 18 +- .../VariableDeclarationStatementTests.cs | 181 ++++++++---------- .../CSharp/Resolver/LambdaTests.cs | 14 ++ ICSharpCode.NRefactory/CSharp/Ast/AstType.cs | 22 +++ 6 files changed, 202 insertions(+), 118 deletions(-) diff --git a/ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/AttributeSectionTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/AttributeSectionTests.cs index ce21addc4c..11450dd976 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/AttributeSectionTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/AttributeSectionTests.cs @@ -3,28 +3,31 @@ using System; using System.Linq; +using System.Text.RegularExpressions; +using ICSharpCode.NRefactory.PatternMatching; using NUnit.Framework; namespace ICSharpCode.NRefactory.CSharp.Parser.GeneralScope { - [TestFixture, Ignore] + [TestFixture] public class AttributeSectionTests { - [Test, Ignore] + [Test, Ignore("Parser crash")] public void GlobalAttributeCSharp() { string program = @"[global::Microsoft.VisualBasic.CompilerServices.DesignerGenerated()] [someprefix::DesignerGenerated()] public class Form1 { }"; - // TODO This old NRefactory test checked that [global] attributes are incorrectly applied to the following type??? - //TypeDeclaration decl = ParseUtilCSharp.ParseGlobal(program); - //Assert.AreEqual("Microsoft.VisualBasic.CompilerServices.DesignerGenerated", decl.Attributes.First().Attributes.Single().Name); - //Assert.AreEqual("someprefix.DesignerGenerated", decl.Attributes.Last().Attributes.Single().Name); + TypeDeclaration decl = ParseUtilCSharp.ParseGlobal(program); + Assert.AreEqual(2, decl.Attributes.Count); + Assert.AreEqual("global::Microsoft.VisualBasic.CompilerServices.DesignerGenerated", + decl.Attributes.First().Attributes.Single().Type.ToString()); + Assert.AreEqual("someprefix::DesignerGenerated", decl.Attributes.Last().Attributes.Single().Type.ToString()); } - [Test] + [Test, Ignore("assembly/module attributes are broken")] public void AssemblyAttributeCSharp() { string program = @"[assembly: System.Attribute()]"; @@ -33,7 +36,7 @@ public class Form1 { Assert.AreEqual("assembly", decl.AttributeTarget); } - [Test] + [Test, Ignore("assembly/module attributes are broken")] public void AssemblyAttributeCSharpWithNamedArguments() { string program = @"[assembly: Foo(1, namedArg: 2, prop = 3)]"; @@ -43,16 +46,25 @@ public class Form1 { Assert.AreEqual("Foo", a.Type); Assert.AreEqual(3, a.Arguments.Count()); - // TODO: check arguments + Assert.IsTrue(a.Arguments.ElementAt(0).IsMatch(new PrimitiveExpression(1))); + Assert.IsTrue(a.Arguments.ElementAt(1).IsMatch(new NamedArgumentExpression { + Identifier = "namedArg", + Expression = new PrimitiveExpression(2) + })); + Assert.IsTrue(a.Arguments.ElementAt(2).IsMatch(new AssignmentExpression { + Left = new IdentifierExpression("prop"), + Operator = AssignmentOperatorType.Assign, + Right = new PrimitiveExpression(3) + })); } - [Test] + [Test, Ignore("assembly/module attributes are broken")] public void ModuleAttributeCSharp() { string program = @"[module: System.Attribute()]"; AttributeSection decl = ParseUtilCSharp.ParseGlobal(program); Assert.AreEqual(new AstLocation(1, 1), decl.StartLocation); - Assert.AreEqual(AttributeTarget.Module, decl.AttributeTarget); + Assert.AreEqual("module", decl.AttributeTarget); } [Test] @@ -62,7 +74,28 @@ public class Form1 { TypeDeclaration type = ParseUtilCSharp.ParseGlobal(program); AttributeSection decl = type.Attributes.Single(); Assert.AreEqual(new AstLocation(1, 1), decl.StartLocation); - Assert.AreEqual(AttributeTarget.Type, decl.AttributeTarget); + Assert.AreEqual("type", decl.AttributeTarget); + } + + [Test, Ignore("Parser doesn't support attributes on type parameters")] + public void AttributesOnTypeParameter() + { + string program = @"class Test<[A,B]C> {}"; + TypeDeclaration type = ParseUtilCSharp.ParseGlobal(program); + Assert.IsTrue( + new TypeParameterDeclaration { + Attributes = { + new AttributeSection { + Attributes = { + new Attribute { Type = new SimpleType("A") }, + new Attribute { Type = new SimpleType("B") } + } + } + }, + Name = "C" + }.IsMatch(type.TypeParameters.Single())); } + + // TODO: Tests for other contexts where attributes can appear } } diff --git a/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/FixedStatementTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/FixedStatementTests.cs index 4259e3a157..374bf760b5 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/FixedStatementTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/FixedStatementTests.cs @@ -12,15 +12,37 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Statements [Test] public void FixedStatementTest() { - FixedStatement fixedStmt = ParseUtilCSharp.ParseStatement("fixed (int* ptr = &myIntArr) { }"); ParseUtilCSharp.AssertStatement( - "fixed (int* ptr = &myIntArr) { }", + "fixed (int* ptr = myIntArr) { }", new FixedStatement { Type = new PrimitiveType("int").MakePointerType(), Variables = { new VariableInitializer { Name = "ptr", - Initializer = new UnaryOperatorExpression(UnaryOperatorType.AddressOf, new IdentifierExpression("myIntArr")) + Initializer = new IdentifierExpression("myIntArr") + } + }, + EmbeddedStatement = new BlockStatement() + }); + } + + [Test] + public void FixedStatementWithMultipleVariables() + { + ParseUtilCSharp.AssertStatement( + "fixed (int* ptr1 = &myIntArr[1], ptr2 = myIntArr) { }", + new FixedStatement { + Type = new PrimitiveType("int").MakePointerType(), + Variables = { + new VariableInitializer { + Name = "ptr1", + Initializer = new UnaryOperatorExpression( + UnaryOperatorType.AddressOf, + new IndexerExpression { Target = new IdentifierExpression("myIntArr"), Arguments = { new PrimitiveExpression(1) } }) + }, + new VariableInitializer { + Name = "ptr2", + Initializer = new IdentifierExpression("myIntArr") } }, EmbeddedStatement = new BlockStatement() diff --git a/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/UsingStatementTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/UsingStatementTests.cs index 785b913557..db377d0782 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/UsingStatementTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/UsingStatementTests.cs @@ -2,6 +2,7 @@ // This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; +using System.Linq; using NUnit.Framework; namespace ICSharpCode.NRefactory.CSharp.Parser.Statements @@ -9,11 +10,22 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Statements [TestFixture] public class UsingStatementTests { - [Test] - public void UsingStatementTest() + [Test, Ignore("Parser doesn't report the VariableDeclarationStatement")] + public void UsingStatementWithVariableDeclaration() { UsingStatement usingStmt = ParseUtilCSharp.ParseStatement("using (MyVar var = new MyVar()) { } "); - // TODO : Extend test. + VariableDeclarationStatement varDecl = (VariableDeclarationStatement)usingStmt.ResourceAcquisition; + Assert.AreEqual("var", varDecl.Variables.Single().Name); + Assert.IsTrue(varDecl.Variables.Single().Initializer is ObjectCreateExpression); + Assert.AreEqual("MyVar", ((SimpleType)varDecl.Type).Identifier); + Assert.IsTrue(usingStmt.EmbeddedStatement is BlockStatement); + } + + public void UsingStatementWithExpression() + { + UsingStatement usingStmt = ParseUtilCSharp.ParseStatement("using (new MyVar()) { } "); + Assert.IsTrue(usingStmt.ResourceAcquisition is ObjectCreateExpression); + Assert.IsTrue(usingStmt.EmbeddedStatement is BlockStatement); } } } diff --git a/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/VariableDeclarationStatementTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/VariableDeclarationStatementTests.cs index 8e4c5fa398..74564a6bf8 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/VariableDeclarationStatementTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/VariableDeclarationStatementTests.cs @@ -3,6 +3,7 @@ using System; using System.Linq; +using ICSharpCode.NRefactory.PatternMatching; using NUnit.Framework; namespace ICSharpCode.NRefactory.CSharp.Parser.Statements @@ -21,185 +22,137 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Statements Assert.AreEqual(5, ((PrimitiveExpression)lvd.Variables.First ().Initializer).Value); } - /* TODO port unit tests [Test] public void VoidPointerVariableDeclarationTest() { VariableDeclarationStatement lvd = ParseUtilCSharp.ParseStatement("void *a;"); - Assert.AreEqual(1, lvd.Variables.Count); - Assert.AreEqual("a", ((VariableDeclaration)lvd.Variables[0]).Name); - TypeReference type = lvd.GetTypeForVariable(0); - Assert.AreEqual("System.Void", type.Type); - Assert.AreEqual(1, type.PointerNestingLevel); + Assert.IsTrue(new VariableDeclarationStatement(new PrimitiveType("void").MakePointerType(), "a").IsMatch(lvd)); } [Test] public void ComplexGenericVariableDeclarationStatementTest() { VariableDeclarationStatement lvd = ParseUtilCSharp.ParseStatement("Generic > where = new Generic>();"); - Assert.AreEqual(1, lvd.Variables.Count); - Assert.AreEqual("where", ((VariableDeclaration)lvd.Variables[0]).Name); - TypeReference type = lvd.GetTypeForVariable(0); - Assert.AreEqual("Generic", type.Type); - Assert.AreEqual(2, type.GenericTypes.Count); - Assert.AreEqual("Namespace.Printable", type.GenericTypes[0].Type); - Assert.AreEqual(0, type.GenericTypes[0].GenericTypes.Count); - Assert.AreEqual("G", type.GenericTypes[1].Type); - Assert.AreEqual(1, type.GenericTypes[1].GenericTypes.Count); - Assert.AreEqual("Printable", type.GenericTypes[1].GenericTypes[0].Type); - - // TODO: Check initializer + AstType type = new SimpleType("Generic") { + TypeArguments = { + new MemberType { Target = new SimpleType("Namespace"), MemberName = "Printable" }, + new SimpleType("G") { TypeArguments = { new SimpleType("Printable").MakeArrayType() } } + }}; + Assert.IsTrue(new VariableDeclarationStatement(type, "where", new ObjectCreateExpression { Type = type.Clone() }).IsMatch(lvd)); } [Test] public void NestedGenericVariableDeclarationStatementTest() { VariableDeclarationStatement lvd = ParseUtilCSharp.ParseStatement("MyType.InnerClass.InnerInnerClass a;"); - Assert.AreEqual(1, lvd.Variables.Count); - InnerClassTypeReference ic = (InnerClassTypeReference)lvd.GetTypeForVariable(0); - Assert.AreEqual("InnerInnerClass", ic.Type); - Assert.AreEqual(0, ic.GenericTypes.Count); - ic = (InnerClassTypeReference)ic.BaseType; - Assert.AreEqual("InnerClass", ic.Type); - Assert.AreEqual(1, ic.GenericTypes.Count); - Assert.AreEqual("System.Int32", ic.GenericTypes[0].Type); - Assert.AreEqual("MyType", ic.BaseType.Type); - Assert.AreEqual(1, ic.BaseType.GenericTypes.Count); - Assert.AreEqual("System.String", ic.BaseType.GenericTypes[0].Type); + AstType type = new MemberType { + Target = new MemberType { + Target = new SimpleType("MyType") { TypeArguments = { new PrimitiveType("string") } }, + MemberName = "InnerClass", + TypeArguments = { new PrimitiveType("int") } + }, + MemberName = "InnerInnerClass" + }; + Assert.IsTrue(new VariableDeclarationStatement(type, "a").IsMatch(lvd)); } [Test] public void GenericWithArrayVariableDeclarationStatementTest1() { VariableDeclarationStatement lvd = ParseUtilCSharp.ParseStatement("G[] a;"); - Assert.AreEqual(1, lvd.Variables.Count); - TypeReference type = lvd.GetTypeForVariable(0); - Assert.AreEqual("G", type.Type); - Assert.AreEqual(1, type.GenericTypes.Count); - Assert.AreEqual("System.Int32", type.GenericTypes[0].Type); - Assert.AreEqual(0, type.GenericTypes[0].GenericTypes.Count); - Assert.IsFalse(type.GenericTypes[0].IsArrayType); - Assert.AreEqual(new int[] {0}, type.RankSpecifier); + AstType type = new SimpleType("G") { + TypeArguments = { new PrimitiveType("int") } + }.MakeArrayType(); + Assert.IsTrue(new VariableDeclarationStatement(type, "a").IsMatch(lvd)); } [Test] public void GenericWithArrayVariableDeclarationStatementTest2() { VariableDeclarationStatement lvd = ParseUtilCSharp.ParseStatement("G a;"); - Assert.AreEqual(1, lvd.Variables.Count); - TypeReference type = lvd.GetTypeForVariable(0); - Assert.AreEqual("G", type.Type); - Assert.AreEqual(1, type.GenericTypes.Count); - Assert.AreEqual("System.Int32", type.GenericTypes[0].Type); - Assert.AreEqual(0, type.GenericTypes[0].GenericTypes.Count); - Assert.IsFalse(type.IsArrayType); - Assert.AreEqual(new int[] {0}, type.GenericTypes[0].RankSpecifier); + AstType type = new SimpleType("G") { + TypeArguments = { new PrimitiveType("int").MakeArrayType() } + }; + Assert.IsTrue(new VariableDeclarationStatement(type, "a").IsMatch(lvd)); } [Test] public void GenericVariableDeclarationStatementTest2() { VariableDeclarationStatement lvd = ParseUtilCSharp.ParseStatement("G > a;"); - Assert.AreEqual(1, lvd.Variables.Count); - TypeReference type = lvd.GetTypeForVariable(0); - Assert.AreEqual("G", type.Type); - Assert.AreEqual(1, type.GenericTypes.Count); - Assert.AreEqual("G", type.GenericTypes[0].Type); - Assert.AreEqual(1, type.GenericTypes[0].GenericTypes.Count); - Assert.AreEqual("System.Int32", type.GenericTypes[0].GenericTypes[0].Type); + AstType type = new SimpleType("G") { + TypeArguments = { + new SimpleType("G") { TypeArguments = { new PrimitiveType("int") } } + } + }; + Assert.IsTrue(new VariableDeclarationStatement(type, "a").IsMatch(lvd)); } [Test] public void GenericVariableDeclarationStatementTest2WithoutSpace() { VariableDeclarationStatement lvd = ParseUtilCSharp.ParseStatement("G> a;"); - Assert.AreEqual(1, lvd.Variables.Count); - TypeReference type = lvd.GetTypeForVariable(0); - Assert.AreEqual("G", type.Type); - Assert.AreEqual(1, type.GenericTypes.Count); - Assert.AreEqual("G", type.GenericTypes[0].Type); - Assert.AreEqual(1, type.GenericTypes[0].GenericTypes.Count); - Assert.AreEqual("System.Int32", type.GenericTypes[0].GenericTypes[0].Type); + AstType type = new SimpleType("G") { + TypeArguments = { + new SimpleType("G") { TypeArguments = { new PrimitiveType("int") } } + } + }; + Assert.IsTrue(new VariableDeclarationStatement(type, "a").IsMatch(lvd)); } [Test] public void GenericVariableDeclarationStatementTest() { VariableDeclarationStatement lvd = ParseUtilCSharp.ParseStatement("G a;"); - Assert.AreEqual(1, lvd.Variables.Count); - TypeReference type = lvd.GetTypeForVariable(0); - Assert.AreEqual("G", type.Type); - Assert.AreEqual(1, type.GenericTypes.Count); - Assert.AreEqual("System.Int32", type.GenericTypes[0].Type); + AstType type = new SimpleType("G") { + TypeArguments = { new PrimitiveType("int") } + }; + Assert.IsTrue(new VariableDeclarationStatement(type, "a").IsMatch(lvd)); } [Test] public void SimpleVariableDeclarationStatementTest() { VariableDeclarationStatement lvd = ParseUtilCSharp.ParseStatement("MyVar var = new MyVar();"); - Assert.AreEqual(1, lvd.Variables.Count); - Assert.AreEqual("var", ((VariableDeclaration)lvd.Variables[0]).Name); - TypeReference type = lvd.GetTypeForVariable(0); - Assert.AreEqual("MyVar", type.Type); - // TODO: Check initializer + Assert.IsTrue(new VariableDeclarationStatement(new SimpleType("MyVar"), "var", new ObjectCreateExpression { Type = new SimpleType("MyVar") }).IsMatch(lvd)); } [Test] public void SimpleVariableDeclarationStatementTest1() { VariableDeclarationStatement lvd = ParseUtilCSharp.ParseStatement("yield yield = new yield();"); - Assert.AreEqual(1, lvd.Variables.Count); - Assert.AreEqual("yield", ((VariableDeclaration)lvd.Variables[0]).Name); - TypeReference type = lvd.GetTypeForVariable(0); - Assert.AreEqual("yield", type.Type); - // TODO: Check initializer + Assert.IsTrue(new VariableDeclarationStatement(new SimpleType("yield"), "yield", new ObjectCreateExpression { Type = new SimpleType("yield") }).IsMatch(lvd)); } [Test] public void NullableVariableDeclarationStatementTest1() { VariableDeclarationStatement lvd = ParseUtilCSharp.ParseStatement("int? a;"); - Assert.AreEqual(1, lvd.Variables.Count); - Assert.AreEqual("a", ((VariableDeclaration)lvd.Variables[0]).Name); - TypeReference type = lvd.GetTypeForVariable(0); - Assert.AreEqual("System.Nullable", type.Type); - Assert.AreEqual("System.Int32", type.GenericTypes[0].Type); + Assert.IsTrue(new VariableDeclarationStatement(new PrimitiveType("int").MakeNullableType(), "a").IsMatch(lvd)); } [Test] public void NullableVariableDeclarationStatementTest2() { VariableDeclarationStatement lvd = ParseUtilCSharp.ParseStatement("DateTime? a;"); - Assert.AreEqual(1, lvd.Variables.Count); - Assert.AreEqual("a", ((VariableDeclaration)lvd.Variables[0]).Name); - TypeReference type = lvd.GetTypeForVariable(0); - Assert.AreEqual("System.Nullable", type.Type); - Assert.AreEqual("DateTime", type.GenericTypes[0].Type); + Assert.IsTrue(new VariableDeclarationStatement(new SimpleType("DateTime").MakeNullableType(), "a").IsMatch(lvd)); } - [Test] + [Test, Ignore("The parser creates nested ComposedTypes while MakeArrayType() adds the specifier to the existing ComposedType")] public void NullableVariableDeclarationStatementTest3() { VariableDeclarationStatement lvd = ParseUtilCSharp.ParseStatement("DateTime?[] a;"); - Assert.AreEqual(1, lvd.Variables.Count); - Assert.AreEqual("a", ((VariableDeclaration)lvd.Variables[0]).Name); - TypeReference type = lvd.GetTypeForVariable(0); - Assert.IsTrue(type.IsArrayType); - Assert.AreEqual("System.Nullable", type.Type); - Assert.AreEqual("DateTime", type.GenericTypes[0].Type); + Assert.IsTrue(new VariableDeclarationStatement(new SimpleType("DateTime").MakeNullableType().MakeArrayType(), "a").IsMatch(lvd)); } [Test] public void NullableVariableDeclarationStatementTest4() { VariableDeclarationStatement lvd = ParseUtilCSharp.ParseStatement("SomeStruct? a;"); - Assert.AreEqual(1, lvd.Variables.Count); - Assert.AreEqual("a", ((VariableDeclaration)lvd.Variables[0]).Name); - TypeReference type = lvd.GetTypeForVariable(0); - Assert.AreEqual("System.Nullable", type.Type); - Assert.AreEqual("SomeStruct", type.GenericTypes[0].Type); - Assert.AreEqual("System.Nullable", type.GenericTypes[0].GenericTypes[0].Type); - Assert.AreEqual("System.Int32", type.GenericTypes[0].GenericTypes[0].GenericTypes[0].Type); + AstType type = new SimpleType("SomeStruct") { + TypeArguments = { new PrimitiveType("int").MakeNullableType() } + }.MakeNullableType(); + Assert.IsTrue(new VariableDeclarationStatement(type, "a").IsMatch(lvd)); } [Test] @@ -216,11 +169,39 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Statements public void PositionTestWithModifier() { VariableDeclarationStatement lvd = ParseUtilCSharp.ParseStatement("\nconst double w = 7;"); - Assert.AreEqual(Modifiers.Const, lvd.Modifier); + Assert.AreEqual(Modifiers.Const, lvd.Modifiers); Assert.AreEqual(2, lvd.StartLocation.Line); Assert.AreEqual(1, lvd.StartLocation.Column); Assert.AreEqual(2, lvd.EndLocation.Line); Assert.AreEqual(20, lvd.EndLocation.Column); - }*/ + } + + [Test, Ignore("Nested arrays are broken in the parser")] + public void NestedArray() + { + VariableDeclarationStatement lvd = ParseUtilCSharp.ParseStatement("DateTime[,][] a;"); + Assert.IsTrue(new VariableDeclarationStatement(new SimpleType("DateTime").MakeArrayType(1).MakeArrayType(2), "a").IsMatch(lvd)); + } + + [Test, Ignore("Nested pointers are broken in the parser")] + public void NestedPointers() + { + VariableDeclarationStatement lvd = ParseUtilCSharp.ParseStatement("DateTime*** a;"); + Assert.IsTrue(new VariableDeclarationStatement(new SimpleType("DateTime").MakePointerType().MakePointerType().MakePointerType(), "a").IsMatch(lvd)); + } + + [Test, Ignore("The parser creates nested ComposedTypes while MakeArrayType() adds the specifier to the existing ComposedType")] + public void ArrayOfPointers() + { + VariableDeclarationStatement lvd = ParseUtilCSharp.ParseStatement("DateTime*[] a;"); + Assert.IsTrue(new VariableDeclarationStatement(new SimpleType("DateTime").MakePointerType().MakeArrayType(), "a").IsMatch(lvd)); + } + + [Test, Ignore("The parser creates nested ComposedTypes while MakeArrayType() adds the specifier to the existing ComposedType")] + public void ArrayOfNullables() + { + VariableDeclarationStatement lvd = ParseUtilCSharp.ParseStatement("DateTime?[] a;"); + Assert.IsTrue(new VariableDeclarationStatement(new SimpleType("DateTime").MakeNullableType().MakeArrayType(), "a").IsMatch(lvd)); + } } } diff --git a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/LambdaTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/LambdaTests.cs index f98155d961..9df45f3d92 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/LambdaTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/LambdaTests.cs @@ -274,5 +274,19 @@ class TestClass { var lrr = Resolve(program); Assert.AreEqual("System.Int32", lrr.Type.ReflectionName); } + + /* TODO write test for this +class A +{ + static void Foo(string x, Action y) { Console.WriteLine(1); } + static void Foo(object x, Func, int> y) { Console.WriteLine(2); } + + static void Main() + { + Foo(null, x => x()); // Prints 1 + Foo(null, x => (x())); // Prints 2 + } +} + */ } } diff --git a/ICSharpCode.NRefactory/CSharp/Ast/AstType.cs b/ICSharpCode.NRefactory/CSharp/Ast/AstType.cs index aa5d2484c9..4c6c0f0b00 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/AstType.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/AstType.cs @@ -71,16 +71,38 @@ namespace ICSharpCode.NRefactory.CSharp get { return NodeType.TypeReference; } } + public new AstType Clone() + { + return (AstType)base.Clone(); + } + + /// + /// Creates a pointer type from this type by nesting it in a . + /// If this type already is a pointer type, this method just increases the PointerRank of the existing pointer type. + /// public virtual AstType MakePointerType() { return new ComposedType { BaseType = this }.MakePointerType(); } + /// + /// Creates an array type from this type by nesting it in a . + /// If this type already is an array type, the additional rank is prepended to the existing array specifier list. + /// Thus, new SimpleType("T").MakeArrayType(1).MakeArrayType(2) will result in "T[,][]". + /// public virtual AstType MakeArrayType(int rank = 1) { return new ComposedType { BaseType = this }.MakeArrayType(rank); } + /// + /// Creates a nullable type from this type by nesting it in a . + /// + public AstType MakeNullableType() + { + return new ComposedType { BaseType = this, HasNullableSpecifier = true }; + } + /// /// Builds an expression that can be used to access a static member on this type. ///