PageRenderTime 45ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

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

https://github.com/w4x/boolangstudio
C# | 134 lines | 93 code | 12 blank | 29 comment | 24 complexity | 5a1efd15c0787e91a6fcddace7f60bfe MD5 | raw file
Possible License(s): GPL-2.0
  1. #region license
  2. // Copyright (c) 2003, 2004, 2005 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 System;
  29. using System.Reflection;
  30. using System.Collections.Generic;
  31. using Boo.Lang.Compiler.Ast;
  32. using Boo.Lang.Compiler.Util;
  33. namespace Boo.Lang.Compiler.TypeSystem
  34. {
  35. /// <summary>
  36. /// </summary>
  37. public static class MetadataUtil
  38. {
  39. public static bool IsAttributeDefined(TypeMember member, IType attributeType)
  40. {
  41. foreach (Boo.Lang.Compiler.Ast.Attribute attr in member.Attributes)
  42. {
  43. IEntity entity = TypeSystemServices.GetEntity(attr);
  44. if (entity == attributeType) return true; // pre bound attribute
  45. IConstructor constructor = entity as IConstructor;
  46. if (null == constructor) continue;
  47. if (constructor.DeclaringType == attributeType) return true;
  48. }
  49. return false;
  50. }
  51. public static Boo.Lang.Compiler.Ast.Attribute[] GetCustomAttributes(TypeMember member, IType attributeType)
  52. {
  53. List<Boo.Lang.Compiler.Ast.Attribute> attrs = new List<Boo.Lang.Compiler.Ast.Attribute>();
  54. foreach (Boo.Lang.Compiler.Ast.Attribute attr in member.Attributes)
  55. {
  56. IEntity entity = TypeSystemServices.GetEntity(attr);
  57. if (entity == attributeType) { // pre bound attribute
  58. attrs.Add(attr);
  59. continue;
  60. }
  61. IConstructor constructor = entity as IConstructor;
  62. if (null == constructor) continue;
  63. if (constructor.DeclaringType == attributeType) {
  64. attrs.Add(attr);
  65. continue;
  66. }
  67. }
  68. return attrs.ToArray();
  69. }
  70. private static readonly MemberInfo[] NoExtensions = new MemberInfo[0];
  71. private static Dictionary<Type, MemberInfo[]> _clrExtensionsMembers = new Dictionary<Type, MemberInfo[]>();
  72. public static MemberInfo[] GetClrExtensions(Type type, string memberName)
  73. {
  74. if (!HasClrExtensions()) return NoExtensions;
  75. MemberInfo[] members = null;
  76. if (!_clrExtensionsMembers.TryGetValue(type, out members))
  77. {
  78. if (!IsAttributeDefined(type, Types.ClrExtensionAttribute))
  79. {
  80. _clrExtensionsMembers.Add(type, NoExtensions);
  81. }
  82. else
  83. {
  84. members = type.FindMembers(MemberTypes.Method, BindingFlags.Public | BindingFlags.Static, ClrExtensionFilter, memberName);
  85. _clrExtensionsMembers.Add(type, members);
  86. }
  87. }
  88. return members ?? NoExtensions;
  89. }
  90. public static bool HasClrExtensions()
  91. {
  92. return Types.ClrExtensionAttribute != null;
  93. }
  94. private static bool ClrExtensionFilter(MemberInfo member, object memberName)
  95. {
  96. return TypeUtilities.TypeName(member.Name).Equals(memberName) && IsAttributeDefined(member, Types.ClrExtensionAttribute);
  97. }
  98. public static bool IsAttributeDefined(MemberInfo member, Type attributeType)
  99. {
  100. if (Types.ClrExtensionAttribute == attributeType && null != member.DeclaringType)
  101. {
  102. MemberInfo[] members;
  103. if (_clrExtensionsMembers.TryGetValue(member.DeclaringType, out members))
  104. {
  105. return ((ICollection<MemberInfo>) members).Contains(member);
  106. }
  107. }
  108. return System.Attribute.IsDefined(member, attributeType);
  109. #if CHECK_ATTRIBUTES_BY_NAME
  110. // check attribute by name to account for different
  111. // loaded modules (and thus different type identities)
  112. string attributeName = attributeType.FullName;
  113. System.Attribute[] attributes = System.Attribute.GetCustomAttributes(member);
  114. foreach (System.Attribute a in attributes)
  115. {
  116. if (a.GetType().FullName == attributeName) return true;
  117. }
  118. return false;
  119. #endif
  120. }
  121. }
  122. }