1
// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team
3
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
4
// software and associated documentation files (the "Software"), to deal in the Software
5
// without restriction, including without limitation the rights to use, copy, modify, merge,
6
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
7
// to whom the Software is furnished to do so, subject to the following conditions:
9
// The above copyright notice and this permission notice shall be included in all copies or
10
// substantial portions of the Software.
12
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
13
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
15
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
16
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
17
// DEALINGS IN THE SOFTWARE.
21
using ICSharpCode.NRefactory.TypeSystem;
22
using NUnit.Framework;
24
namespace ICSharpCode.NRefactory.CSharp.Parser.GeneralScope
27
public class TypeDeclarationTests
30
public void SimpleClassTypeDeclarationTest()
32
TypeDeclaration td = ParseUtilCSharp.ParseGlobal<TypeDeclaration>("class MyClass : My.Base.Class { }");
34
Assert.AreEqual(ClassType.Class, td.ClassType);
35
Assert.AreEqual("MyClass", td.Name);
36
Assert.AreEqual("My.Base.Class", td.BaseTypes.First ().ToString ());
37
Assert.AreEqual(Modifiers.None, td.Modifiers);
41
public void SimpleClassRegionTest()
43
const string program = "class MyClass\n{\n}\n";
44
TypeDeclaration td = ParseUtilCSharp.ParseGlobal<TypeDeclaration>(program);
45
Assert.AreEqual(1, td.StartLocation.Line, "StartLocation.Y");
46
Assert.AreEqual(1, td.StartLocation.Column, "StartLocation.X");
47
TextLocation bodyStartLocation = td.NameToken.EndLocation;
48
Assert.AreEqual(1, bodyStartLocation.Line, "BodyStartLocation.Y");
49
Assert.AreEqual(14, bodyStartLocation.Column, "BodyStartLocation.X");
50
Assert.AreEqual(3, td.EndLocation.Line, "EndLocation.Y");
51
Assert.AreEqual(2, td.EndLocation.Column, "EndLocation.Y");
55
public void SimplePartialClassTypeDeclarationTest()
57
TypeDeclaration td = ParseUtilCSharp.ParseGlobal<TypeDeclaration>("partial class MyClass { }");
58
Assert.IsFalse(td.IsNull);
59
Assert.AreEqual(ClassType.Class, td.ClassType);
60
Assert.AreEqual("MyClass", td.Name);
61
Assert.AreEqual(Modifiers.Partial, td.Modifiers);
65
public void NestedClassesTest()
67
TypeDeclaration td = ParseUtilCSharp.ParseGlobal<TypeDeclaration>("class MyClass { partial class P1 {} public partial class P2 {} static class P3 {} internal static class P4 {} }");
68
Assert.IsFalse(td.IsNull);
69
Assert.AreEqual(ClassType.Class, td.ClassType);
70
Assert.AreEqual("MyClass", td.Name);
71
Assert.AreEqual(Modifiers.Partial, ((TypeDeclaration)td.Members.ElementAt(0)).Modifiers);
72
Assert.AreEqual(Modifiers.Partial | Modifiers.Public, ((TypeDeclaration)td.Members.ElementAt(1)).Modifiers);
73
Assert.AreEqual(Modifiers.Static, ((TypeDeclaration)td.Members.ElementAt(2)).Modifiers);
74
Assert.AreEqual(Modifiers.Static | Modifiers.Internal, ((TypeDeclaration)td.Members.ElementAt(3)).Modifiers);
78
public void SimpleStaticClassTypeDeclarationTest()
80
TypeDeclaration td = ParseUtilCSharp.ParseGlobal<TypeDeclaration>("static class MyClass { }");
81
Assert.IsFalse(td.IsNull);
82
Assert.AreEqual(ClassType.Class, td.ClassType);
83
Assert.AreEqual("MyClass", td.Name);
84
Assert.AreEqual(Modifiers.Static, td.Modifiers);
88
public void GenericClassTypeDeclarationTest()
90
ParseUtilCSharp.AssertGlobal(
91
"public class G<T> {}",
93
ClassType = ClassType.Class,
94
Modifiers = Modifiers.Public,
96
TypeParameters = { new TypeParameterDeclaration { Name = "T" } }
101
public void GenericClassWithWhere()
103
ParseUtilCSharp.AssertGlobal(
104
@"public class Test<T> where T : IMyInterface { }",
105
new TypeDeclaration {
106
ClassType = ClassType.Class,
107
Modifiers = Modifiers.Public,
109
TypeParameters = { new TypeParameterDeclaration { Name = "T" } },
112
TypeParameter = new SimpleType ("T"),
113
BaseTypes = { new SimpleType("IMyInterface") }
119
public void ComplexGenericInterfaceTypeDeclarationTest()
121
ParseUtilCSharp.AssertGlobal(
122
"public interface Generic<in T, out S> : System.IComparable where S : G<T[]>, new() where T : MyNamespace.IMyInterface {}",
123
new TypeDeclaration {
124
ClassType = ClassType.Interface,
125
Modifiers = Modifiers.Public,
128
new TypeParameterDeclaration { Variance = VarianceModifier.Contravariant, Name = "T" },
129
new TypeParameterDeclaration { Variance = VarianceModifier.Covariant, Name = "S" }
133
Target = new SimpleType("System"),
134
MemberName = "IComparable"
139
TypeParameter = new SimpleType ("S"),
143
TypeArguments = { new SimpleType("T").MakeArrayType() }
145
new PrimitiveType("new")
149
TypeParameter = new SimpleType ("T"),
152
Target = new SimpleType("MyNamespace"),
153
MemberName = "IMyInterface"
162
public void ComplexClassTypeDeclarationTest()
164
ParseUtilCSharp.AssertGlobal(
167
public abstract class MyClass : MyBase, Interface1, My.Test.Interface2
170
new TypeDeclaration {
171
ClassType = ClassType.Class,
173
new AttributeSection {
175
new Attribute { Type = new SimpleType("MyAttr") }
179
Modifiers = Modifiers.Public | Modifiers.Abstract,
182
new SimpleType("MyBase"),
183
new SimpleType("Interface1"),
185
Target = new MemberType {
186
Target = new SimpleType("My"),
189
MemberName = "Interface2"
195
public void SimpleStructTypeDeclarationTest()
197
TypeDeclaration td = ParseUtilCSharp.ParseGlobal<TypeDeclaration>("struct MyStruct {}");
199
Assert.AreEqual(ClassType.Struct, td.ClassType);
200
Assert.AreEqual("MyStruct", td.Name);
204
public void SimpleInterfaceTypeDeclarationTest()
206
TypeDeclaration td = ParseUtilCSharp.ParseGlobal<TypeDeclaration>("interface MyInterface {}");
208
Assert.AreEqual(ClassType.Interface, td.ClassType);
209
Assert.AreEqual("MyInterface", td.Name);
213
public void SimpleEnumTypeDeclarationTest()
215
TypeDeclaration td = ParseUtilCSharp.ParseGlobal<TypeDeclaration>("enum MyEnum {}");
217
Assert.AreEqual(ClassType.Enum, td.ClassType);
218
Assert.AreEqual("MyEnum", td.Name);
221
[Test, Ignore("Mono parser bug?")]
222
public void ContextSensitiveKeywordTest()
224
ParseUtilCSharp.AssertGlobal(
225
"partial class partial<[partial: where] where> where where : partial<where> { }",
226
new TypeDeclaration {
227
ClassType = ClassType.Class,
228
Modifiers = Modifiers.Partial,
231
new TypeParameterDeclaration {
233
new AttributeSection {
234
AttributeTarget = "partial",
235
Attributes = { new Attribute { Type = new SimpleType("where") } }
243
TypeParameter = new SimpleType ("where"),
246
Identifier = "partial",
247
TypeArguments = { new SimpleType("where") }
255
public void TypeInNamespaceTest()
257
NamespaceDeclaration ns = ParseUtilCSharp.ParseGlobal<NamespaceDeclaration>("namespace N { class MyClass { } }");
259
Assert.AreEqual("N", ns.Name);
260
Assert.AreEqual("MyClass", ((TypeDeclaration)ns.Members.Single()).Name);
264
public void StructInNamespaceTest()
266
NamespaceDeclaration ns = ParseUtilCSharp.ParseGlobal<NamespaceDeclaration>("namespace N { struct MyClass { } }");
268
Assert.AreEqual("N", ns.Name);
269
Assert.AreEqual("MyClass", ((TypeDeclaration)ns.Members.Single()).Name);
273
public void EnumInNamespaceTest()
275
NamespaceDeclaration ns = ParseUtilCSharp.ParseGlobal<NamespaceDeclaration>("namespace N { enum MyClass { } }");
277
Assert.AreEqual("N", ns.Name);
278
Assert.AreEqual("MyClass", ((TypeDeclaration)ns.Members.Single()).Name);
282
public void InterfaceInNamespaceTest()
284
NamespaceDeclaration ns = ParseUtilCSharp.ParseGlobal<NamespaceDeclaration>("namespace N { interface MyClass { } }");
286
Assert.AreEqual("N", ns.Name);
287
Assert.AreEqual("MyClass", ((TypeDeclaration)ns.Members.Single()).Name);
291
public void EnumWithInitializer()
293
TypeDeclaration td = ParseUtilCSharp.ParseGlobal<TypeDeclaration>("enum MyEnum { Val1 = 10 }");
294
EnumMemberDeclaration member = (EnumMemberDeclaration)td.Members.Single();
295
Assert.AreEqual("Val1", member.Name);
296
Assert.AreEqual(10, ((PrimitiveExpression)member.Initializer).Value);
300
public void EnumWithBaseType()
302
TypeDeclaration td = ParseUtilCSharp.ParseGlobal<TypeDeclaration>("enum MyEnum : short { }");
303
Assert.AreEqual("MyEnum", td.Name);
304
Assert.AreEqual("short", ((PrimitiveType)td.BaseTypes.Single()).Keyword);
307
[Test, Ignore("Mono parser crash")]
308
public void EnumWithIncorrectNewlineAfterIntegerLiteral ()
310
ParseUtilCSharp.AssertGlobal (
311
"enum DisplayFlags { D = 4\r\r\n}",
312
new TypeDeclaration {
313
ClassType = ClassType.Enum,
314
Name = "DisplayFlags",
316
new EnumMemberDeclaration {
318
Initializer = new PrimitiveExpression(4)
324
public void EnumWithCommaAtEnd()
326
TypeDeclaration td = ParseUtilCSharp.ParseGlobal<TypeDeclaration>("enum MyEnum { A, }");
332
Roles.TypeMemberRole,
335
}, td.Children.Select(c => c.Role).ToArray());
339
public void EnumWithCommaAndSemicolonAtEnd()
341
TypeDeclaration td = ParseUtilCSharp.ParseGlobal<TypeDeclaration>("enum MyEnum { A, };");
347
Roles.TypeMemberRole,
351
}, td.Children.Select(c => c.Role).ToArray());
354
[Test, Ignore("Parser bug (incorrectly creates a comma at the end of the enum)")]
355
public void EnumWithSemicolonAtEnd()
357
TypeDeclaration td = ParseUtilCSharp.ParseGlobal<TypeDeclaration>("enum MyEnum { A };");
363
Roles.TypeMemberRole,
366
}, td.Children.Select(c => c.Role).ToArray());