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.
20
using System.Collections.Generic;
23
using ICSharpCode.NRefactory.CSharp;
24
using ICSharpCode.NRefactory.TypeSystem;
25
using ICSharpCode.NRefactory.TypeSystem.Implementation;
26
using NUnit.Framework;
28
namespace ICSharpCode.NRefactory.Documentation
31
public class IDStringTests
33
class IDStringTestProjectContent : DefaultUnresolvedAssembly, IDocumentationProvider
35
public IDStringTestProjectContent() : base("Test") {}
37
public DocumentationComment GetDocumentation(IEntity entity)
39
// Note: there's no mscorlib in the context.
40
// These tests only use primitive types from mscorlib, so the full name is known
41
// without resolving them.
42
return new DocumentationComment(IdStringProvider.GetIdString(entity), new SimpleTypeResolveContext(entity));
46
IDStringTestProjectContent pc;
47
ICompilation compilation;
49
void Init(string program)
51
pc = new IDStringTestProjectContent();
53
var syntaxTree = SyntaxTree.Parse(program, "program.cs");
54
foreach (var type in syntaxTree.ToTypeSystem().TopLevelTypeDefinitions) {
55
pc.AddTypeDefinition(type);
57
compilation = new SimpleCompilation(pc, CecilLoaderTests.Mscorlib);
60
ITypeDefinition GetTypeDefinition(string nameSpace, string name, int typeParameterCount = 0)
62
return compilation.MainAssembly.GetTypeDefinition(new TopLevelTypeName(nameSpace, name, typeParameterCount));
66
public void TypeDefinitions()
69
enum Color { Red, Blue, Green }
74
class Widget: IProcess
76
public class NestedClass {}
78
public interface IMenuItem {}
80
public delegate void Del(int i);
82
public enum Direction { North, South, East, West }
90
Assert.AreEqual("T:Color", GetTypeDefinition(string.Empty, "Color").Documentation.ToString());
91
Assert.AreEqual("T:Acme.IProcess", GetTypeDefinition("Acme", "IProcess").Documentation.ToString());
92
Assert.AreEqual("T:Acme.ValueType", GetTypeDefinition("Acme", "ValueType").Documentation.ToString());
94
ITypeDefinition widget = GetTypeDefinition("Acme", "Widget");
95
Assert.AreEqual("T:Acme.Widget", widget.Documentation.ToString());
96
Assert.AreEqual("T:Acme.Widget.NestedClass", widget.NestedTypes.Single(t => t.Name == "NestedClass").Documentation.ToString());
97
Assert.AreEqual("T:Acme.Widget.IMenuItem", widget.NestedTypes.Single(t => t.Name == "IMenuItem").Documentation.ToString());
98
Assert.AreEqual("T:Acme.Widget.Del", widget.NestedTypes.Single(t => t.Name == "Del").Documentation.ToString());
99
Assert.AreEqual("T:Acme.Widget.Direction", widget.NestedTypes.Single(t => t.Name == "Direction").Documentation.ToString());
100
Assert.AreEqual("T:Acme.MyList`1", GetTypeDefinition("Acme", "MyList", 1).Documentation.ToString());
101
Assert.AreEqual("T:Acme.MyList`1.Helper`2", GetTypeDefinition("Acme", "MyList", 1).NestedTypes.Single().Documentation.ToString());
110
class Widget : IProcess
112
public class NestedClass
117
private string message;
118
private const double PI = 3.14159;
119
private unsafe float **ppValues;
123
ITypeDefinition widget = GetTypeDefinition("Acme", "Widget");
124
Assert.AreEqual("F:Acme.Widget.NestedClass.value", widget.NestedTypes.Single().Fields.Single().Documentation.ToString());
125
Assert.AreEqual("F:Acme.Widget.message", widget.Fields.Single(f => f.Name == "message").Documentation.ToString());
126
Assert.AreEqual("F:Acme.Widget.PI", widget.Fields.Single(f => f.Name == "PI").Documentation.ToString());
127
Assert.AreEqual("F:Acme.Widget.ppValues", widget.Fields.Single(f => f.Name == "ppValues").Documentation.ToString());
131
public void Constructors()
136
class Widget: IProcess
140
public Widget(string s) {}
144
ITypeDefinition widget = GetTypeDefinition("Acme", "Widget");
145
Assert.AreEqual("M:Acme.Widget.#cctor", widget.Methods.Single(m => m.IsStatic).Documentation.ToString());
146
Assert.AreEqual("M:Acme.Widget.#ctor", widget.Methods.Single(m => !m.IsStatic && m.Parameters.Count == 0).Documentation.ToString());
147
Assert.AreEqual("M:Acme.Widget.#ctor(System.String)", widget.Methods.Single(m => m.Parameters.Count == 1).Documentation.ToString());
151
public void Destructor()
156
class Widget: IProcess
162
ITypeDefinition widget = GetTypeDefinition("Acme", "Widget");
163
Assert.AreEqual("M:Acme.Widget.Finalize", widget.Methods.Single(m => m.EntityType == EntityType.Destructor).Documentation.ToString());
167
public void Methods()
174
class Widget: IProcess
176
public class NestedClass
178
public void M(int i) {}
181
public static void M0() {...}
182
public void M1(char c, out float f, ref ValueType v) {...}
183
public void M2(short[] x1, int[,] x2, long[][] x3) {...}
184
public void M3(long[][] x3, Widget[][,,] x4) {...}
185
public unsafe void M4(char *pc, Color **pf) {...}
186
public unsafe void M5(void *pv, double *[][,] pd) {...}
187
public void M6(int? i, params object[] args) {...}
192
public void Test(T t) { }
197
public void Process(MyList<Color> list) { }
198
public MyList<T> GetValues<T>(T inputValue) { return null; }
202
ITypeDefinition widget = GetTypeDefinition("Acme", "Widget");
203
Assert.AreEqual("M:Acme.Widget.NestedClass.M(System.Int32)", widget.NestedTypes.Single().Methods.Single(m => m.EntityType == EntityType.Method).Documentation.ToString());
204
Assert.AreEqual("M:Acme.Widget.M0", widget.Methods.Single(m => m.Name == "M0").Documentation.ToString());
205
Assert.AreEqual("M:Acme.Widget.M1(System.Char,System.Single@,Acme.ValueType@)",
206
widget.Methods.Single(m => m.Name == "M1").Documentation.ToString());
207
Assert.AreEqual("M:Acme.Widget.M2(System.Int16[],System.Int32[0:,0:],System.Int64[][])",
208
widget.Methods.Single(m => m.Name == "M2").Documentation.ToString());
209
Assert.AreEqual("M:Acme.Widget.M3(System.Int64[][],Acme.Widget[0:,0:,0:][])",
210
widget.Methods.Single(m => m.Name == "M3").Documentation.ToString());
211
Assert.AreEqual("M:Acme.Widget.M4(System.Char*,Color**)",
212
widget.Methods.Single(m => m.Name == "M4").Documentation.ToString());
213
Assert.AreEqual("M:Acme.Widget.M5(System.Void*,System.Double*[0:,0:][])",
214
widget.Methods.Single(m => m.Name == "M5").Documentation.ToString());
215
Assert.AreEqual("M:Acme.Widget.M6(System.Nullable{System.Int32},System.Object[])",
216
widget.Methods.Single(m => m.Name == "M6").Documentation.ToString());
218
Assert.AreEqual("M:Acme.MyList`1.Test(`0)",
219
GetTypeDefinition("Acme", "MyList", 1).Methods.Single(m => m.Name == "Test").Documentation.ToString());
221
Assert.AreEqual("M:Acme.UseList.Process(Acme.MyList{Color})",
222
GetTypeDefinition("Acme", "UseList").Methods.Single(m => m.Name == "Process").Documentation.ToString());
223
Assert.AreEqual("M:Acme.UseList.GetValues``1(``0)",
224
GetTypeDefinition("Acme", "UseList").Methods.Single(m => m.Name == "GetValues").Documentation.ToString());
228
public void NestedGenerics()
230
Init("class A<X> { class B<Y> { void M(A<Y>.B<X> a) { } } }");
231
ITypeDefinition b = GetTypeDefinition("", "A", 1).NestedTypes.Single();
232
Assert.AreEqual("T:A`1.B`1", b.Documentation.ToString());
233
Assert.AreEqual("M:A`1.B`1.M(A{`1}.B{`0})", b.Methods.Single(m => m.EntityType == EntityType.Method).Documentation.ToString());
237
public void Properties()
242
class Widget: IProcess
244
public int Width { get {...} set {...} }
245
public int this[int i] { get {...} set {...} }
246
public int this[string s, int i] { get {...} set {...} }
250
ITypeDefinition widget = GetTypeDefinition("Acme", "Widget");
251
Assert.AreEqual("P:Acme.Widget.Width", widget.Properties.Single(p => p.Parameters.Count == 0).Documentation.ToString());
252
Assert.AreEqual("P:Acme.Widget.Item(System.Int32)",
253
widget.Properties.Single(p => p.Parameters.Count == 1).Documentation.ToString());
254
Assert.AreEqual("P:Acme.Widget.Item(System.String,System.Int32)",
255
widget.Properties.Single(p => p.Parameters.Count == 2).Documentation.ToString());
265
class Widget: IProcess
267
public event Del AnEvent;
271
ITypeDefinition widget = GetTypeDefinition("Acme", "Widget");
272
Assert.AreEqual("E:Acme.Widget.AnEvent", widget.Events.Single().Documentation.ToString());
277
public void UnaryOperator()
282
class Widget: IProcess
284
public static Widget operator+(Widget x) { }
288
ITypeDefinition widget = GetTypeDefinition("Acme", "Widget");
289
Assert.AreEqual("M:Acme.Widget.op_UnaryPlus(Acme.Widget)", widget.Methods.Single(m => m.EntityType == EntityType.Operator).Documentation.ToString());
293
public void BinaryOperator()
298
class Widget: IProcess
300
public static Widget operator+(Widget x1, Widget x2) { }
304
ITypeDefinition widget = GetTypeDefinition("Acme", "Widget");
305
Assert.AreEqual("M:Acme.Widget.op_Addition(Acme.Widget,Acme.Widget)", widget.Methods.Single(m => m.EntityType == EntityType.Operator).Documentation.ToString());
309
public void ConversionOperator()
314
class Widget: IProcess
316
public static explicit operator int(Widget x) { }
317
public static implicit operator long(Widget x) { }
321
ITypeDefinition widget = GetTypeDefinition("Acme", "Widget");
322
Assert.AreEqual("M:Acme.Widget.op_Explicit(Acme.Widget)~System.Int32", widget.Methods.First(m => m.EntityType == EntityType.Operator).Documentation.ToString());
323
Assert.AreEqual("M:Acme.Widget.op_Implicit(Acme.Widget)~System.Int64", widget.Methods.Last(m => m.EntityType == EntityType.Operator).Documentation.ToString());
327
public void CorlibIDStrings()
329
var list = new SimpleCompilation(CecilLoaderTests.Mscorlib).FindType(typeof(List<>)).GetDefinition();
330
Assert.AreEqual("T:System.Collections.Generic.List`1",
331
IdStringProvider.GetIdString(list));
332
Assert.AreEqual("M:System.Collections.Generic.List`1.Add(`0)",
333
IdStringProvider.GetIdString(list.Methods.Single(m => m.Name == "Add")));
334
Assert.AreEqual("M:System.Collections.Generic.List`1.AddRange(System.Collections.Generic.IEnumerable{`0})",
335
IdStringProvider.GetIdString(list.Methods.Single(m => m.Name == "AddRange")));
336
Assert.AreEqual("M:System.Collections.Generic.List`1.ConvertAll``1(System.Converter{`0,``0})",
337
IdStringProvider.GetIdString(list.Methods.Single(m => m.Name == "ConvertAll")));
341
public void ExplicitGenericInterfaceImplementation_IDString()
345
interface IGeneric<A, B> { void Test<T>(ref T a); }
346
class Impl<T> : IGeneric<string[,], T> {
347
void IGeneric<string[,], T>.Test<X>(ref X a);
351
ITypeDefinition impl = GetTypeDefinition("xxx", "Impl", 1);
352
IMethod method = impl.Methods.Single(m => m.Name == "Test");
355
"M:xxx.Impl`1.xxx#IGeneric{System#String[@]@T}#Test``1(``0@)",
356
IdStringProvider.GetIdString(method));