/NRefactory/ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractMember.cs

http://github.com/icsharpcode/ILSpy · C# · 317 lines · 245 code · 41 blank · 31 comment · 26 complexity · ea6225e5022b4e1db141886993e83889 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.Generic;
  20. using ICSharpCode.NRefactory.Utils;
  21. namespace ICSharpCode.NRefactory.TypeSystem.Implementation
  22. {
  23. /// <summary>
  24. /// Base class for <see cref="IMember"/> implementations.
  25. /// </summary>
  26. [Serializable]
  27. public abstract class AbstractMember : AbstractFreezable, IMember
  28. {
  29. // possible optimizations to reduce the memory usage of AbstractMember:
  30. // - put 'bool isFrozen' into flags
  31. // - store regions in more compact form (e.g. assume both file names are identical; use ushort for columns)
  32. ITypeDefinition declaringTypeDefinition;
  33. ITypeReference returnType = SharedTypes.UnknownType;
  34. IList<IAttribute> attributes;
  35. IList<IExplicitInterfaceImplementation> interfaceImplementations;
  36. DomRegion region;
  37. DomRegion bodyRegion;
  38. string name;
  39. // 1 byte per enum + 2 bytes for flags
  40. Accessibility accessibility;
  41. EntityType entityType;
  42. protected BitVector16 flags;
  43. const ushort FlagSealed = 0x0001;
  44. const ushort FlagAbstract = 0x0002;
  45. const ushort FlagShadowing = 0x0004;
  46. const ushort FlagSynthetic = 0x0008;
  47. const ushort FlagVirtual = 0x0010;
  48. const ushort FlagOverride = 0x0020;
  49. const ushort FlagStatic = 0x0040;
  50. // Flags of form 0xY000 are reserved for use in derived classes (DefaultMethod etc.)
  51. protected override void FreezeInternal()
  52. {
  53. attributes = FreezeList(attributes);
  54. interfaceImplementations = FreezeList(interfaceImplementations);
  55. base.FreezeInternal();
  56. }
  57. protected AbstractMember(ITypeDefinition declaringTypeDefinition, string name, EntityType entityType)
  58. {
  59. if (declaringTypeDefinition == null)
  60. throw new ArgumentNullException("declaringTypeDefinition");
  61. if (name == null)
  62. throw new ArgumentNullException("name");
  63. this.declaringTypeDefinition = declaringTypeDefinition;
  64. this.entityType = entityType;
  65. this.name = name;
  66. }
  67. /// <summary>
  68. /// Copy constructor
  69. /// </summary>
  70. protected AbstractMember(IMember member)
  71. {
  72. if (member == null)
  73. throw new ArgumentNullException("member");
  74. this.declaringTypeDefinition = member.DeclaringTypeDefinition;
  75. this.returnType = member.ReturnType;
  76. this.attributes = CopyList(member.Attributes);
  77. this.interfaceImplementations = CopyList(member.InterfaceImplementations);
  78. this.region = member.Region;
  79. this.bodyRegion = member.BodyRegion;
  80. this.name = member.Name;
  81. this.accessibility = member.Accessibility;
  82. this.entityType = member.EntityType;
  83. this.IsSealed = member.IsSealed;
  84. this.IsAbstract = member.IsAbstract;
  85. this.IsShadowing = member.IsShadowing;
  86. this.IsSynthetic = member.IsSynthetic;
  87. this.IsVirtual = member.IsVirtual;
  88. this.IsOverride = member.IsOverride;
  89. this.IsStatic = member.IsStatic;
  90. }
  91. public ITypeDefinition DeclaringTypeDefinition {
  92. get { return declaringTypeDefinition; }
  93. }
  94. public virtual IType DeclaringType {
  95. get { return declaringTypeDefinition; }
  96. }
  97. public virtual IMember MemberDefinition {
  98. get { return this; }
  99. }
  100. public ITypeReference ReturnType {
  101. get { return returnType; }
  102. set {
  103. CheckBeforeMutation();
  104. if (value == null)
  105. throw new ArgumentNullException();
  106. returnType = value;
  107. }
  108. }
  109. public IList<IExplicitInterfaceImplementation> InterfaceImplementations {
  110. get {
  111. if (interfaceImplementations == null)
  112. interfaceImplementations = new List<IExplicitInterfaceImplementation>();
  113. return interfaceImplementations;
  114. }
  115. }
  116. public bool IsVirtual {
  117. get { return flags[FlagVirtual]; }
  118. set {
  119. CheckBeforeMutation();
  120. flags[FlagVirtual] = value;
  121. }
  122. }
  123. public bool IsOverride {
  124. get { return flags[FlagOverride]; }
  125. set {
  126. CheckBeforeMutation();
  127. flags[FlagOverride] = value;
  128. }
  129. }
  130. public bool IsOverridable {
  131. get {
  132. return (IsVirtual || IsOverride) && !IsSealed;
  133. }
  134. }
  135. public EntityType EntityType {
  136. get { return entityType; }
  137. set {
  138. CheckBeforeMutation();
  139. entityType = value;
  140. }
  141. }
  142. public DomRegion Region {
  143. get { return region; }
  144. set {
  145. CheckBeforeMutation();
  146. region = value;
  147. }
  148. }
  149. public DomRegion BodyRegion {
  150. get { return bodyRegion; }
  151. set {
  152. CheckBeforeMutation();
  153. bodyRegion = value;
  154. }
  155. }
  156. public IList<IAttribute> Attributes {
  157. get {
  158. if (attributes == null)
  159. attributes = new List<IAttribute>();
  160. return attributes;
  161. }
  162. }
  163. public virtual string Documentation {
  164. get {
  165. // To save memory, we don't store the documentation provider within the member,
  166. // but simply use our declaring type definition as documentation provider.
  167. // If that fails, we try if the project content is a documentation provider:
  168. IDocumentationProvider provider = declaringTypeDefinition as IDocumentationProvider
  169. ?? declaringTypeDefinition.ProjectContent as IDocumentationProvider;
  170. if (provider != null)
  171. return provider.GetDocumentation(this);
  172. else
  173. return null;
  174. }
  175. }
  176. public Accessibility Accessibility {
  177. get { return accessibility; }
  178. set {
  179. CheckBeforeMutation();
  180. accessibility = value;
  181. }
  182. }
  183. public bool IsStatic {
  184. get { return flags[FlagStatic]; }
  185. set {
  186. CheckBeforeMutation();
  187. flags[FlagStatic] = value;
  188. }
  189. }
  190. public bool IsAbstract {
  191. get { return flags[FlagAbstract]; }
  192. set {
  193. CheckBeforeMutation();
  194. flags[FlagAbstract] = value;
  195. }
  196. }
  197. public bool IsSealed {
  198. get { return flags[FlagSealed]; }
  199. set {
  200. CheckBeforeMutation();
  201. flags[FlagSealed] = value;
  202. }
  203. }
  204. public bool IsShadowing {
  205. get { return flags[FlagShadowing]; }
  206. set {
  207. CheckBeforeMutation();
  208. flags[FlagShadowing] = value;
  209. }
  210. }
  211. public bool IsSynthetic {
  212. get { return flags[FlagSynthetic]; }
  213. set {
  214. CheckBeforeMutation();
  215. flags[FlagSynthetic] = value;
  216. }
  217. }
  218. public bool IsPrivate {
  219. get { return Accessibility == Accessibility.Private; }
  220. }
  221. public bool IsPublic {
  222. get { return Accessibility == Accessibility.Public; }
  223. }
  224. public bool IsProtected {
  225. get { return Accessibility == Accessibility.Protected; }
  226. }
  227. public bool IsInternal {
  228. get { return Accessibility == Accessibility.Internal; }
  229. }
  230. public bool IsProtectedOrInternal {
  231. get { return Accessibility == Accessibility.ProtectedOrInternal; }
  232. }
  233. public bool IsProtectedAndInternal {
  234. get { return Accessibility == Accessibility.ProtectedAndInternal; }
  235. }
  236. public IProjectContent ProjectContent {
  237. get { return declaringTypeDefinition.ProjectContent; }
  238. }
  239. public IParsedFile ParsedFile {
  240. get { return declaringTypeDefinition.ParsedFile; }
  241. }
  242. public string Name {
  243. get { return name; }
  244. set {
  245. CheckBeforeMutation();
  246. if (value == null)
  247. throw new ArgumentNullException();
  248. name = value;
  249. }
  250. }
  251. public virtual string FullName {
  252. get {
  253. return this.DeclaringType.FullName + "." + this.Name;
  254. }
  255. }
  256. public string Namespace {
  257. get { return declaringTypeDefinition.Namespace; }
  258. }
  259. public virtual string ReflectionName {
  260. get { return this.DeclaringType.ReflectionName + "." + this.Name; }
  261. }
  262. public override string ToString()
  263. {
  264. return "[" + EntityType + " " + ReflectionName + ":" + ReturnType + "]";
  265. }
  266. public virtual void ApplyInterningProvider(IInterningProvider provider)
  267. {
  268. if (provider != null) {
  269. returnType = provider.Intern(returnType);
  270. attributes = provider.InternList(attributes);
  271. interfaceImplementations = provider.InternList(interfaceImplementations);
  272. name = provider.Intern(name);
  273. }
  274. }
  275. }
  276. }