PageRenderTime 43ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/src/Boo.Lang.Compiler/TypeSystem/ExternalType.cs

https://github.com/boo/boo-lang
C# | 439 lines | 354 code | 59 blank | 26 comment | 63 complexity | 0bc1b85a4a2e4a519113a7be04be4ece MD5 | raw file
Possible License(s): GPL-2.0
  1. #region license
  2. // Copyright (c) 2004, Rodrigo B. de Oliveira (rbo@acm.org)
  3. // All rights reserved.
  4. //
  5. // Redistribution and use in source and binary forms, with or without modification,
  6. // are permitted provided that the following conditions are met:
  7. //
  8. // * Redistributions of source code must retain the above copyright notice,
  9. // this list of conditions and the following disclaimer.
  10. // * Redistributions in binary form must reproduce the above copyright notice,
  11. // this list of conditions and the following disclaimer in the documentation
  12. // and/or other materials provided with the distribution.
  13. // * Neither the name of Rodrigo B. de Oliveira nor the names of its
  14. // contributors may be used to endorse or promote products derived from this
  15. // software without specific prior written permission.
  16. //
  17. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  18. // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  19. // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  20. // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
  21. // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  22. // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  23. // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  24. // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  25. // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26. // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27. #endregion
  28. using Boo.Lang.Compiler.Util;
  29. namespace Boo.Lang.Compiler.TypeSystem
  30. {
  31. using System;
  32. using System.Reflection;
  33. public class ExternalType : IType
  34. {
  35. protected TypeSystemServices _typeSystemServices;
  36. private readonly Type _type;
  37. IConstructor[] _constructors;
  38. IType[] _interfaces;
  39. IEntity[] _members;
  40. int _typeDepth = -1;
  41. string _primitiveName;
  42. string _fullName;
  43. private string _name;
  44. internal ExternalType(TypeSystemServices tss, Type type)
  45. {
  46. if (null == type) throw new ArgumentException("type");
  47. _typeSystemServices = tss;
  48. _type = type;
  49. }
  50. public virtual string FullName
  51. {
  52. get
  53. {
  54. if (null != _fullName) return _fullName;
  55. return _fullName = BuildFullName();
  56. }
  57. }
  58. internal string PrimitiveName
  59. {
  60. get { return _primitiveName; }
  61. set { _primitiveName = value; }
  62. }
  63. public virtual string Name
  64. {
  65. get
  66. {
  67. if (null != _name) return _name;
  68. return _name = TypeName();
  69. }
  70. }
  71. private string TypeName()
  72. {
  73. return TypeUtilities.TypeName(_type);
  74. }
  75. public EntityType EntityType
  76. {
  77. get { return EntityType.Type; }
  78. }
  79. public IType Type
  80. {
  81. get { return this; }
  82. }
  83. public virtual bool IsFinal
  84. {
  85. get { return _type.IsSealed; }
  86. }
  87. public bool IsByRef
  88. {
  89. get { return _type.IsByRef; }
  90. }
  91. public IType DeclaringType
  92. {
  93. get
  94. {
  95. System.Type declaringType = _type.DeclaringType;
  96. return null != declaringType
  97. ? _typeSystemServices.Map(declaringType)
  98. : null;
  99. }
  100. }
  101. public bool IsDefined(IType attributeType)
  102. {
  103. ExternalType type = attributeType as ExternalType;
  104. if (null == type) return false;
  105. return MetadataUtil.IsAttributeDefined(_type, type.ActualType);
  106. }
  107. public virtual IType GetElementType()
  108. {
  109. return _typeSystemServices.Map(_type.GetElementType() ?? _type);
  110. }
  111. public virtual bool IsClass
  112. {
  113. get { return _type.IsClass; }
  114. }
  115. public bool IsAbstract
  116. {
  117. get { return _type.IsAbstract; }
  118. }
  119. public bool IsInterface
  120. {
  121. get { return _type.IsInterface; }
  122. }
  123. public bool IsEnum
  124. {
  125. get { return _type.IsEnum; }
  126. }
  127. public virtual bool IsValueType
  128. {
  129. get { return _type.IsValueType; }
  130. }
  131. public bool IsArray
  132. {
  133. get { return false; }
  134. }
  135. public virtual IType BaseType
  136. {
  137. get
  138. {
  139. Type baseType = _type.BaseType;
  140. return null == baseType
  141. ? null
  142. : _typeSystemServices.Map(baseType);
  143. }
  144. }
  145. protected virtual MemberInfo[] GetDefaultMembers()
  146. {
  147. MemberInfo[] miarr = ActualType.GetDefaultMembers();
  148. if(this.IsInterface && GetInterfaces() != null)
  149. {
  150. System.Collections.Generic.List<MemberInfo> memlist =
  151. new System.Collections.Generic.List<MemberInfo>();
  152. if(miarr != null)
  153. memlist.AddRange(miarr);
  154. foreach(ExternalType type in GetInterfaces())
  155. {
  156. miarr = type.GetDefaultMembers();
  157. if(miarr != null)
  158. memlist.AddRange(miarr);
  159. }
  160. miarr = memlist.ToArray();
  161. }
  162. return miarr;
  163. }
  164. public IEntity GetDefaultMember()
  165. {
  166. return _typeSystemServices.Map(GetDefaultMembers());
  167. }
  168. public Type ActualType
  169. {
  170. get { return _type; }
  171. }
  172. public virtual bool IsSubclassOf(IType other)
  173. {
  174. ExternalType external = other as ExternalType;
  175. if (null == external /*|| _typeSystemServices.VoidType == other*/)
  176. {
  177. return false;
  178. }
  179. return _type.IsSubclassOf(external._type) ||
  180. (external.IsInterface && external._type.IsAssignableFrom(_type))
  181. ;
  182. }
  183. public virtual bool IsAssignableFrom(IType other)
  184. {
  185. ExternalType external = other as ExternalType;
  186. if (null == external)
  187. {
  188. if (EntityType.Null == other.EntityType)
  189. {
  190. return !IsValueType;
  191. }
  192. return other.IsSubclassOf(this);
  193. }
  194. if (other == _typeSystemServices.VoidType)
  195. {
  196. return false;
  197. }
  198. return _type.IsAssignableFrom(external._type);
  199. }
  200. public virtual IConstructor[] GetConstructors()
  201. {
  202. if (null == _constructors)
  203. {
  204. BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
  205. ConstructorInfo[] ctors = _type.GetConstructors(flags);
  206. _constructors = new IConstructor[ctors.Length];
  207. for (int i=0; i<_constructors.Length; ++i)
  208. {
  209. _constructors[i] = new ExternalConstructor(_typeSystemServices, ctors[i]);
  210. }
  211. }
  212. return _constructors;
  213. }
  214. public virtual IType[] GetInterfaces()
  215. {
  216. if (null == _interfaces)
  217. {
  218. Type[] interfaces = _type.GetInterfaces();
  219. _interfaces = new IType[interfaces.Length];
  220. for (int i=0; i<_interfaces.Length; ++i)
  221. {
  222. _interfaces[i] = _typeSystemServices.Map(interfaces[i]);
  223. }
  224. }
  225. return _interfaces;
  226. }
  227. public virtual IEntity[] GetMembers()
  228. {
  229. if (null == _members)
  230. {
  231. BindingFlags flags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static;// | BindingFlags.FlattenHierarchy;
  232. MemberInfo[] members = _type.GetMembers(flags);
  233. Type[] nested = _type.GetNestedTypes();
  234. _members = new IEntity[members.Length+nested.Length];
  235. int i = 0;
  236. for (i=0; i<members.Length; ++i)
  237. {
  238. _members[i] = _typeSystemServices.Map(members[i]);
  239. }
  240. for (int j=0; j<nested.Length; ++j)
  241. {
  242. _members[i++] = _typeSystemServices.Map(nested[j]);
  243. }
  244. }
  245. return _members;
  246. }
  247. public int GetTypeDepth()
  248. {
  249. if (-1 == _typeDepth)
  250. {
  251. _typeDepth = GetTypeDepth(_type);
  252. }
  253. return _typeDepth;
  254. }
  255. public virtual INamespace ParentNamespace
  256. {
  257. get { return null; }
  258. }
  259. public virtual bool Resolve(List targetList, string name, EntityType flags)
  260. {
  261. bool found = false;
  262. foreach (IEntity member in GetMembers())
  263. {
  264. if (!NameResolutionService.IsFlagSet(flags, member.EntityType)) continue;
  265. if (member.Name == name)
  266. {
  267. targetList.AddUnique(member);
  268. found = true;
  269. }
  270. }
  271. if (IsInterface)
  272. {
  273. if (_typeSystemServices.ObjectType.Resolve(targetList, name, flags))
  274. {
  275. found = true;
  276. }
  277. foreach (IType baseInterface in GetInterfaces())
  278. {
  279. found |= baseInterface.Resolve(targetList, name, flags);
  280. }
  281. }
  282. else
  283. {
  284. if (!found || TypeSystemServices.ContainsMethodsOnly(targetList))
  285. {
  286. IType baseType = BaseType;
  287. if (null != baseType)
  288. {
  289. found |= baseType.Resolve(targetList, name, flags);
  290. }
  291. }
  292. }
  293. return found;
  294. }
  295. override public string ToString()
  296. {
  297. return FullName;
  298. }
  299. static int GetTypeDepth(Type type)
  300. {
  301. if (type.IsByRef)
  302. {
  303. return GetTypeDepth(type.GetElementType());
  304. }
  305. else if (type.IsInterface)
  306. {
  307. return GetInterfaceDepth(type);
  308. }
  309. return GetClassDepth(type);
  310. }
  311. static int GetClassDepth(Type type)
  312. {
  313. int depth = 0;
  314. Type objectType = Types.Object;
  315. while (type != objectType)
  316. {
  317. type = type.BaseType;
  318. ++depth;
  319. }
  320. return depth;
  321. }
  322. static int GetInterfaceDepth(Type type)
  323. {
  324. Type[] interfaces = type.GetInterfaces();
  325. if (interfaces.Length > 0)
  326. {
  327. int current = 0;
  328. foreach (Type i in interfaces)
  329. {
  330. int depth = GetInterfaceDepth(i);
  331. if (depth > current)
  332. {
  333. current = depth;
  334. }
  335. }
  336. return 1+current;
  337. }
  338. return 1;
  339. }
  340. protected virtual string BuildFullName()
  341. {
  342. if (_primitiveName != null) return _primitiveName;
  343. // keep builtin names pretty ('ref int' instead of 'ref System.Int32')
  344. if (_type.IsByRef) return "ref " + GetElementType().FullName;
  345. return Boo.Lang.Compiler.Util.TypeUtilities.GetFullName(_type);
  346. }
  347. ExternalGenericTypeInfo _genericTypeDefinitionInfo = null;
  348. public virtual IGenericTypeInfo GenericInfo
  349. {
  350. get
  351. {
  352. if (ActualType.IsGenericTypeDefinition)
  353. {
  354. if (_genericTypeDefinitionInfo == null)
  355. {
  356. _genericTypeDefinitionInfo = new ExternalGenericTypeInfo(_typeSystemServices, this);
  357. }
  358. return _genericTypeDefinitionInfo;
  359. }
  360. return null;
  361. }
  362. }
  363. ExternalConstructedTypeInfo _genericTypeInfo = null;
  364. public virtual IConstructedTypeInfo ConstructedInfo
  365. {
  366. get
  367. {
  368. if (ActualType.IsGenericType)
  369. {
  370. if (_genericTypeInfo == null)
  371. {
  372. _genericTypeInfo = new ExternalConstructedTypeInfo(_typeSystemServices, this);
  373. }
  374. return _genericTypeInfo;
  375. }
  376. return null;
  377. }
  378. }
  379. }
  380. }