5 // Mike Krüger <mkrueger@novell.com>
7 // Copyright (C) 2008 Novell, Inc (http://www.novell.com)
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:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
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.
30 using System
.Collections
.Generic
;
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
{
48 this.declaringType
= value;
49 fullNameIsDirty
= true;
54 public virtual string FullName
{
56 if (fullNameIsDirty
) {
57 fullName
= CalculateFullName ();
58 fullNameIsDirty
= false;
64 protected bool fullNameIsDirty
= true;
65 protected virtual string CalculateFullName ()
67 return DeclaringType
!= null ? DeclaringType
.FullName
+ "." + Name
: Name
;
70 public virtual IReturnType ReturnType
{
79 public IEnumerable
<IReturnType
> ExplicitInterfaces
{
81 return (IEnumerable
<IReturnType
>)explicitInterfaces
?? new IReturnType
[0];
85 public bool IsExplicitDeclaration
{
87 return explicitInterfaces
!= null && explicitInterfaces
.Count
> 0;
91 protected string name
;
92 public virtual string Name
{
98 fullNameIsDirty
= true;
102 public virtual string Documentation
{
107 public virtual DomLocation Location
{
112 public virtual DomRegion BodyRegion
{
117 public virtual Modifiers Modifiers
{
122 public virtual bool IsObsolete
{
124 foreach (IAttribute attr
in Attributes
) {
126 case "System.Obsolete":
127 case "System.ObsoleteAttribute":
129 case "ObsoleteAttribute":
137 List
<IAttribute
> attributes
= null;
138 static readonly IAttribute
[] emptyAttributes
= new IAttribute
[0];
139 public virtual IEnumerable
<IAttribute
> Attributes
{
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)
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)
169 foreach (IAttribute attribute
in attributes
) {
175 /// This method is used to look up special methods that are connected to
176 /// the member (like set/get method for events).
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.
183 /// A <see cref="IMethod"/> when the special method is found, null otherwise.
185 protected IMethod
LookupSpecialMethod (string prefix
)
187 if (DeclaringType
== null)
189 string specialMethodName
= prefix
+ Name
;
190 foreach (IMethod method
in DeclaringType
.Methods
) {
191 if (method
.IsSpecialName
&& method
.Name
== specialMethodName
)
197 public abstract string HelpUrl
{
201 public abstract string StockIcon
{
206 /// Help method used for getting the right icon for a member.
208 /// <param name="modifier">
209 /// A <see cref="Modifiers"/>
212 /// A <see cref="System.Int32"/>
214 protected static int ModifierToOffset (Modifiers modifier
)
216 if ((modifier
& Modifiers
.Private
) == Modifiers
.Private
)
218 if ((modifier
& Modifiers
.Protected
) == Modifiers
.Protected
)
220 if ((modifier
& Modifiers
.Internal
) == Modifiers
.Internal
)
224 // Dictionary<string, bool> protectedTable = new Dictionary<string, bool> ();
225 public virtual bool IsAccessibleFrom (ProjectDom dom
, IType calledType
, IMember member
, bool includeProtected
)
228 return IsStatic
|| IsPublic
;
229 // if (member.IsStatic && !IsStatic)
231 if (IsPublic
|| calledType
!= null && calledType
.ClassType
== ClassType
.Interface
)
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
)
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;
246 if (!(member
is IType
) && (member
.DeclaringType
== null || DeclaringType
== null))
251 /* foreach (IType type in dom.GetInheritanceTree (calledType)) {
252 if (type.FullName == member.DeclaringType.FullName) {
253 protectedTable[protectedTableKey] = true;
257 return includeProtected
;
260 IType declaringType
= member
.DeclaringType
;
261 while (declaringType
!= null) {
262 if (declaringType
.Equals (DeclaringType
))
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
)
276 return Name
.CompareTo (((IMember
)obj
).Name
);
280 #region ModifierAccessors
281 public bool IsPrivate
{
283 return (this.Modifiers
& Modifiers
.Private
) == Modifiers
.Private
;
286 public bool IsInternal
{
288 return (this.Modifiers
& Modifiers
.Internal
) == Modifiers
.Internal
;
291 public bool IsProtected
{
293 return (this.Modifiers
& Modifiers
.Protected
) == Modifiers
.Protected
;
296 public bool IsPublic
{
298 return (this.Modifiers
& Modifiers
.Public
) == Modifiers
.Public
;
301 public bool IsProtectedAndInternal
{
303 return (this.Modifiers
& Modifiers
.ProtectedAndInternal
) == Modifiers
.ProtectedAndInternal
;
306 public bool IsProtectedOrInternal
{
308 return (this.Modifiers
& Modifiers
.ProtectedOrInternal
) == Modifiers
.ProtectedOrInternal
;
312 public bool IsAbstract
{
314 return (this.Modifiers
& Modifiers
.Abstract
) == Modifiers
.Abstract
;
317 public bool IsVirtual
{
319 return (this.Modifiers
& Modifiers
.Virtual
) == Modifiers
.Virtual
;
322 public bool IsSealed
{
324 return (this.Modifiers
& Modifiers
.Sealed
) == Modifiers
.Sealed
;
327 public bool IsStatic
{
329 return (this.Modifiers
& Modifiers
.Static
) == Modifiers
.Static
;
332 public bool IsOverride
{
334 return (this.Modifiers
& Modifiers
.Override
) == Modifiers
.Override
;
337 public bool IsReadonly
{
339 return (this.Modifiers
& Modifiers
.Readonly
) == Modifiers
.Readonly
;
342 public bool IsConst
{
344 return (this.Modifiers
& Modifiers
.Const
) == Modifiers
.Const
;
349 return (this.Modifiers
& Modifiers
.New
) == Modifiers
.New
;
352 public bool IsPartial
{
354 return (this.Modifiers
& Modifiers
.Partial
) == Modifiers
.Partial
;
358 public bool IsExtern
{
360 return (this.Modifiers
& Modifiers
.Extern
) == Modifiers
.Extern
;
363 public bool IsVolatile
{
365 return (this.Modifiers
& Modifiers
.Volatile
) == Modifiers
.Volatile
;
368 public bool IsUnsafe
{
370 return (this.Modifiers
& Modifiers
.Unsafe
) == Modifiers
.Unsafe
;
373 public bool IsOverloads
{
375 return (this.Modifiers
& Modifiers
.Overloads
) == Modifiers
.Overloads
;
378 public bool IsWithEvents
{
380 return (this.Modifiers
& Modifiers
.WithEvents
) == Modifiers
.WithEvents
;
383 public bool IsDefault
{
385 return (this.Modifiers
& Modifiers
.Default
) == Modifiers
.Default
;
388 public bool IsFixed
{
390 return (this.Modifiers
& Modifiers
.Fixed
) == Modifiers
.Fixed
;
394 public bool IsSpecialName
{
396 return (this.Modifiers
& Modifiers
.SpecialName
) == Modifiers
.SpecialName
;
399 public bool IsFinal
{
401 return (this.Modifiers
& Modifiers
.Final
) == Modifiers
.Final
;
404 public bool IsLiteral
{
406 return (this.Modifiers
& Modifiers
.Literal
) == Modifiers
.Literal
;
411 public virtual System
.Xml
.XmlNode
GetMonodocDocumentation ()
413 if (DeclaringType
== null)
416 if (DeclaringType
.HelpXml
!= null) {
417 System
.Xml
.XmlNode result
= DeclaringType
.HelpXml
.SelectSingleNode ("/Type/Members/Member[@MemberName='" + Name
+ "']/Docs");
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
;
430 return this.Location
== m
.Location
&& this.FullName
== m
.FullName
;
433 public override int GetHashCode ()
435 return this.Location
.GetHashCode () ^
this.FullName
.GetHashCode ();