PageRenderTime 63ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

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

https://github.com/w4x/boolangstudio
C# | 432 lines | 348 code | 58 blank | 26 comment | 61 complexity | 3b2ad28fc7141ceb34be770147aa4125 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 virtual IType GetElementType()
  102. {
  103. return _typeSystemServices.Map(_type.GetElementType() ?? _type);
  104. }
  105. public virtual bool IsClass
  106. {
  107. get { return _type.IsClass; }
  108. }
  109. public bool IsAbstract
  110. {
  111. get { return _type.IsAbstract; }
  112. }
  113. public bool IsInterface
  114. {
  115. get { return _type.IsInterface; }
  116. }
  117. public bool IsEnum
  118. {
  119. get { return _type.IsEnum; }
  120. }
  121. public virtual bool IsValueType
  122. {
  123. get { return _type.IsValueType; }
  124. }
  125. public bool IsArray
  126. {
  127. get { return false; }
  128. }
  129. public virtual IType BaseType
  130. {
  131. get
  132. {
  133. Type baseType = _type.BaseType;
  134. return null == baseType
  135. ? null
  136. : _typeSystemServices.Map(baseType);
  137. }
  138. }
  139. protected virtual MemberInfo[] GetDefaultMembers()
  140. {
  141. MemberInfo[] miarr = ActualType.GetDefaultMembers();
  142. if(this.IsInterface && GetInterfaces() != null)
  143. {
  144. System.Collections.Generic.List<MemberInfo> memlist =
  145. new System.Collections.Generic.List<MemberInfo>();
  146. if(miarr != null)
  147. memlist.AddRange(miarr);
  148. foreach(ExternalType type in GetInterfaces())
  149. {
  150. miarr = type.GetDefaultMembers();
  151. if(miarr != null)
  152. memlist.AddRange(miarr);
  153. }
  154. miarr = memlist.ToArray();
  155. }
  156. return miarr;
  157. }
  158. public IEntity GetDefaultMember()
  159. {
  160. return _typeSystemServices.Map(GetDefaultMembers());
  161. }
  162. public Type ActualType
  163. {
  164. get { return _type; }
  165. }
  166. public virtual bool IsSubclassOf(IType other)
  167. {
  168. ExternalType external = other as ExternalType;
  169. if (null == external /*|| _typeSystemServices.VoidType == other*/)
  170. {
  171. return false;
  172. }
  173. return _type.IsSubclassOf(external._type) ||
  174. (external.IsInterface && external._type.IsAssignableFrom(_type))
  175. ;
  176. }
  177. public virtual bool IsAssignableFrom(IType other)
  178. {
  179. ExternalType external = other as ExternalType;
  180. if (null == external)
  181. {
  182. if (EntityType.Null == other.EntityType)
  183. {
  184. return !IsValueType;
  185. }
  186. return other.IsSubclassOf(this);
  187. }
  188. if (other == _typeSystemServices.VoidType)
  189. {
  190. return false;
  191. }
  192. return _type.IsAssignableFrom(external._type);
  193. }
  194. public virtual IConstructor[] GetConstructors()
  195. {
  196. if (null == _constructors)
  197. {
  198. BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
  199. ConstructorInfo[] ctors = _type.GetConstructors(flags);
  200. _constructors = new IConstructor[ctors.Length];
  201. for (int i=0; i<_constructors.Length; ++i)
  202. {
  203. _constructors[i] = new ExternalConstructor(_typeSystemServices, ctors[i]);
  204. }
  205. }
  206. return _constructors;
  207. }
  208. public virtual IType[] GetInterfaces()
  209. {
  210. if (null == _interfaces)
  211. {
  212. Type[] interfaces = _type.GetInterfaces();
  213. _interfaces = new IType[interfaces.Length];
  214. for (int i=0; i<_interfaces.Length; ++i)
  215. {
  216. _interfaces[i] = _typeSystemServices.Map(interfaces[i]);
  217. }
  218. }
  219. return _interfaces;
  220. }
  221. public virtual IEntity[] GetMembers()
  222. {
  223. if (null == _members)
  224. {
  225. BindingFlags flags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static;// | BindingFlags.FlattenHierarchy;
  226. MemberInfo[] members = _type.GetMembers(flags);
  227. Type[] nested = _type.GetNestedTypes();
  228. _members = new IEntity[members.Length+nested.Length];
  229. int i = 0;
  230. for (i=0; i<members.Length; ++i)
  231. {
  232. _members[i] = _typeSystemServices.Map(members[i]);
  233. }
  234. for (int j=0; j<nested.Length; ++j)
  235. {
  236. _members[i++] = _typeSystemServices.Map(nested[j]);
  237. }
  238. }
  239. return _members;
  240. }
  241. public int GetTypeDepth()
  242. {
  243. if (-1 == _typeDepth)
  244. {
  245. _typeDepth = GetTypeDepth(_type);
  246. }
  247. return _typeDepth;
  248. }
  249. public virtual INamespace ParentNamespace
  250. {
  251. get { return null; }
  252. }
  253. public virtual bool Resolve(List targetList, string name, EntityType flags)
  254. {
  255. bool found = false;
  256. foreach (IEntity member in GetMembers())
  257. {
  258. if (!NameResolutionService.IsFlagSet(flags, member.EntityType)) continue;
  259. if (member.Name == name)
  260. {
  261. targetList.AddUnique(member);
  262. found = true;
  263. }
  264. }
  265. if (IsInterface)
  266. {
  267. if (_typeSystemServices.ObjectType.Resolve(targetList, name, flags))
  268. {
  269. found = true;
  270. }
  271. foreach (IType baseInterface in GetInterfaces())
  272. {
  273. found |= baseInterface.Resolve(targetList, name, flags);
  274. }
  275. }
  276. else
  277. {
  278. if (!found || TypeSystemServices.ContainsMethodsOnly(targetList))
  279. {
  280. IType baseType = BaseType;
  281. if (null != baseType)
  282. {
  283. found |= baseType.Resolve(targetList, name, flags);
  284. }
  285. }
  286. }
  287. return found;
  288. }
  289. override public string ToString()
  290. {
  291. return FullName;
  292. }
  293. static int GetTypeDepth(Type type)
  294. {
  295. if (type.IsByRef)
  296. {
  297. return GetTypeDepth(type.GetElementType());
  298. }
  299. else if (type.IsInterface)
  300. {
  301. return GetInterfaceDepth(type);
  302. }
  303. return GetClassDepth(type);
  304. }
  305. static int GetClassDepth(Type type)
  306. {
  307. int depth = 0;
  308. Type objectType = Types.Object;
  309. while (type != objectType)
  310. {
  311. type = type.BaseType;
  312. ++depth;
  313. }
  314. return depth;
  315. }
  316. static int GetInterfaceDepth(Type type)
  317. {
  318. Type[] interfaces = type.GetInterfaces();
  319. if (interfaces.Length > 0)
  320. {
  321. int current = 0;
  322. foreach (Type i in interfaces)
  323. {
  324. int depth = GetInterfaceDepth(i);
  325. if (depth > current)
  326. {
  327. current = depth;
  328. }
  329. }
  330. return 1+current;
  331. }
  332. return 1;
  333. }
  334. protected virtual string BuildFullName()
  335. {
  336. if (_primitiveName != null) return _primitiveName;
  337. // keep builtin names pretty ('ref int' instead of 'ref System.Int32')
  338. if (_type.IsByRef) return "ref " + GetElementType().FullName;
  339. return Boo.Lang.Compiler.Util.TypeUtilities.GetFullName(_type);
  340. }
  341. ExternalGenericTypeInfo _genericTypeDefinitionInfo = null;
  342. public virtual IGenericTypeInfo GenericInfo
  343. {
  344. get
  345. {
  346. if (ActualType.IsGenericTypeDefinition)
  347. {
  348. if (_genericTypeDefinitionInfo == null)
  349. {
  350. _genericTypeDefinitionInfo = new ExternalGenericTypeInfo(_typeSystemServices, this);
  351. }
  352. return _genericTypeDefinitionInfo;
  353. }
  354. return null;
  355. }
  356. }
  357. ExternalConstructedTypeInfo _genericTypeInfo = null;
  358. public virtual IConstructedTypeInfo ConstructedInfo
  359. {
  360. get
  361. {
  362. if (ActualType.IsGenericType)
  363. {
  364. if (_genericTypeInfo == null)
  365. {
  366. _genericTypeInfo = new ExternalConstructedTypeInfo(_typeSystemServices, this);
  367. }
  368. return _genericTypeInfo;
  369. }
  370. return null;
  371. }
  372. }
  373. }
  374. }