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.TypeMembers
27
public class MethodDeclarationTests
30
public void SimpleMethodDeclarationTest()
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);
39
public void AbstractMethodDeclarationTest()
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);
50
public void DefiningPartialMethodDeclarationTest()
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);
61
public void ImplementingPartialMethodDeclarationTest()
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);
72
public void SimpleMethodRegionTest()
74
const string program = @"
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");
88
public void MethodWithModifiersRegionTest()
90
const string program = @"
91
public static void MyMethod()
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");
104
public void MethodWithUnnamedParameterDeclarationTest()
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);
113
public void GenericVoidMethodDeclarationTest()
115
ParseUtilCSharp.AssertTypeMember(
116
"void MyMethod<T>(T a) {} ",
117
new MethodDeclaration {
118
ReturnType = new PrimitiveType("void"),
120
TypeParameters = { new TypeParameterDeclaration { Name = "T" } },
121
Parameters = { new ParameterDeclaration(new SimpleType("T"), "a") },
122
Body = new BlockStatement()
127
public void GenericMethodDeclarationTest()
129
ParseUtilCSharp.AssertTypeMember(
130
"T MyMethod<T>(T a) {} ",
131
new MethodDeclaration {
132
ReturnType = new SimpleType("T"),
134
TypeParameters = { new TypeParameterDeclaration { Name = "T" } },
135
Parameters = { new ParameterDeclaration(new SimpleType("T"), "a") },
136
Body = new BlockStatement()
141
public void GenericMethodDeclarationWithConstraintTest()
143
ParseUtilCSharp.AssertTypeMember(
144
"T MyMethod<T>(T a) where T : ISomeInterface {} ",
145
new MethodDeclaration {
146
ReturnType = new SimpleType("T"),
148
TypeParameters = { new TypeParameterDeclaration { Name = "T" } },
149
Parameters = { new ParameterDeclaration(new SimpleType("T"), "a") },
152
TypeParameter = new SimpleType ("T"),
153
BaseTypes = { new SimpleType("ISomeInterface") }
156
Body = new BlockStatement()
162
public void GenericMethodWithTwoConstraints()
164
ParseUtilCSharp.AssertTypeMember(
165
"void MyMethod<A, B>() where A : IA where B : IB {} ",
166
new MethodDeclaration {
167
ReturnType = new PrimitiveType("void"),
170
new TypeParameterDeclaration { Name = "A" },
171
new TypeParameterDeclaration { Name = "B" }
175
TypeParameter = new SimpleType("A"),
176
BaseTypes = { new SimpleType("IA") }
179
TypeParameter = new SimpleType("B"),
180
BaseTypes = { new SimpleType("IB") }
183
Body = new BlockStatement()
188
public void GenericMethodDeclarationWithThreeConstraintsTest()
190
ParseUtilCSharp.AssertTypeMember(
191
"A MyMethod<A, B, C>() where B : BB where A : BA, IA where C : class {} ",
192
new MethodDeclaration {
193
ReturnType = new SimpleType("A"),
196
new TypeParameterDeclaration { Name = "A" },
197
new TypeParameterDeclaration { Name = "B" },
198
new TypeParameterDeclaration { Name = "C" }
202
TypeParameter = new SimpleType ("B"),
203
BaseTypes = { new SimpleType("BB") }
206
TypeParameter = new SimpleType ("A"),
207
BaseTypes = { new SimpleType("BA"), new SimpleType("IA") }
210
TypeParameter = new SimpleType ("C"),
211
BaseTypes = { new PrimitiveType("class") }
214
Body = new BlockStatement()
219
public void GenericMethodInInterface()
221
ParseUtilCSharp.AssertGlobal(
222
@"interface MyInterface {
223
T MyMethod<T>(T a) where T : ISomeInterface;
226
new TypeDeclaration {
227
ClassType = ClassType.Interface,
228
Name = "MyInterface",
230
new MethodDeclaration {
231
ReturnType = new SimpleType("T"),
233
TypeParameters = { new TypeParameterDeclaration { Name = "T" } },
234
Parameters = { new ParameterDeclaration(new SimpleType("T"), "a") },
237
TypeParameter = new SimpleType ("T"),
238
BaseTypes = { new SimpleType("ISomeInterface") }
245
public void GenericVoidMethodInInterface()
247
ParseUtilCSharp.AssertGlobal(
248
@"interface MyInterface {
249
void MyMethod<T>(T a) where T : ISomeInterface;
252
new TypeDeclaration {
253
ClassType = ClassType.Interface,
254
Name = "MyInterface",
256
new MethodDeclaration {
257
ReturnType = new PrimitiveType("void"),
259
TypeParameters = { new TypeParameterDeclaration { Name = "T" } },
260
Parameters = { new ParameterDeclaration(new SimpleType("T"), "a") },
263
TypeParameter = new SimpleType ("T"),
264
BaseTypes = { new SimpleType("ISomeInterface") }
271
public void ShadowingMethodInInterface ()
273
ParseUtilCSharp.AssertGlobal (
274
@"interface MyInterface : IDisposable {
278
new TypeDeclaration {
279
ClassType = ClassType.Interface,
280
Name = "MyInterface",
281
BaseTypes = { new SimpleType("IDisposable") },
283
new MethodDeclaration {
284
Modifiers = Modifiers.New,
285
ReturnType = new PrimitiveType("void"),
291
public void MethodImplementingInterfaceTest()
293
ParseUtilCSharp.AssertTypeMember(
294
"int MyInterface.MyMethod() {} ",
295
new MethodDeclaration {
296
ReturnType = new PrimitiveType("int"),
297
PrivateImplementationType = new SimpleType("MyInterface"),
299
Body = new BlockStatement()
304
public void MethodImplementingGenericInterfaceTest()
306
ParseUtilCSharp.AssertTypeMember(
307
"int MyInterface<string>.MyMethod() {} ",
308
new MethodDeclaration {
309
ReturnType = new PrimitiveType("int"),
310
PrivateImplementationType = new SimpleType("MyInterface") { TypeArguments = { new PrimitiveType("string") } },
312
Body = new BlockStatement()
317
public void VoidMethodImplementingInterfaceTest()
319
ParseUtilCSharp.AssertTypeMember (
320
"void MyInterface.MyMethod() {} ",
321
new MethodDeclaration {
322
ReturnType = new PrimitiveType("void"),
323
PrivateImplementationType = new SimpleType("MyInterface"),
325
Body = new BlockStatement()
330
public void VoidMethodImplementingGenericInterfaceTest()
332
ParseUtilCSharp.AssertTypeMember (
333
"void MyInterface<string>.MyMethod() {} ",
334
new MethodDeclaration {
335
ReturnType = new PrimitiveType("void"),
336
PrivateImplementationType = new SimpleType("MyInterface") { TypeArguments = { new PrimitiveType("string") } },
338
Body = new BlockStatement()
343
public void IncompleteConstraintsTest()
345
MethodDeclaration md = ParseUtilCSharp.ParseTypeMember<MethodDeclaration>(
346
"void a<T>() where T { }", true // expect errors
348
Assert.AreEqual("a", md.Name);
349
Assert.AreEqual(1, md.TypeParameters.Count);
350
Assert.AreEqual("T", md.TypeParameters.Single().Name);
351
Assert.AreEqual(1, md.Constraints.Count());
352
Assert.AreEqual(0, md.Constraints.First ().BaseTypes.Count());
357
public void ExtensionMethodTest()
359
MethodDeclaration md = ParseUtilCSharp.ParseTypeMember<MethodDeclaration>(
360
"public static int ToInt32(this string s) { return int.Parse(s); }"
362
Assert.AreEqual("ToInt32", md.Name);
363
Assert.AreEqual("s", md.Parameters.First().Name);
364
Assert.AreEqual(ParameterModifier.This, md.Parameters.First().ParameterModifier);
365
Assert.AreEqual("string", ((PrimitiveType)md.Parameters.First().Type).Keyword);
366
Assert.IsTrue(md.IsExtensionMethod);
370
public void ExtensionMethodWithAttributeTest()
372
MethodDeclaration md = ParseUtilCSharp.ParseTypeMember<MethodDeclaration>(
373
"public static int ToInt32([Attr] this string s) { return int.Parse(s); }"
375
Assert.AreEqual("ToInt32", md.Name);
376
Assert.IsTrue(md.IsExtensionMethod);
377
Assert.AreEqual("s", md.Parameters.Single().Name);
378
Assert.AreEqual(KnownTypeCode.String, ((PrimitiveType)md.Parameters.Single().Type).KnownTypeCode);
379
Assert.AreEqual(1, md.Parameters.Single().Attributes.Count);
383
public void VoidExtensionMethodTest()
385
MethodDeclaration md = ParseUtilCSharp.ParseTypeMember<MethodDeclaration>(
386
"public static void Print(this string s) { Console.WriteLine(s); }"
388
Assert.AreEqual("Print", md.Name);
389
Assert.AreEqual("s", md.Parameters.First().Name);
390
Assert.AreEqual(ParameterModifier.This, md.Parameters.First().ParameterModifier);
391
Assert.AreEqual("string", ((PrimitiveType)md.Parameters.First().Type).Keyword);
392
Assert.IsTrue(md.IsExtensionMethod);
396
public void MethodWithEmptyAssignmentErrorInBody()
398
MethodDeclaration md = ParseUtilCSharp.ParseTypeMember<MethodDeclaration>(
403
"}", true // expect errors
405
Assert.AreEqual("A", md.Name);
406
Assert.AreEqual(new TextLocation(2, 1), md.Body.StartLocation);
407
Assert.AreEqual(new TextLocation(5, 2), md.Body.EndLocation);
411
public void OptionalParameterTest()
413
ParseUtilCSharp.AssertTypeMember(
414
"public void Foo(string bar = null, int baz = 0) { }",
415
new MethodDeclaration {
416
Modifiers = Modifiers.Public,
417
ReturnType = new PrimitiveType("void"),
419
Body = new BlockStatement(),
421
new ParameterDeclaration {
422
Type = new PrimitiveType("string"),
424
DefaultExpression = new NullReferenceExpression()
426
new ParameterDeclaration {
427
Type = new PrimitiveType("int"),
429
DefaultExpression = new PrimitiveExpression(0)
435
public void AsyncMethod()
437
ParseUtilCSharp.AssertTypeMember(
438
"async void MyMethod() {}",
439
new MethodDeclaration {
440
Modifiers = Modifiers.Async,
441
ReturnType = new PrimitiveType("void"),
443
Body = new BlockStatement()
447
[Test, Ignore("parser bug, reported upstream.")]
448
public void AsyncAsyncAsync()
450
ParseUtilCSharp.AssertTypeMember(
451
"async async async(async async) {}",
452
new MethodDeclaration {
453
Modifiers = Modifiers.Async,
454
ReturnType = new SimpleType("async"),
456
Body = new BlockStatement(),
458
new ParameterDeclaration(new SimpleType("async"), "async")