/NRefactory/ICSharpCode.NRefactory.Tests/TypeSystem/GetAllBaseTypesTest.cs

http://github.com/icsharpcode/ILSpy · C# · 256 lines · 210 code · 23 blank · 23 comment · 0 complexity · 7210303ba3b1da6915a1af90adccb32f 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. using System;
  19. using System.Collections;
  20. using System.Collections.Generic;
  21. using System.Linq;
  22. using System.Runtime.Serialization;
  23. using ICSharpCode.NRefactory.CSharp;
  24. using ICSharpCode.NRefactory.TypeSystem.Implementation;
  25. using NUnit.Framework;
  26. namespace ICSharpCode.NRefactory.TypeSystem
  27. {
  28. using Unbound = ReflectionHelper.UnboundTypeArgument;
  29. [TestFixture]
  30. public class GetAllBaseTypesTest
  31. {
  32. const string corlib = @"
  33. namespace System {
  34. class Object {}
  35. class ValueType {}
  36. class String : System.Collections.Generic.IEnumerable<char>, IComparable<string> {}
  37. class Array : System.Collections.IList, ICloneable {}
  38. interface ICloneable {}
  39. interface IComparable<in T> {}
  40. struct Int32 {}
  41. struct Char {}
  42. }
  43. namespace System.Collections {
  44. interface IEnumerable {}
  45. interface ICollection : IEnumerable {}
  46. interface IList : ICollection {}
  47. interface IDictionary : ICollection {}
  48. }
  49. namespace System.Collections.Generic {
  50. interface IEnumerable<out T> : IEnumerable {}
  51. interface ICollection<T> : IEnumerable<T> {}
  52. interface IList<T> : ICollection<T> {}
  53. interface IDictionary<TKey, TValue> : ICollection<KeyValuePair<TKey, TValue>> {}
  54. class List<T> : IList, IList<T> {}
  55. class Dictionary<TKey, TValue> : IDictionary<TKey, TValue>, IDictionary {}
  56. struct KeyValuePair<TKey, TValue> {}
  57. }
  58. ";
  59. ICompilation compilation;
  60. [SetUp]
  61. public void SetUp()
  62. {
  63. var unresolvedFile = new CSharpParser().Parse(corlib, "corlib.cs").ToTypeSystem();
  64. compilation = new CSharpProjectContent().SetAssemblyName("mscorlib").AddOrUpdateFiles(unresolvedFile).CreateCompilation();
  65. }
  66. IType[] GetAllBaseTypes(Type type)
  67. {
  68. return compilation.FindType(type).GetAllBaseTypes().OrderBy(t => t.ReflectionName).ToArray();
  69. }
  70. IType[] GetTypes(params Type[] types)
  71. {
  72. return types.Select(t => compilation.FindType(t)).OrderBy(t => t.ReflectionName).ToArray();
  73. }
  74. ITypeDefinition Resolve(IUnresolvedTypeDefinition typeDef)
  75. {
  76. return compilation.MainAssembly.GetTypeDefinition(typeDef);
  77. }
  78. [Test]
  79. public void ObjectBaseTypes()
  80. {
  81. Assert.AreEqual(GetTypes(typeof(object)), GetAllBaseTypes(typeof(object)));
  82. Assert.That(compilation.FindType(KnownTypeCode.Object).DirectBaseTypes, Is.Empty);
  83. }
  84. [Test]
  85. public void StringBaseTypes()
  86. {
  87. Assert.AreEqual(GetTypes(typeof(string), typeof(object),
  88. typeof(IComparable<string>), typeof(IEnumerable<char>), typeof(IEnumerable)),
  89. GetAllBaseTypes(typeof(string)));
  90. }
  91. [Test]
  92. public void ArrayOfString()
  93. {
  94. var expectedTypes = GetTypes(
  95. typeof(string[]), typeof(Array), typeof(object),
  96. typeof(IList), typeof(ICollection), typeof(IEnumerable), typeof(ICloneable),
  97. typeof(IList<string>), typeof(ICollection<string>), typeof(IEnumerable<string>));
  98. Assert.AreEqual(expectedTypes,
  99. GetAllBaseTypes(typeof(string[])));
  100. }
  101. [Test]
  102. public unsafe void ArrayOfPointers()
  103. {
  104. Assert.AreEqual(GetTypes(typeof(int*[]), typeof(Array), typeof(object),
  105. typeof(IList), typeof(ICollection), typeof(IEnumerable), typeof(ICloneable)),
  106. GetAllBaseTypes(typeof(int*[])));
  107. }
  108. [Test]
  109. public void MultidimensionalArrayOfString()
  110. {
  111. Assert.AreEqual(GetTypes(typeof(string[,]), typeof(Array), typeof(object),
  112. typeof(IList), typeof(ICollection), typeof(IEnumerable), typeof(ICloneable)),
  113. GetAllBaseTypes(typeof(string[,])));
  114. }
  115. [Test]
  116. public void ClassDerivingFromItself()
  117. {
  118. // class C : C {}
  119. var c = new DefaultUnresolvedTypeDefinition(string.Empty, "C");
  120. c.BaseTypes.Add(c);
  121. compilation = TypeSystemHelper.CreateCompilation(c);
  122. ITypeDefinition resolvedC = Resolve(c);
  123. Assert.AreEqual(new [] { resolvedC }, resolvedC.GetAllBaseTypes().ToArray());
  124. }
  125. [Test]
  126. public void TwoClassesDerivingFromEachOther()
  127. {
  128. // class C1 : C2 {} class C2 : C1 {}
  129. var c1 = new DefaultUnresolvedTypeDefinition(string.Empty, "C1");
  130. var c2 = new DefaultUnresolvedTypeDefinition(string.Empty, "C2");
  131. c1.BaseTypes.Add(c2);
  132. c2.BaseTypes.Add(c1);
  133. compilation = TypeSystemHelper.CreateCompilation(c1, c2);
  134. ITypeDefinition resolvedC1 = Resolve(c1);
  135. ITypeDefinition resolvedC2 = Resolve(c2);
  136. Assert.AreEqual(new [] { resolvedC2, resolvedC1 }, resolvedC1.GetAllBaseTypes().ToArray());
  137. }
  138. [Test]
  139. public void ClassDerivingFromParameterizedVersionOfItself()
  140. {
  141. // class C<X> : C<C<X>> {}
  142. var c = new DefaultUnresolvedTypeDefinition(string.Empty, "C");
  143. c.TypeParameters.Add(new DefaultUnresolvedTypeParameter(EntityType.TypeDefinition, 0, "X"));
  144. c.BaseTypes.Add(new ParameterizedTypeReference(c, new [] { new ParameterizedTypeReference(c, new [] { new TypeParameterReference(EntityType.TypeDefinition, 0) }) }));
  145. compilation = TypeSystemHelper.CreateCompilation(c);
  146. ITypeDefinition resolvedC = Resolve(c);
  147. Assert.AreEqual(new [] { resolvedC }, resolvedC.GetAllBaseTypes().ToArray());
  148. }
  149. [Test]
  150. public void ClassDerivingFromTwoInstanciationsOfIEnumerable()
  151. {
  152. // class C : IEnumerable<int>, IEnumerable<uint> {}
  153. var c = new DefaultUnresolvedTypeDefinition(string.Empty, "C");
  154. c.BaseTypes.Add(typeof(IEnumerable<int>).ToTypeReference());
  155. c.BaseTypes.Add(typeof(IEnumerable<uint>).ToTypeReference());
  156. compilation = TypeSystemHelper.CreateCompilation(c);
  157. ITypeDefinition resolvedC = Resolve(c);
  158. IType[] expected = {
  159. resolvedC,
  160. compilation.FindType(typeof(IEnumerable<int>)),
  161. compilation.FindType(typeof(IEnumerable<uint>)),
  162. compilation.FindType(typeof(IEnumerable)),
  163. compilation.FindType(typeof(object))
  164. };
  165. Assert.AreEqual(expected,
  166. resolvedC.GetAllBaseTypes().OrderBy(t => t.ReflectionName).ToArray());
  167. }
  168. [Test]
  169. public void StructImplementingIEquatable()
  170. {
  171. // struct S : IEquatable<S> {}
  172. // don't use a Cecil-loaded struct for this test; we're testing the implicit addition of System.ValueType
  173. var s = new DefaultUnresolvedTypeDefinition(string.Empty, "S");
  174. s.Kind = TypeKind.Struct;
  175. s.BaseTypes.Add(new ParameterizedTypeReference(typeof(IEquatable<>).ToTypeReference(), new[] { s }));
  176. compilation = TypeSystemHelper.CreateCompilation(s);
  177. ITypeDefinition resolvedS = Resolve(s);
  178. IType[] expected = {
  179. resolvedS,
  180. s.BaseTypes[0].Resolve(new SimpleTypeResolveContext(resolvedS)),
  181. compilation.FindType(typeof(object)),
  182. compilation.FindType(typeof(ValueType))
  183. };
  184. Assert.AreEqual(expected,
  185. resolvedS.GetAllBaseTypes().OrderBy(t => t.ReflectionName).ToArray());
  186. }
  187. [Test]
  188. public void BaseTypesOfListOfString()
  189. {
  190. Assert.AreEqual(
  191. GetTypes(typeof(List<string>), typeof(object),
  192. typeof(IList), typeof(ICollection), typeof(IEnumerable),
  193. typeof(IEnumerable<string>), typeof(ICollection<string>), typeof(IList<string>)),
  194. GetAllBaseTypes(typeof(List<string>)));
  195. }
  196. [Test]
  197. public void BaseTypesOfUnboundDictionary()
  198. {
  199. Assert.AreEqual(
  200. new [] {
  201. typeof(Dictionary<,>).FullName,
  202. typeof(ICollection<>).FullName + "[[" + typeof(KeyValuePair<,>).FullName + "[[`0],[`1]]]]",
  203. typeof(IDictionary<,>).FullName + "[[`0],[`1]]",
  204. typeof(IEnumerable<>).FullName + "[[" + typeof(KeyValuePair<,>).FullName + "[[`0],[`1]]]]",
  205. typeof(ICollection).FullName,
  206. typeof(IDictionary).FullName,
  207. typeof(IEnumerable).FullName,
  208. typeof(object).FullName
  209. },
  210. GetAllBaseTypes(typeof(Dictionary<,>)).Select(t => t.ReflectionName).OrderBy(n => n).ToArray());
  211. }
  212. [Test]
  213. public void BaseTypeDefinitionsOfListOfString()
  214. {
  215. Assert.AreEqual(
  216. GetTypes(typeof(List<>), typeof(object),
  217. typeof(IList), typeof(ICollection), typeof(IEnumerable),
  218. typeof(IEnumerable<>), typeof(ICollection<>), typeof(IList<>)),
  219. compilation.FindType(typeof(List<string>)).GetAllBaseTypeDefinitions().OrderBy(t => t.ReflectionName).ToArray());
  220. }
  221. [Test]
  222. public void BaseTypeDefinitionsOfStringArray()
  223. {
  224. Assert.AreEqual(
  225. GetTypes(typeof(Array), typeof(object), typeof(ICloneable),
  226. typeof(IList), typeof(ICollection), typeof(IEnumerable),
  227. typeof(IEnumerable<>), typeof(ICollection<>), typeof(IList<>)),
  228. compilation.FindType(typeof(string[])).GetAllBaseTypeDefinitions().OrderBy(t => t.ReflectionName).ToArray());
  229. }
  230. }
  231. }