PageRenderTime 73ms CodeModel.GetById 26ms app.highlight 41ms RepoModel.GetById 2ms app.codeStats 0ms

/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeMembers/MethodDeclarationTests.cs

http://github.com/icsharpcode/ILSpy
C# | 428 lines | 383 code | 28 blank | 17 comment | 0 complexity | 2a7fe87b4e1df3b653487f934c1e423d 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.TypeMembers
 25{
 26	[TestFixture]
 27	public class MethodDeclarationTests
 28	{
 29		[Test]
 30		public void SimpleMethodDeclarationTest()
 31		{
 32			MethodDeclaration md = ParseUtilCSharp.ParseTypeMember<MethodDeclaration>("void MyMethod() {} ");
 33			Assert.AreEqual("void", ((PrimitiveType)md.ReturnType).Keyword);
 34			Assert.AreEqual(0, md.Parameters.Count());
 35			Assert.IsFalse(md.IsExtensionMethod);
 36		}
 37		
 38		[Test]
 39		public void AbstractMethodDeclarationTest()
 40		{
 41			MethodDeclaration md = ParseUtilCSharp.ParseTypeMember<MethodDeclaration>("abstract void MyMethod();");
 42			Assert.AreEqual("void", ((PrimitiveType)md.ReturnType).Keyword);
 43			Assert.AreEqual(0, md.Parameters.Count());
 44			Assert.IsFalse(md.IsExtensionMethod);
 45			Assert.IsTrue(md.Body.IsNull);
 46			Assert.AreEqual(Modifiers.Abstract, md.Modifiers);
 47		}
 48		
 49		[Test]
 50		public void DefiningPartialMethodDeclarationTest()
 51		{
 52			MethodDeclaration md = ParseUtilCSharp.ParseTypeMember<MethodDeclaration>("partial void MyMethod();");
 53			Assert.AreEqual("void", ((PrimitiveType)md.ReturnType).Keyword);
 54			Assert.AreEqual(0, md.Parameters.Count());
 55			Assert.IsFalse(md.IsExtensionMethod);
 56			Assert.IsTrue(md.Body.IsNull);
 57			Assert.AreEqual(Modifiers.Partial, md.Modifiers);
 58		}
 59		
 60		[Test]
 61		public void ImplementingPartialMethodDeclarationTest()
 62		{
 63			MethodDeclaration md = ParseUtilCSharp.ParseTypeMember<MethodDeclaration>("partial void MyMethod() { }");
 64			Assert.AreEqual("void", ((PrimitiveType)md.ReturnType).Keyword);
 65			Assert.AreEqual(0, md.Parameters.Count());
 66			Assert.IsFalse(md.IsExtensionMethod);
 67			Assert.IsFalse(md.Body.IsNull);
 68			Assert.AreEqual(Modifiers.Partial, md.Modifiers);
 69		}
 70		
 71		[Test]
 72		public void SimpleMethodRegionTest()
 73		{
 74			const string program = @"
 75		void MyMethod()
 76		{
 77			OtherMethod();
 78		}
 79";
 80			MethodDeclaration md = ParseUtilCSharp.ParseTypeMember<MethodDeclaration>(program);
 81			Assert.AreEqual(2, md.StartLocation.Line, "StartLocation.Y");
 82			Assert.AreEqual(5, md.EndLocation.Line, "EndLocation.Y");
 83			Assert.AreEqual(3, md.StartLocation.Column, "StartLocation.X");
 84			Assert.AreEqual(4, md.EndLocation.Column, "EndLocation.X");
 85		}
 86		
 87		[Test]
 88		public void MethodWithModifiersRegionTest()
 89		{
 90			const string program = @"
 91		public static void MyMethod()
 92		{
 93			OtherMethod();
 94		}
 95";
 96			MethodDeclaration md = ParseUtilCSharp.ParseTypeMember<MethodDeclaration>(program);
 97			Assert.AreEqual(2, md.StartLocation.Line, "StartLocation.Y");
 98			Assert.AreEqual(5, md.EndLocation.Line, "EndLocation.Y");
 99			Assert.AreEqual(3, md.StartLocation.Column, "StartLocation.X");
100			Assert.AreEqual(4, md.EndLocation.Column, "EndLocation.X");
101		}
102		
103		[Test]
104		public void MethodWithUnnamedParameterDeclarationTest()
105		{
106			MethodDeclaration md = ParseUtilCSharp.ParseTypeMember<MethodDeclaration>("void MyMethod(int) {} ", true);
107			Assert.AreEqual("void", md.ReturnType.ToString ());
108			Assert.AreEqual(1, md.Parameters.Count());
109			Assert.AreEqual("int", ((PrimitiveType)md.Parameters.Single().Type).Keyword);
110		}
111		
112		[Test]
113		public void GenericVoidMethodDeclarationTest()
114		{
115			ParseUtilCSharp.AssertTypeMember(
116				"void MyMethod<T>(T a) {} ",
117				new MethodDeclaration {
118					ReturnType = new PrimitiveType("void"),
119					Name = "MyMethod",
120					TypeParameters = { new TypeParameterDeclaration { Name = "T" } },
121					Parameters = { new ParameterDeclaration(new SimpleType("T"), "a") },
122					Body = new BlockStatement()
123				});
124		}
125		
126		[Test]
127		public void GenericMethodDeclarationTest()
128		{
129			ParseUtilCSharp.AssertTypeMember(
130				"T MyMethod<T>(T a) {} ",
131				new MethodDeclaration {
132					ReturnType = new SimpleType("T"),
133					Name = "MyMethod",
134					TypeParameters = { new TypeParameterDeclaration { Name = "T" } },
135					Parameters = { new ParameterDeclaration(new SimpleType("T"), "a") },
136					Body = new BlockStatement()
137				});
138		}
139		
140		[Test]
141		public void GenericMethodDeclarationWithConstraintTest()
142		{
143			ParseUtilCSharp.AssertTypeMember(
144				"T MyMethod<T>(T a) where T : ISomeInterface {} ",
145				new MethodDeclaration {
146					ReturnType = new SimpleType("T"),
147					Name = "MyMethod",
148					TypeParameters = { new TypeParameterDeclaration { Name = "T" } },
149					Parameters = { new ParameterDeclaration(new SimpleType("T"), "a") },
150					Constraints = {
151						new Constraint {
152							TypeParameter = new SimpleType ("T"),
153							BaseTypes = { new SimpleType("ISomeInterface") }
154						}
155					},
156					Body = new BlockStatement()
157				});
158		}
159		
160		[Test]
161		public void GenericMethodInInterface()
162		{
163			ParseUtilCSharp.AssertGlobal(
164				@"interface MyInterface {
165	T MyMethod<T>(T a) where T : ISomeInterface;
166}
167",
168				new TypeDeclaration {
169					ClassType = ClassType.Interface,
170					Name = "MyInterface",
171					Members = {
172						new MethodDeclaration {
173							ReturnType = new SimpleType("T"),
174							Name = "MyMethod",
175							TypeParameters = { new TypeParameterDeclaration { Name = "T" } },
176							Parameters = { new ParameterDeclaration(new SimpleType("T"), "a") },
177							Constraints = {
178								new Constraint {
179									TypeParameter = new SimpleType ("T"),
180									BaseTypes = { new SimpleType("ISomeInterface") }
181								}
182							}
183						}}});
184		}
185		
186		[Test]
187		public void GenericVoidMethodInInterface()
188		{
189			ParseUtilCSharp.AssertGlobal(
190				@"interface MyInterface {
191	void MyMethod<T>(T a) where T : ISomeInterface;
192}
193",
194				new TypeDeclaration {
195					ClassType = ClassType.Interface,
196					Name = "MyInterface",
197					Members = {
198						new MethodDeclaration {
199							ReturnType = new PrimitiveType("void"),
200							Name = "MyMethod",
201							TypeParameters = { new TypeParameterDeclaration { Name = "T" } },
202							Parameters = { new ParameterDeclaration(new SimpleType("T"), "a") },
203							Constraints = {
204								new Constraint {
205									TypeParameter = new SimpleType ("T"),
206									BaseTypes = { new SimpleType("ISomeInterface") }
207								}
208							}
209						}}});
210		}
211		
212		[Test]
213		public void ShadowingMethodInInterface ()
214		{
215			ParseUtilCSharp.AssertGlobal (
216				@"interface MyInterface : IDisposable {
217	new void Dispose();
218}
219",
220				new TypeDeclaration {
221					ClassType = ClassType.Interface,
222					Name = "MyInterface",
223					BaseTypes = { new SimpleType("IDisposable") },
224					Members = {
225						new MethodDeclaration {
226							Modifiers = Modifiers.New,
227							ReturnType = new PrimitiveType("void"),
228							Name = "Dispose"
229						}}});
230		}
231		
232		[Test]
233		public void MethodImplementingInterfaceTest()
234		{
235			ParseUtilCSharp.AssertTypeMember(
236				"int MyInterface.MyMethod() {} ",
237				new MethodDeclaration {
238					ReturnType = new PrimitiveType("int"),
239					PrivateImplementationType = new SimpleType("MyInterface"),
240					Name = "MyMethod",
241					Body = new BlockStatement()
242				});
243		}
244		
245		[Test]
246		public void MethodImplementingGenericInterfaceTest()
247		{
248			ParseUtilCSharp.AssertTypeMember(
249				"int MyInterface<string>.MyMethod() {} ",
250				new MethodDeclaration {
251					ReturnType = new PrimitiveType("int"),
252					PrivateImplementationType = new SimpleType("MyInterface") { TypeArguments = { new PrimitiveType("string") } },
253					Name = "MyMethod",
254					Body = new BlockStatement()
255				});
256		}
257		
258		[Test]
259		public void VoidMethodImplementingInterfaceTest()
260		{
261			ParseUtilCSharp.AssertTypeMember (
262				"void MyInterface.MyMethod() {} ",
263				new MethodDeclaration {
264					ReturnType = new PrimitiveType("void"),
265					PrivateImplementationType = new SimpleType("MyInterface"),
266					Name = "MyMethod",
267					Body = new BlockStatement()
268				});
269		}
270		
271		[Test]
272		public void VoidMethodImplementingGenericInterfaceTest()
273		{
274			ParseUtilCSharp.AssertTypeMember (
275				"void MyInterface<string>.MyMethod() {} ",
276				new MethodDeclaration {
277					ReturnType = new PrimitiveType("void"),
278					PrivateImplementationType = new SimpleType("MyInterface") { TypeArguments = { new PrimitiveType("string") } },
279					Name = "MyMethod",
280					Body = new BlockStatement()
281				});
282		}
283		
284		[Test, Ignore("Parser bug: constraints added in wrong order")]
285		public void GenericMethodWithMultipleConstraints()
286		{
287			ParseUtilCSharp.AssertTypeMember(
288				"void MyMethod<A, B>() where A : IA where B : IB {} ",
289				new MethodDeclaration {
290					ReturnType = new PrimitiveType("void"),
291					Name = "MyMethod",
292					TypeParameters = {
293						new TypeParameterDeclaration { Name = "A" },
294						new TypeParameterDeclaration { Name = "B" }
295					},
296					Constraints = {
297						new Constraint {
298							TypeParameter = new SimpleType("A"),
299							BaseTypes = { new SimpleType("IA") }
300						},
301						new Constraint {
302							TypeParameter = new SimpleType("B"),
303							BaseTypes = { new SimpleType("IB") }
304						}
305					}});
306		}
307		
308		[Test]
309		public void IncompleteConstraintsTest()
310		{
311			MethodDeclaration md = ParseUtilCSharp.ParseTypeMember<MethodDeclaration>(
312				"void a<T>() where T { }", true // expect errors
313			);
314			Assert.AreEqual("a", md.Name);
315			Assert.AreEqual(1, md.TypeParameters.Count);
316			Assert.AreEqual("T", md.TypeParameters.Single().Name);
317			Assert.AreEqual(1, md.Constraints.Count());
318			Assert.AreEqual(0, md.Constraints.First ().BaseTypes.Count());
319			
320		}
321		
322		[Test]
323		public void ExtensionMethodTest()
324		{
325			MethodDeclaration md = ParseUtilCSharp.ParseTypeMember<MethodDeclaration>(
326				"public static int ToInt32(this string s) { return int.Parse(s); }"
327			);
328			Assert.AreEqual("ToInt32", md.Name);
329			Assert.AreEqual("s", md.Parameters.First().Name);
330			Assert.AreEqual(ParameterModifier.This, md.Parameters.First().ParameterModifier);
331			Assert.AreEqual("string", ((PrimitiveType)md.Parameters.First().Type).Keyword);
332			Assert.IsTrue(md.IsExtensionMethod);
333		}
334		
335		[Test]
336		public void ExtensionMethodWithAttributeTest()
337		{
338			MethodDeclaration md = ParseUtilCSharp.ParseTypeMember<MethodDeclaration>(
339				"public static int ToInt32([Attr] this string s) { return int.Parse(s); }"
340			);
341			Assert.AreEqual("ToInt32", md.Name);
342			Assert.IsTrue(md.IsExtensionMethod);
343			Assert.AreEqual("s", md.Parameters.Single().Name);
344			Assert.AreEqual(KnownTypeCode.String, ((PrimitiveType)md.Parameters.Single().Type).KnownTypeCode);
345			Assert.AreEqual(1, md.Parameters.Single().Attributes.Count);
346		}
347		
348		[Test]
349		public void VoidExtensionMethodTest()
350		{
351			MethodDeclaration md = ParseUtilCSharp.ParseTypeMember<MethodDeclaration>(
352				"public static void Print(this string s) { Console.WriteLine(s); }"
353			);
354			Assert.AreEqual("Print", md.Name);
355			Assert.AreEqual("s", md.Parameters.First().Name);
356			Assert.AreEqual(ParameterModifier.This, md.Parameters.First().ParameterModifier);
357			Assert.AreEqual("string", ((PrimitiveType)md.Parameters.First().Type).Keyword);
358			Assert.IsTrue(md.IsExtensionMethod);
359		}
360		
361		[Test]
362		public void MethodWithEmptyAssignmentErrorInBody()
363		{
364			MethodDeclaration md = ParseUtilCSharp.ParseTypeMember<MethodDeclaration>(
365				"void A ()\n" +
366				"{\n" +
367				"int a = 3;\n" +
368				" = 4;\n" +
369				"}", true // expect errors
370			);
371			Assert.AreEqual("A", md.Name);
372			Assert.AreEqual(new TextLocation(2, 1), md.Body.StartLocation);
373			Assert.AreEqual(new TextLocation(5, 2), md.Body.EndLocation);
374		}
375		
376		[Test]
377		public void OptionalParameterTest()
378		{
379			ParseUtilCSharp.AssertTypeMember(
380				"public void Foo(string bar = null, int baz = 0) { }",
381				new MethodDeclaration {
382					Modifiers = Modifiers.Public,
383					ReturnType = new PrimitiveType("void"),
384					Name = "Foo",
385					Body = new BlockStatement(),
386					Parameters = {
387						new ParameterDeclaration {
388							Type = new PrimitiveType("string"),
389							Name = "bar",
390							DefaultExpression = new NullReferenceExpression()
391						},
392						new ParameterDeclaration {
393							Type = new PrimitiveType("int"),
394							Name = "baz",
395							DefaultExpression = new PrimitiveExpression(0)
396						}
397					}});
398		}
399		
400		[Test]
401		public void AsyncMethod()
402		{
403			ParseUtilCSharp.AssertTypeMember(
404				"async void MyMethod() {}",
405				new MethodDeclaration {
406					Modifiers = Modifiers.Async,
407					ReturnType = new PrimitiveType("void"),
408					Name = "MyMethod",
409					Body = new BlockStatement()
410				});
411		}
412		
413		[Test, Ignore("parser bug, reported upstream.")]
414		public void AsyncAsyncAsync()
415		{
416			ParseUtilCSharp.AssertTypeMember(
417				"async async async(async async) {}",
418				new MethodDeclaration {
419					Modifiers = Modifiers.Async,
420					ReturnType = new SimpleType("async"),
421					Name = "async",
422					Body = new BlockStatement(),
423					Parameters = {
424						new ParameterDeclaration(new SimpleType("async"), "async")
425					}});
426		}
427	}
428}