PageRenderTime 36ms CodeModel.GetById 14ms app.highlight 17ms RepoModel.GetById 1ms app.codeStats 0ms

/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/TypeDeclarationTests.cs

http://github.com/icsharpcode/ILSpy
C# | 369 lines | 320 code | 32 blank | 17 comment | 0 complexity | 01c6b9983f3a9b583982dd99bf61bb25 MD5 | raw file
  1// Copyright (c) AlphaSierraPapa for the SharpDevelop Team
  2// 
  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:
  8// 
  9// The above copyright notice and this permission notice shall be included in all copies or
 10// substantial portions of the Software.
 11// 
 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.
 18
 19using System;
 20using System.Linq;
 21using ICSharpCode.NRefactory.TypeSystem;
 22using NUnit.Framework;
 23
 24namespace ICSharpCode.NRefactory.CSharp.Parser.GeneralScope
 25{
 26	[TestFixture]
 27	public class TypeDeclarationTests
 28	{
 29		[Test]
 30		public void SimpleClassTypeDeclarationTest()
 31		{
 32			TypeDeclaration td = ParseUtilCSharp.ParseGlobal<TypeDeclaration>("class MyClass  : My.Base.Class  { }");
 33			
 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);
 38		}
 39		
 40		[Test]
 41		public void SimpleClassRegionTest()
 42		{
 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.GetChildByRole(Roles.LBrace).PrevSibling.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");
 52		}
 53		
 54		[Test]
 55		public void SimplePartialClassTypeDeclarationTest()
 56		{
 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);
 62		}
 63		
 64		[Test]
 65		public void NestedClassesTest()
 66		{
 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);
 75		}
 76		
 77		[Test]
 78		public void SimpleStaticClassTypeDeclarationTest()
 79		{
 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);
 85		}
 86		
 87		[Test]
 88		public void GenericClassTypeDeclarationTest()
 89		{
 90			ParseUtilCSharp.AssertGlobal(
 91				"public class G<T> {}",
 92				new TypeDeclaration {
 93					ClassType = ClassType.Class,
 94					Modifiers = Modifiers.Public,
 95					Name = "G",
 96					TypeParameters = { new TypeParameterDeclaration { Name = "T" } }
 97				});
 98		}
 99		
