* MonoDevelop.Projects.Dom/AbstractMember.cs: Fixed inner type bug.
[monodevelop.git] / main / src / core / MonoDevelop.Projects / MonoDevelop.Projects.Dom / AbstractMember.cs
blob58bd0b76a68b71fe66aa45828189189d28e0422c
1 //
2 // AbstractMember.cs
3 //
4 // Author:
5 // Mike Krüger <mkrueger@novell.com>
6 //
7 // Copyright (C) 2008 Novell, Inc (http://www.novell.com)
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 using System;
30 using System.Collections.Generic;
31 using System.Linq;
32 using MonoDevelop.Projects.Dom.Parser;
34 namespace MonoDevelop.Projects.Dom
36 public abstract class AbstractMember : IMember
38 protected IReturnType returnType;
39 protected List<IReturnType> explicitInterfaces = null;
41 protected IType declaringType;
43 public IType DeclaringType {
44 get {
45 return declaringType;
47 set {
48 this.declaringType = value;
49 fullNameIsDirty = true;
53 string fullName;
54 public virtual string FullName {
55 get {
56 if (fullNameIsDirty) {
57 fullName = CalculateFullName ();
58 fullNameIsDirty = false;
60 return fullName;
64 protected bool fullNameIsDirty = true;
65 protected virtual string CalculateFullName ()
67 return DeclaringType != null ? DeclaringType.FullName + "." + Name : Name;
70 public virtual IReturnType ReturnType {
71 get {
72 return returnType;
74 set {
75 returnType = value;
79 public IEnumerable<IReturnType> ExplicitInterfaces {
80 get {
81 return (IEnumerable<IReturnType>)explicitInterfaces ?? new IReturnType [0];
85 public bool IsExplicitDeclaration {
86 get {
87 return explicitInterfaces != null && explicitInterfaces.Count > 0;
91 protected string name;
92 public virtual string Name {
93 get {
94 return name;
96 set {
97 name = value;
98 fullNameIsDirty = true;
102 public virtual string Documentation {
103 get;
104 set;
107 public virtual DomLocation Location {
108 get;
109 set;
112 public virtual DomRegion BodyRegion {
113 get;
114 set;
117 public virtual Modifiers Modifiers {
118 get;
119 set;
122 public virtual bool IsObsolete {
123 get {
124 foreach (IAttribute attr in Attributes) {
125 switch (attr.Name) {
126 case "System.Obsolete":
127 case "System.ObsoleteAttribute":
128 case "Obsolete":
129 case "ObsoleteAttribute":
130 return true;
133 return false;
137 List<IAttribute> attributes = null;
138 static readonly IAttribute[] emptyAttributes = new IAttribute[0];
139 public virtual IEnumerable<IAttribute> Attributes {
140 get {
141 return (IEnumerable<IAttribute>)attributes ?? emptyAttributes;
145 public void AddExplicitInterface (IReturnType iface)
147 if (explicitInterfaces == null)
148 explicitInterfaces = new List<IReturnType> ();
149 explicitInterfaces.Add (iface);
152 protected void ClearAttributes ()
154 if (attributes != null)
155 attributes.Clear ();
158 public void Add (IAttribute attribute)
160 if (attributes == null)
161 attributes = new List<IAttribute> ();
162 attributes.Add (attribute);
165 public void AddRange (IEnumerable<IAttribute> attributes)
167 if (attributes == null)
168 return;
169 foreach (IAttribute attribute in attributes) {
170 Add (attribute);
174 /// <summary>
175 /// This method is used to look up special methods that are connected to
176 /// the member (like set/get method for events).
177 /// </summary>
178 /// <param name="prefix">
179 /// A <see cref="System.String"/> for the prefix. For example the property Name has the method set_Name attacehd
180 /// and 'set_' is the prefix.
181 /// </param>
182 /// <returns>
183 /// A <see cref="IMethod"/> when the special method is found, null otherwise.
184 /// </returns>
185 protected IMethod LookupSpecialMethod (string prefix)
187 if (DeclaringType == null)
188 return null;
189 string specialMethodName = prefix + Name;
190 foreach (IMethod method in DeclaringType.Methods) {
191 if (method.IsSpecialName && method.Name == specialMethodName)
192 return method;
194 return null;
197 public abstract string HelpUrl {
198 get;
201 public abstract string StockIcon {
202 get;
205 /// <summary>
206 /// Help method used for getting the right icon for a member.
207 /// </summary>
208 /// <param name="modifier">
209 /// A <see cref="Modifiers"/>
210 /// </param>
211 /// <returns>
212 /// A <see cref="System.Int32"/>
213 /// </returns>
214 protected static int ModifierToOffset (Modifiers modifier)
216 if ((modifier & Modifiers.Private) == Modifiers.Private)
217 return 1;
218 if ((modifier & Modifiers.Protected) == Modifiers.Protected)
219 return 2;
220 if ((modifier & Modifiers.Internal) == Modifiers.Internal)
221 return 3;
222 return 0;
224 // Dictionary<string, bool> protectedTable = new Dictionary<string, bool> ();
225 public virtual bool IsAccessibleFrom (ProjectDom dom, IType calledType, IMember member, bool includeProtected)
227 if (member == null)
228 return IsStatic || IsPublic;
229 // if (member.IsStatic && !IsStatic)
230 // return false;
231 if (IsPublic || calledType != null && calledType.ClassType == ClassType.Interface)
232 return true;
233 if (IsInternal) {
234 IType type1 = this is IType ? (IType)this : DeclaringType;
235 IType type2 = member is IType ? (IType)member : member.DeclaringType;
236 // easy case, projects are the same
237 if (type1.SourceProjectDom == type2.SourceProjectDom)
238 return true;
239 // maybe type2 hasn't project dom set (may occur in some cases), check if the file is in the project
240 if (type1.SourceProjectDom != null && type1.SourceProjectDom.Project != null)
241 return type1.SourceProjectDom.Project.GetProjectFile (type2.CompilationUnit.FileName) != null;
242 if (type2.SourceProjectDom != null && type2.SourceProjectDom.Project != null)
243 return type2.SourceProjectDom.Project.GetProjectFile (type1.CompilationUnit.FileName) != null;
244 return false;
246 if (!(member is IType) && (member.DeclaringType == null || DeclaringType == null))
247 return false;
249 if (IsProtected) {
251 /* foreach (IType type in dom.GetInheritanceTree (calledType)) {
252 if (type.FullName == member.DeclaringType.FullName) {
253 protectedTable[protectedTableKey] = true;
254 return true;
257 return includeProtected;
259 // inner class
260 IType declaringType = member.DeclaringType;
261 while (declaringType != null) {
262 if (declaringType.Equals (DeclaringType))
263 return true;
264 declaringType = declaringType.DeclaringType;
266 if (member is MonoDevelop.Projects.Dom.BaseResolveResult.BaseMemberDecorator)
267 return IsPublic | IsProtected;
269 return member.DeclaringType != null && DeclaringType.FullName == member.DeclaringType.FullName;
273 public virtual int CompareTo (object obj)
275 if (obj is IMember)
276 return Name.CompareTo (((IMember)obj).Name);
277 return 1;
280 #region ModifierAccessors
281 public bool IsPrivate {
282 get {
283 return (this.Modifiers & Modifiers.Private) == Modifiers.Private;
286 public bool IsInternal {
287 get {
288 return (this.Modifiers & Modifiers.Internal) == Modifiers.Internal;
291 public bool IsProtected {
292 get {
293 return (this.Modifiers & Modifiers.Protected) == Modifiers.Protected;
296 public bool IsPublic {
297 get {
298 return (this.Modifiers & Modifiers.Public) == Modifiers.Public;
301 public bool IsProtectedAndInternal {
302 get {
303 return (this.Modifiers & Modifiers.ProtectedAndInternal) == Modifiers.ProtectedAndInternal;
306 public bool IsProtectedOrInternal {
307 get {
308 return (this.Modifiers & Modifiers.ProtectedOrInternal) == Modifiers.ProtectedOrInternal;
312 public bool IsAbstract {
313 get {
314 return (this.Modifiers & Modifiers.Abstract) == Modifiers.Abstract;
317 public bool IsVirtual {
318 get {
319 return (this.Modifiers & Modifiers.Virtual) == Modifiers.Virtual;
322 public bool IsSealed {
323 get {
324 return (this.Modifiers & Modifiers.Sealed) == Modifiers.Sealed;
327 public bool IsStatic {
328 get {
329 return (this.Modifiers & Modifiers.Static) == Modifiers.Static;
332 public bool IsOverride {
333 get {
334 return (this.Modifiers & Modifiers.Override) == Modifiers.Override;
337 public bool IsReadonly {
338 get {
339 return (this.Modifiers & Modifiers.Readonly) == Modifiers.Readonly;
342 public bool IsConst {
343 get {
344 return (this.Modifiers & Modifiers.Const) == Modifiers.Const;
347 public bool IsNew {
348 get {
349 return (this.Modifiers & Modifiers.New) == Modifiers.New;
352 public bool IsPartial {
353 get {
354 return (this.Modifiers & Modifiers.Partial) == Modifiers.Partial;
358 public bool IsExtern {
359 get {
360 return (this.Modifiers & Modifiers.Extern) == Modifiers.Extern;
363 public bool IsVolatile {
364 get {
365 return (this.Modifiers & Modifiers.Volatile) == Modifiers.Volatile;
368 public bool IsUnsafe {
369 get {
370 return (this.Modifiers & Modifiers.Unsafe) == Modifiers.Unsafe;
373 public bool IsOverloads {
374 get {
375 return (this.Modifiers & Modifiers.Overloads) == Modifiers.Overloads;
378 public bool IsWithEvents {
379 get {
380 return (this.Modifiers & Modifiers.WithEvents) == Modifiers.WithEvents;
383 public bool IsDefault {
384 get {
385 return (this.Modifiers & Modifiers.Default) == Modifiers.Default;
388 public bool IsFixed {
389 get {
390 return (this.Modifiers & Modifiers.Fixed) == Modifiers.Fixed;
394 public bool IsSpecialName {
395 get {
396 return (this.Modifiers & Modifiers.SpecialName) == Modifiers.SpecialName;
399 public bool IsFinal {
400 get {
401 return (this.Modifiers & Modifiers.Final) == Modifiers.Final;
404 public bool IsLiteral {
405 get {
406 return (this.Modifiers & Modifiers.Literal) == Modifiers.Literal;
409 #endregion
411 public virtual System.Xml.XmlNode GetMonodocDocumentation ()
413 if (DeclaringType == null)
414 return null;
416 if (DeclaringType.HelpXml != null) {
417 System.Xml.XmlNode result = DeclaringType.HelpXml.SelectSingleNode ("/Type/Members/Member[@MemberName='" + Name + "']/Docs");
418 return result;
420 return null;
423 public abstract S AcceptVisitor<T, S> (IDomVisitor<T, S> visitor, T data);
425 public override bool Equals (object obj)
427 IMember m = obj as IMember;
428 if (m == null)
429 return false;
430 return this.Location == m.Location && this.FullName == m.FullName;
433 public override int GetHashCode ()
435 return this.Location.GetHashCode () ^ this.FullName.GetHashCode ();