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;
21
using System.Collections.Generic;
23
using System.Runtime.Serialization;
24
using ICSharpCode.NRefactory.CSharp;
25
using ICSharpCode.NRefactory.TypeSystem.Implementation;
26
using NUnit.Framework;
28
namespace ICSharpCode.NRefactory.TypeSystem
30
using Unbound = ReflectionHelper.UnboundTypeArgument;
33
public class GetAllBaseTypesTest
35
const string corlib = @"
39
class String : System.Collections.Generic.IEnumerable<char>, IComparable<string> {}
40
class Array : System.Collections.IList, ICloneable {}
42
interface ICloneable {}
43
interface IComparable<in T> {}
47
namespace System.Collections {
48
interface IEnumerable {}
49
interface ICollection : IEnumerable {}
50
interface IList : ICollection {}
51
interface IDictionary : ICollection {}
53
namespace System.Collections.Generic {
54
interface IEnumerable<out T> : IEnumerable {}
55
interface ICollection<T> : IEnumerable<T> {}
56
interface IList<T> : ICollection<T> {}
57
interface IDictionary<TKey, TValue> : ICollection<KeyValuePair<TKey, TValue>> {}
59
class List<T> : IList, IList<T> {}
60
class Dictionary<TKey, TValue> : IDictionary<TKey, TValue>, IDictionary {}
61
struct KeyValuePair<TKey, TValue> {}
65
ICompilation compilation;
70
var unresolvedFile = new CSharpParser().Parse(corlib, "corlib.cs").ToTypeSystem();
71
compilation = new CSharpProjectContent().SetAssemblyName("mscorlib").AddOrUpdateFiles(unresolvedFile).CreateCompilation();
74
IType[] GetAllBaseTypes(Type type)
76
return compilation.FindType(type).GetAllBaseTypes().OrderBy(t => t.ReflectionName).ToArray();
79
IType[] GetTypes(params Type[] types)
81
return types.Select(t => compilation.FindType(t)).OrderBy(t => t.ReflectionName).ToArray();
84
ITypeDefinition Resolve(IUnresolvedTypeDefinition typeDef)
86
return typeDef.Resolve(new SimpleTypeResolveContext(compilation.MainAssembly)).GetDefinition();
90
public void ObjectBaseTypes()
92
Assert.AreEqual(GetTypes(typeof(object)), GetAllBaseTypes(typeof(object)));
94
Assert.That(compilation.FindType(KnownTypeCode.Object).DirectBaseTypes, Is.Empty);
98
public void StringBaseTypes()
100
Assert.AreEqual(GetTypes(typeof(string), typeof(object),
101
typeof(IComparable<string>), typeof(IEnumerable<char>), typeof(IEnumerable)),
102
GetAllBaseTypes(typeof(string)));
106
public void ArrayOfString()
108
var expectedTypes = GetTypes(
109
typeof(string[]), typeof(Array), typeof(object),
110
typeof(IList), typeof(ICollection), typeof(IEnumerable), typeof(ICloneable),
111
typeof(IList<string>), typeof(ICollection<string>), typeof(IEnumerable<string>));
112
Assert.AreEqual(expectedTypes,
113
GetAllBaseTypes(typeof(string[])));
117
public unsafe void ArrayOfPointers()
119
Assert.AreEqual(GetTypes(typeof(int*[]), typeof(Array), typeof(object),
120
typeof(IList), typeof(ICollection), typeof(IEnumerable), typeof(ICloneable)),
121
GetAllBaseTypes(typeof(int*[])));
125
public void MultidimensionalArrayOfString()
127
Assert.AreEqual(GetTypes(typeof(string[,]), typeof(Array), typeof(object),
128
typeof(IList), typeof(ICollection), typeof(IEnumerable), typeof(ICloneable)),
129
GetAllBaseTypes(typeof(string[,])));
133
public void ClassDerivingFromItself()
136
var c = new DefaultUnresolvedTypeDefinition(string.Empty, "C");
138
ITypeDefinition resolvedC = TypeSystemHelper.CreateCompilationAndResolve(c);
139
Assert.AreEqual(new [] { resolvedC }, resolvedC.GetAllBaseTypes().ToArray());
143
public void TwoClassesDerivingFromEachOther()
145
// class C1 : C2 {} class C2 : C1 {}
146
var c1 = new DefaultUnresolvedTypeDefinition(string.Empty, "C1");
147
var c2 = new DefaultUnresolvedTypeDefinition(string.Empty, "C2");
148
c1.BaseTypes.Add(c2);
149
c2.BaseTypes.Add(c1);
150
compilation = TypeSystemHelper.CreateCompilation(c1, c2);
151
ITypeDefinition resolvedC1 = Resolve(c1);
152
ITypeDefinition resolvedC2 = Resolve(c2);
153
Assert.AreEqual(new [] { resolvedC2, resolvedC1 }, resolvedC1.GetAllBaseTypes().ToArray());
157
public void ClassDerivingFromParameterizedVersionOfItself()
159
// class C<X> : C<C<X>> {}
160
var c = new DefaultUnresolvedTypeDefinition(string.Empty, "C");
161
c.TypeParameters.Add(new DefaultUnresolvedTypeParameter(EntityType.TypeDefinition, 0, "X"));
162
c.BaseTypes.Add(new ParameterizedTypeReference(c, new [] { new ParameterizedTypeReference(c, new [] { new TypeParameterReference(EntityType.TypeDefinition, 0) }) }));
163
compilation = TypeSystemHelper.CreateCompilation(c);
164
ITypeDefinition resolvedC = Resolve(c);
165
Assert.AreEqual(new [] { resolvedC }, resolvedC.GetAllBaseTypes().ToArray());
169
public void ClassDerivingFromTwoInstanciationsOfIEnumerable()
171
// class C : IEnumerable<int>, IEnumerable<uint> {}
172
var c = new DefaultUnresolvedTypeDefinition(string.Empty, "C");
173
c.BaseTypes.Add(typeof(IEnumerable<int>).ToTypeReference());
174
c.BaseTypes.Add(typeof(IEnumerable<uint>).ToTypeReference());
175
compilation = TypeSystemHelper.CreateCompilation(c);
176
ITypeDefinition resolvedC = Resolve(c);
179
compilation.FindType(typeof(IEnumerable<int>)),
180
compilation.FindType(typeof(IEnumerable<uint>)),
181
compilation.FindType(typeof(IEnumerable)),
182
compilation.FindType(typeof(object))
184
Assert.AreEqual(expected,
185
resolvedC.GetAllBaseTypes().OrderBy(t => t.ReflectionName).ToArray());
189
public void StructImplementingIEquatable()
191
// struct S : IEquatable<S> {}
192
// don't use a Cecil-loaded struct for this test; we're testing the implicit addition of System.ValueType
193
var s = new DefaultUnresolvedTypeDefinition(string.Empty, "S");
194
s.Kind = TypeKind.Struct;
195
s.BaseTypes.Add(new ParameterizedTypeReference(typeof(IEquatable<>).ToTypeReference(), new[] { s }));
196
compilation = TypeSystemHelper.CreateCompilation(s);
197
ITypeDefinition resolvedS = Resolve(s);
200
s.BaseTypes[0].Resolve(new SimpleTypeResolveContext(resolvedS)),
201
compilation.FindType(typeof(object)),
202
compilation.FindType(typeof(ValueType))
204
Assert.AreEqual(expected,
205
resolvedS.GetAllBaseTypes().OrderBy(t => t.ReflectionName).ToArray());
209
public void BaseTypesOfListOfString()
212
GetTypes(typeof(List<string>), typeof(object),
213
typeof(IList), typeof(ICollection), typeof(IEnumerable),
214
typeof(IEnumerable<string>), typeof(ICollection<string>), typeof(IList<string>)),
215
GetAllBaseTypes(typeof(List<string>)));
219
public void BaseTypesOfUnboundDictionary()
223
typeof(Dictionary<,>).FullName,
224
typeof(ICollection<>).FullName + "[[" + typeof(KeyValuePair<,>).FullName + "[[`0],[`1]]]]",
225
typeof(IDictionary<,>).FullName + "[[`0],[`1]]",
226
typeof(IEnumerable<>).FullName + "[[" + typeof(KeyValuePair<,>).FullName + "[[`0],[`1]]]]",
227
typeof(ICollection).FullName,
228
typeof(IDictionary).FullName,
229
typeof(IEnumerable).FullName,
230
typeof(object).FullName
232
GetAllBaseTypes(typeof(Dictionary<,>)).Select(t => t.ReflectionName).OrderBy(n => n).ToArray());
236
public void BaseTypeDefinitionsOfListOfString()
239
GetTypes(typeof(List<>), typeof(object),
240
typeof(IList), typeof(ICollection), typeof(IEnumerable),
241
typeof(IEnumerable<>), typeof(ICollection<>), typeof(IList<>)),
242
compilation.FindType(typeof(List<string>)).GetAllBaseTypeDefinitions().OrderBy(t => t.ReflectionName).ToArray());
246
public void BaseTypeDefinitionsOfStringArray()
249
GetTypes(typeof(Array), typeof(object), typeof(ICloneable),
250
typeof(IList), typeof(ICollection), typeof(IEnumerable),
251
typeof(IEnumerable<>), typeof(ICollection<>), typeof(IList<>)),
252
compilation.FindType(typeof(string[])).GetAllBaseTypeDefinitions().OrderBy(t => t.ReflectionName).ToArray());