100		[Test]
101		public void GenericClassWithWhere()
102		{
103			ParseUtilCSharp.AssertGlobal(
104				@"public class Test<T> where T : IMyInterface { }",
105				new TypeDeclaration {
106					ClassType = ClassType.Class,
107					Modifiers = Modifiers.Public,
108					Name = "Test",
109					TypeParameters = { new TypeParameterDeclaration { Name = "T" } },
110					Constraints = {
111						new Constraint {
112							TypeParameter = new SimpleType ("T"),
113							BaseTypes = { new SimpleType("IMyInterface") }
114						}
115					}});
116		}
117		
118		[Test]
119		public void ComplexGenericInterfaceTypeDeclarationTest()
120		{
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,
126					Name = "Generic",
127					TypeParameters = {
128						new TypeParameterDeclaration { Variance = VarianceModifier.Contravariant, Name = "T" },
129						new TypeParameterDeclaration { Variance = VarianceModifier.Covariant, Name = "S" }
130					},
131					BaseTypes = {
132						new MemberType {
133							Target = new SimpleType("System"),
134							MemberName = "IComparable"
135						}
136					},
137					Constraints = {
138						new Constraint {
139							TypeParameter = new SimpleType ("S"),
140							BaseTypes = {
141								new SimpleType {
142									Identifier = "G",
143									TypeArguments = { new SimpleType("T").MakeArrayType() }
144								},
145								new PrimitiveType("new")
146							}
147						},
148						new Constraint {
149							TypeParameter = new SimpleType ("T"),
150							BaseTypes = {
151								new MemberType {
152									Target = new SimpleType("MyNamespace"),
153									MemberName = "IMyInterface"
154								}
155							}
156						}
157					}
158				});
159		}
160		
161		[Test]
162		public void ComplexClassTypeDeclarationTest()
163		{
164			ParseUtilCSharp.AssertGlobal(
165				@"
166[MyAttr()]
167public abstract class MyClass : MyBase, Interface1, My.Test.Interface2
168{
169}",
170				new TypeDeclaration {
171					ClassType = ClassType.Class,
172					Attributes = {
173						new AttributeSection {
174							Attributes = {
175								new Attribute { Type = new SimpleType("MyAttr") }
176							}
177						}
178					},
179					Modifiers = Modifiers.Public | Modifiers.Abstract,
180					Name = "MyClass",
181					BaseTypes = {
182						new SimpleType("MyBase"),
183						new SimpleType("Interface1"),
184						new MemberType {
185							Target = new MemberType {
186								Target = new SimpleType("My"),
187								MemberName = "Test"
188							},
189							MemberName = "Interface2"
190						}
191					}});
192		}
193		
194		[Test]
195		public void SimpleStructTypeDeclarationTest()
196		{
197			TypeDeclaration td = ParseUtilCSharp.ParseGlobal<TypeDeclaration>("struct MyStruct {}");
198			
199			Assert.AreEqual(ClassType.Struct, td.ClassType);
200			Assert.AreEqual("MyStruct", td.Name);
201		}
202		
203		[Test]
204		public void SimpleInterfaceTypeDeclarationTest()
205		{
206			TypeDeclaration td = ParseUtilCSharp.ParseGlobal<TypeDeclaration>("interface MyInterface {}");
207			
208			Assert.AreEqual(ClassType.Interface, td.ClassType);
209			Assert.AreEqual("MyInterface", td.Name);
210		}
211		
212		[Test]
213		public void SimpleEnumTypeDeclarationTest()
214		{
215			TypeDeclaration td = ParseUtilCSharp.ParseGlobal<TypeDeclaration>("enum MyEnum {}");
216			
217			Assert.AreEqual(ClassType.Enum, td.ClassType);
218			Assert.AreEqual("MyEnum", td.Name);
219		}
220		
221		[Test, Ignore("Mono parser bug?")]
222		public void ContextSensitiveKeywordTest()
223		{
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,
229					Name = "partial",
230					TypeParameters = {
231						new TypeParameterDeclaration {
232							Attributes = {
233								new AttributeSection {
234									AttributeTarget = "partial",
235									Attributes = { new Attribute { Type = new SimpleType("where") } }
236								}
237							},
238							Name = "where"
239						}
240					},
241					Constraints = {
242						new Constraint {
243							TypeParameter = new SimpleType ("where"),
244							BaseTypes = {
245								new SimpleType {
246									Identifier = "partial",
247									TypeArguments = { new SimpleType("where") }
248								}
249							}
250						}
251					}});
252		}
253		
254		[Test]
255		public void TypeInNamespaceTest()
256		{
257			NamespaceDeclaration ns = ParseUtilCSharp.ParseGlobal<NamespaceDeclaration>("namespace N { class MyClass { } }");
258			
259			Assert.AreEqual("N", ns.Name);
260			Assert.AreEqual("MyClass", ((TypeDeclaration)ns.Members.Single()).Name);
261		}
262		
263		[Test]
264		public void StructInNamespaceTest()
265		{
266			NamespaceDeclaration ns = ParseUtilCSharp.ParseGlobal<NamespaceDeclaration>("namespace N { struct MyClass { } }");
267			
268			Assert.AreEqual("N", ns.Name);
269			Assert.AreEqual("MyClass", ((TypeDeclaration)ns.Members.Single()).Name);
270		}
271		
272		[Test]
273		public void EnumInNamespaceTest()
274		{
275			NamespaceDeclaration ns = ParseUtilCSharp.ParseGlobal<NamespaceDeclaration>("namespace N { enum MyClass { } }");
276			
277			Assert.AreEqual("N", ns.Name);
278			Assert.AreEqual("MyClass", ((TypeDeclaration)ns.Members.Single()).Name);
279		}
280		
281		[Test]
282		public void InterfaceInNamespaceTest()
283		{
284			NamespaceDeclaration ns = ParseUtilCSharp.ParseGlobal<NamespaceDeclaration>("namespace N { interface MyClass { } }");
285			
286			Assert.AreEqual("N", ns.Name);
287			Assert.AreEqual("MyClass", ((TypeDeclaration)ns.Members.Single()).Name);
288		}
289		
290		[Test]
291		public void EnumWithInitializer()
292		{
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);
297		}
298		
299		[Test]
300		public void EnumWithBaseType()
301		{
302			TypeDeclaration td = ParseUtilCSharp.ParseGlobal<TypeDeclaration>("enum MyEnum : short { }");
303			Assert.AreEqual("MyEnum", td.Name);
304			Assert.AreEqual("short", ((PrimitiveType)td.BaseTypes.Single()).Keyword);
305		}
306		
307		[Test, Ignore("Mono parser crash")]
308		public void EnumWithIncorrectNewlineAfterIntegerLiteral ()
309		{
310			ParseUtilCSharp.AssertGlobal (
311				"enum DisplayFlags { D = 4\r\r\n}",
312				new TypeDeclaration {
313					ClassType = ClassType.Enum,
314					Name = "DisplayFlags",
315					Members = {
316						new EnumMemberDeclaration {
317							Name = "D",
318							Initializer = new PrimitiveExpression(4)
319						}
320					}});
321		}
322		
323		[Test]
324		public void EnumWithCommaAtEnd()
325		{
326			TypeDeclaration td = ParseUtilCSharp.ParseGlobal<TypeDeclaration>("enum MyEnum { A, }");
327			Assert.AreEqual(
328				new Role[] {
329					Roles.EnumKeyword,
330					Roles.Identifier,
331					Roles.LBrace,
332					Roles.TypeMemberRole,
333					Roles.Comma,
334					Roles.RBrace
335				}, td.Children.Select(c => c.Role).ToArray());
336		}
337		
338		[Test]
339		public void EnumWithCommaAndSemicolonAtEnd()
340		{
341			TypeDeclaration td = ParseUtilCSharp.ParseGlobal<TypeDeclaration>("enum MyEnum { A, };");
342			Assert.AreEqual(
343				new Role[] {
344					Roles.EnumKeyword,
345					Roles.Identifier,
346					Roles.LBrace,
347					Roles.TypeMemberRole,
348					Roles.Comma,
349					Roles.RBrace,
350					Roles.Semicolon
351				}, td.Children.Select(c => c.Role).ToArray());
352		}
353		
354		[Test, Ignore("Parser bug (incorrectly creates a comma at the end of the enum)")]
355		public void EnumWithSemicolonAtEnd()
356		{
357			TypeDeclaration td = ParseUtilCSharp.ParseGlobal<TypeDeclaration>("enum MyEnum { A };");
358			Assert.AreEqual(
359				new Role[] {
360					Roles.EnumKeyword,
361					Roles.Identifier,
362					Roles.LBrace,
363					Roles.TypeMemberRole,
364					Roles.RBrace,
365					Roles.Semicolon
366				}, td.Children.Select(c => c.Role).ToArray());
367		}
368	}
369}