#develop (short for SharpDevelop) is a free IDE for .NET programming languages.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

342 lines
7.4 KiB

// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.Generic;
namespace ICSharpCode.SharpDevelop.Dom
{
public abstract class AbstractEntity : AbstractFreezable, IEntity
{
ModifierEnum modifiers = ModifierEnum.None;
IList<IAttribute> attributes;
DomRegion bodyRegion;
IClass declaringType;
string fullyQualifiedName = null;
string name = null;
string nspace = null;
public AbstractEntity(IClass declaringType)
{
this.declaringType = declaringType;
}
public AbstractEntity(IClass declaringType, string name)
{
if (declaringType == null)
throw new ArgumentNullException("declaringType");
this.declaringType = declaringType;
this.name = name;
nspace = declaringType.FullyQualifiedName;
// lazy-computing the fully qualified name for class members saves ~7 MB RAM (when loading the SharpDevelop solution).
//fullyQualifiedName = nspace + '.' + name;
}
public override string ToString()
{
return String.Format("[{0}: {1}]", GetType().Name, FullyQualifiedName);
}
#region Naming
static readonly char[] nameDelimiters = { '.', '+' };
public string FullyQualifiedName {
get {
if (fullyQualifiedName == null) {
if (name != null && nspace != null) {
fullyQualifiedName = nspace + '.' + name;
} else {
return String.Empty;
}
}
return fullyQualifiedName;
}
set {
CheckBeforeMutation();
if (fullyQualifiedName == value)
return;
fullyQualifiedName = value;
name = null;
nspace = null;
OnFullyQualifiedNameChanged(EventArgs.Empty);
}
}
protected virtual void OnFullyQualifiedNameChanged(EventArgs e)
{
}
public virtual string DotNetName {
get {
if (this.DeclaringType != null) {
return this.DeclaringType.DotNetName + "." + this.Name;
} else {
return FullyQualifiedName;
}
}
}
public string Name {
get {
if (name == null && FullyQualifiedName != null) {
int lastIndex = FullyQualifiedName.LastIndexOfAny(nameDelimiters);
if (lastIndex < 0) {
name = FullyQualifiedName;
} else {
name = FullyQualifiedName.Substring(lastIndex + 1);
}
}
return name;
}
}
public string Namespace {
get {
if (nspace == null && FullyQualifiedName != null) {
int lastIndex = FullyQualifiedName.LastIndexOf('.');
if (lastIndex < 0) {
nspace = String.Empty;
} else {
nspace = FullyQualifiedName.Substring(0, lastIndex);
}
}
return nspace;
}
}
#endregion
protected override void FreezeInternal()
{
attributes = FreezeList(attributes);
base.FreezeInternal();
}
public IClass DeclaringType {
get {
return declaringType;
}
}
public virtual DomRegion BodyRegion {
get {
return bodyRegion;
}
set {
CheckBeforeMutation();
bodyRegion = value;
}
}
public object UserData { get; set; }
public IList<IAttribute> Attributes {
get {
if (attributes == null) {
attributes = new List<IAttribute>();
}
return attributes;
}
set {
CheckBeforeMutation();
attributes = value;
}
}
string documentation;
public string Documentation {
get {
if (documentation == null) {
string documentationTag = this.DocumentationTag;
if (documentationTag != null) {
IProjectContent pc = null;
if (this is IClass) {
pc = ((IClass)this).ProjectContent;
} else if (declaringType != null) {
pc = declaringType.ProjectContent;
}
if (pc != null) {
return pc.GetXmlDocumentation(documentationTag);
}
}
}
return documentation;
}
set {
CheckBeforeMutation();
documentation = value;
}
}
public abstract string DocumentationTag {
get;
}
#region Modifiers
public ModifierEnum Modifiers {
get {
return modifiers;
}
set {
CheckBeforeMutation();
modifiers = value;
}
}
public bool IsAbstract {
get {
return (modifiers & ModifierEnum.Abstract) == ModifierEnum.Abstract;
}
}
public bool IsSealed {
get {
return (modifiers & ModifierEnum.Sealed) == ModifierEnum.Sealed;
}
}
public bool IsStatic {
get {
return ((modifiers & ModifierEnum.Static) == ModifierEnum.Static) || IsConst;
}
}
public bool IsConst {
get {
return (modifiers & ModifierEnum.Const) == ModifierEnum.Const;
}
}
public bool IsVirtual {
get {
return (modifiers & ModifierEnum.Virtual) == ModifierEnum.Virtual;
}
}
public bool IsPublic {
get {
return (modifiers & ModifierEnum.Public) == ModifierEnum.Public;
}
}
public bool IsProtected {
get {
return (modifiers & ModifierEnum.Protected) == ModifierEnum.Protected;
}
}
public bool IsPrivate {
get {
return (modifiers & ModifierEnum.Private) == ModifierEnum.Private;
}
}
public bool IsInternal {
get {
return (modifiers & ModifierEnum.Internal) == ModifierEnum.Internal;
}
}
public bool IsProtectedAndInternal {
get {
return (modifiers & (ModifierEnum.Internal | ModifierEnum.Protected)) == (ModifierEnum.Internal | ModifierEnum.Protected);
}
}
public bool IsProtectedOrInternal {
get {
return IsProtected || IsInternal;
}
}
public bool IsReadonly {
get {
return (modifiers & ModifierEnum.Readonly) == ModifierEnum.Readonly;
}
}
public bool IsOverride {
get {
return (modifiers & ModifierEnum.Override) == ModifierEnum.Override;
}
}
public bool IsOverridable {
get {
return (IsOverride || IsVirtual || IsAbstract) && !IsSealed;
}
}
public bool IsNew {
get {
return (modifiers & ModifierEnum.New) == ModifierEnum.New;
}
}
public bool IsSynthetic {
get {
return (modifiers & ModifierEnum.Synthetic) == ModifierEnum.Synthetic;
}
}
#endregion
bool IsInnerClass(IClass c, IClass possibleInnerClass)
{
foreach (IClass inner in c.InnerClasses) {
if (inner.FullyQualifiedName == possibleInnerClass.FullyQualifiedName) {
return true;
}
if (IsInnerClass(inner, possibleInnerClass)) {
return true;
}
}
return false;
}
// TODO: check inner classes for protected members too.
public bool IsAccessible(IClass callingClass, bool isClassInInheritanceTree)
{
if (IsInternal) {
return true;
}
if (IsPublic) {
return true;
}
if (isClassInInheritanceTree && IsProtected) {
return true;
}
return callingClass != null && (DeclaringType.FullyQualifiedName == callingClass.FullyQualifiedName || IsInnerClass(DeclaringType, callingClass));
}
public bool MustBeShown(IClass callingClass, bool showStatic, bool isClassInInheritanceTree)
{
if (DeclaringType.ClassType == ClassType.Enum) {
return true;
}
if (!showStatic && IsStatic || (showStatic && !(IsStatic || IsConst))) { // const is automatically static
return false;
}
return IsAccessible(callingClass, isClassInInheritanceTree);
}
public virtual int CompareTo(IEntity value)
{
return this.Modifiers - value.Modifiers;
}
int IComparable.CompareTo(object value)
{
return CompareTo((IEntity)value);
}
}
}