⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 decl.cs

📁 C#编译器源代码。Micorsoft开放源代码
💻 CS
📖 第 1 页 / 共 4 页
字号:
//// decl.cs: Declaration base class for structs, classes, enums and interfaces.//// Author: Miguel de Icaza (miguel@gnu.org)//         Marek Safar (marek.safar@seznam.cz)//// Licensed under the terms of the GNU GPL//// (C) 2001 Ximian, Inc (http://www.ximian.com)// (C) 2004 Novell, Inc//// TODO: Move the method verification stuff from the class.cs and interface.cs here//using System;using System.Collections;using System.Globalization;using System.Reflection.Emit;using System.Reflection;#if BOOTSTRAP_WITH_OLDLIBusing XmlElement = System.Object;#elseusing System.Xml;#endifnamespace Mono.CSharp {	public class MemberName {		public readonly string Name;		public readonly MemberName Left;		public readonly Location Location;		bool is_double_colon;		public static readonly MemberName Null = new MemberName ("");		private MemberName (MemberName left, string name, bool is_double_colon, Location loc)		{			this.Name = name;			this.Location = loc;			this.is_double_colon = is_double_colon;			this.Left = left;		}		public MemberName (string name)			: this (null, name, false, Location.Null)		{		}		public MemberName (MemberName left, string name)			: this (left, name, false, left != null ? left.Location : Location.Null)		{		}		public MemberName (string name, Location loc)			: this (null, name, false, loc)		{		}		public MemberName (MemberName left, string name, Location loc)			: this (left, name, false, loc)		{		}		public MemberName (string alias, string name, Location loc)			: this (new MemberName (alias), name, true, loc)		{		}		public MemberName (MemberName left, MemberName right)			: this (left, right, right.Location)		{		}		public MemberName (MemberName left, MemberName right, Location loc)			: this (null, right.Name, false, loc)		{			if (right.is_double_colon)				throw new InternalErrorException ("Cannot append double_colon member name");			this.Left = (right.Left == null) ? left : new MemberName (left, right.Left);		}		static readonly char [] dot_array = { '.' };		public static MemberName FromDotted (string name)		{			string [] elements = name.Split (dot_array);			int count = elements.Length;			int i = 0;			MemberName n = new MemberName (elements [i++]);			while (i < count)				n = new MemberName (n, elements [i++]);			return n;		}		public string GetName ()		{			return GetName (false);		}		public string GetName (bool is_generic)		{			string name = is_generic ? Basename : Name;			string connect = is_double_colon ? "::" : ".";			if (Left != null)				return Left.GetName (is_generic) + connect + name;			else				return name;		}		///		/// This returns exclusively the name as seen on the source code		/// it is not the fully qualifed type after resolution		///		public string GetPartialName ()		{			string connect = is_double_colon ? "::" : ".";			if (Left != null)				return Left.GetPartialName () + connect + Name;			else				return Name;		}		public string GetTypeName ()		{			string connect = is_double_colon ? "::" : ".";			if (Left != null)				return Left.GetTypeName () + connect + Name;			else				return Name;		}		public Expression GetTypeExpression ()		{			if (Left == null)				return new SimpleName (Name, Location);			if (is_double_colon) {				if (Left.Left != null)					throw new InternalErrorException ("The left side of a :: should be an identifier");				return new QualifiedAliasMember (Left.Name, Name, Location);			}			Expression lexpr = Left.GetTypeExpression ();			return new MemberAccess (lexpr, Name, Location);		}		public MemberName Clone ()		{			MemberName left_clone = Left == null ? null : Left.Clone ();			return new MemberName (left_clone, Name, is_double_colon, Location);		}		public string Basename {			get { return Name; }		}		public override string ToString ()		{			string connect = is_double_colon ? "::" : ".";			if (Left != null)				return Left + connect + Name;			else				return Name;		}		public override bool Equals (object other)		{			return Equals (other as MemberName);		}		public bool Equals (MemberName other)		{			if (this == other)				return true;			if (other == null || Name != other.Name)				return false;			if (is_double_colon != other.is_double_colon)				return false;#if NET_2_0			if (TypeArguments == null)				return other.TypeArguments == null;			if (other.TypeArguments == null || TypeArguments.Count != other.TypeArguments.Count)				return false;#endif			if (Left == null)				return other.Left == null;			return Left.Equals (other.Left);		}		public override int GetHashCode ()		{			int hash = Name.GetHashCode ();			for (MemberName n = Left; n != null; n = n.Left)				hash ^= n.Name.GetHashCode ();			if (is_double_colon)				hash ^= 0xbadc01d;#if NET_2_0			if (TypeArguments != null)				hash ^= TypeArguments.Count << 5;#endif			return hash & 0x7FFFFFFF;		}	}	/// <summary>	///   Base representation for members.  This is used to keep track	///   of Name, Location and Modifier flags, and handling Attributes.	/// </summary>	public abstract class MemberCore : Attributable {		/// <summary>		///   Public name		/// </summary>		protected string cached_name;		public string Name {			get {				if (cached_name == null)					cached_name = MemberName.GetName (false);				return cached_name;			}		}                // Is not readonly because of IndexerName attribute		private MemberName member_name;		public MemberName MemberName {			get { return member_name; }		}		/// <summary>		///   Modifier flags that the user specified in the source code		/// </summary>		public int ModFlags;		public /*readonly*/ TypeContainer Parent;		/// <summary>		///   Location where this declaration happens		/// </summary>		public Location Location {			get { return member_name.Location; }		}		/// <summary>		///   XML documentation comment		/// </summary>		public string DocComment;		/// <summary>		///   Represents header string for documentation comment 		///   for each member types.		/// </summary>		public abstract string DocCommentHeader { get; }		[Flags]		public enum Flags {			Obsolete_Undetected = 1,		// Obsolete attribute has not been detected yet			Obsolete = 1 << 1,			// Type has obsolete attribute			ClsCompliance_Undetected = 1 << 2,	// CLS Compliance has not been detected yet			ClsCompliant = 1 << 3,			// Type is CLS Compliant			CloseTypeCreated = 1 << 4,		// Tracks whether we have Closed the type			HasCompliantAttribute_Undetected = 1 << 5,	// Presence of CLSCompliantAttribute has not been detected			HasClsCompliantAttribute = 1 << 6,			// Type has CLSCompliantAttribute			ClsCompliantAttributeTrue = 1 << 7,			// Type has CLSCompliant (true)			Excluded_Undetected = 1 << 8,		// Conditional attribute has not been detected yet			Excluded = 1 << 9,					// Method is conditional			TestMethodDuplication = 1 << 10,		// Test for duplication must be performed			IsUsed = 1 << 11,			IsAssigned = 1 << 12				// Field is assigned		}		/// <summary>		///   MemberCore flags at first detected then cached		/// </summary>		internal Flags caching_flags;		public MemberCore (TypeContainer parent, MemberName name, Attributes attrs)			: base (attrs)		{			if (parent is PartialContainer && !(this is PartialContainer))				throw new InternalErrorException ("A PartialContainer cannot be the direct parent of a member");			Parent = parent;			member_name = name;			caching_flags = Flags.Obsolete_Undetected | Flags.ClsCompliance_Undetected | Flags.HasCompliantAttribute_Undetected | Flags.Excluded_Undetected;		}		protected virtual void SetMemberName (MemberName new_name)		{			member_name = new_name;			cached_name = null;		}		public abstract bool Define ();		// 		// Returns full member name for error message		//		public virtual string GetSignatureForError ()		{			if (Parent == null || Parent.Parent == null)				return Name;			return String.Concat (Parent.GetSignatureForError (), '.', Name);		}		/// <summary>		/// Base Emit method. This is also entry point for CLS-Compliant verification.		/// </summary>		public virtual void Emit ()		{			if (!RootContext.VerifyClsCompliance)				return;			VerifyClsCompliance (Parent);		}		public virtual EmitContext EmitContext		{			get {				return Parent.EmitContext;			}		}		public bool InUnsafe {			get {				return ((ModFlags & Modifiers.UNSAFE) != 0) || Parent.UnsafeContext;			}		}		public virtual bool IsUsed {			get {				return (caching_flags & Flags.IsUsed) != 0;			}		}		public void SetMemberIsUsed ()		{			caching_flags |= Flags.IsUsed;		}		// 		// Whehter is it ok to use an unsafe pointer in this type container		//		public bool UnsafeOK (DeclSpace parent)		{			//			// First check if this MemberCore modifier flags has unsafe set			//			if ((ModFlags & Modifiers.UNSAFE) != 0)				return true;			if (parent.UnsafeContext)				return true;			Expression.UnsafeError (Location);			return false;		}		/// <summary>		/// Returns instance of ObsoleteAttribute for this MemberCore		/// </summary>		public virtual ObsoleteAttribute GetObsoleteAttribute ()		{			// ((flags & (Flags.Obsolete_Undetected | Flags.Obsolete)) == 0) is slower, but why ?			if ((caching_flags & Flags.Obsolete_Undetected) == 0 && (caching_flags & Flags.Obsolete) == 0) {				return null;			}			caching_flags &= ~Flags.Obsolete_Undetected;			if (OptAttributes == null)				return null;			Attribute obsolete_attr = OptAttributes.Search (				TypeManager.obsolete_attribute_type, EmitContext);			if (obsolete_attr == null)				return null;			ObsoleteAttribute obsolete = obsolete_attr.GetObsoleteAttribute (EmitContext);			if (obsolete == null)				return null;			caching_flags |= Flags.Obsolete;			return obsolete;		}		/// <summary>		/// Checks for ObsoleteAttribute presence. It's used for testing of all non-types elements		/// </summary>		public virtual void CheckObsoleteness (Location loc)		{			if (Parent != null)				Parent.CheckObsoleteness (loc);			ObsoleteAttribute oa = GetObsoleteAttribute ();			if (oa == null) {				return;			}			AttributeTester.Report_ObsoleteMessage (oa, GetSignatureForError (), loc);		}		protected void CheckObsoleteType (Expression type)		{			ObsoleteAttribute obsolete_attr = AttributeTester.GetObsoleteAttribute (type.Type);			if (obsolete_attr == null)				return;			if (GetObsoleteAttribute () != null || Parent.GetObsoleteAttribute () != null)				return;			AttributeTester.Report_ObsoleteMessage (obsolete_attr, TypeManager.CSharpName (type.Type), type.Location);		}		/// <summary>		/// Analyze whether CLS-Compliant verification must be execute for this MemberCore.		/// </summary>		public override bool IsClsCompliaceRequired (DeclSpace container)		{			if ((caching_flags & Flags.ClsCompliance_Undetected) == 0)				return (caching_flags & Flags.ClsCompliant) != 0;			if (GetClsCompliantAttributeValue (container) && IsExposedFromAssembly (container)) {				caching_flags &= ~Flags.ClsCompliance_Undetected;				caching_flags |= Flags.ClsCompliant;				return true;			}			caching_flags &= ~Flags.ClsCompliance_Undetected;			return false;		}		/// <summary>		/// Returns true when MemberCore is exposed from assembly.		/// </summary>		public bool IsExposedFromAssembly (DeclSpace ds)		{			if ((ModFlags & (Modifiers.PUBLIC | Modifiers.PROTECTED)) == 0)				return false;						DeclSpace parentContainer = ds;			while (parentContainer != null && parentContainer.ModFlags != 0) {				if ((parentContainer.ModFlags & (Modifiers.PUBLIC | Modifiers.PROTECTED)) == 0)					return false;				parentContainer = parentContainer.Parent;			}			return true;		}		/// <summary>		/// Resolve CLSCompliantAttribute value or gets cached value.		/// </summary>		bool GetClsCompliantAttributeValue (DeclSpace ds)		{			if (OptAttributes != null) {				Attribute cls_attribute = OptAttributes.Search (					TypeManager.cls_compliant_attribute_type, ds.EmitContext);				if (cls_attribute != null) {					caching_flags |= Flags.HasClsCompliantAttribute;					return cls_attribute.GetClsCompliantAttributeValue (ds.EmitContext);				}			}			return ds.GetClsCompliantAttributeValue ();		}		/// <summary>		/// Returns true if MemberCore is explicitly marked with CLSCompliantAttribute		/// </summary>		protected bool HasClsCompliantAttribute {			get {				return (caching_flags & Flags.HasClsCompliantAttribute) != 0;			}		}		/// <summary>		/// It helps to handle error 102 & 111 detection		/// </summary>		public virtual bool MarkForDuplicationCheck ()		{			return false;		}		/// <summary>		/// The main virtual method for CLS-Compliant verifications.		/// The method returns true if member is CLS-Compliant and false if member is not		/// CLS-Compliant which means that CLS-Compliant tests are not necessary. A descendants override it		/// and add their extra verifications.		/// </summary>		protected virtual bool VerifyClsCompliance (DeclSpace ds)		{			if (!IsClsCompliaceRequired (ds)) {				if (HasClsCompliantAttribute && RootContext.WarningLevel >= 2) {					if (!IsExposedFromAssembly (ds))						Report.Warning (3019, Location, "CLS compliance checking will not be performed on `{0}' because it is not visible from outside this assembly", GetSignatureForError ());					if (!CodeGen.Assembly.IsClsCompliant)						Report.Warning (3021, Location, "`{0}' does not need a CLSCompliant attribute because the assembly is not marked as CLS-compliant", GetSignatureForError ());				}				return false;			}			if (!CodeGen.Assembly.IsClsCompliant) {				if (HasClsCompliantAttribute) {					Report.Error (3014, Location,						"`{0}' cannot be marked as CLS-compliant because the assembly is not marked as CLS-compliant",						GetSignatureForError ());				}				return false;			}			if (member_name.Name [0] == '_') {				Report.Error (3008, Location, "Identifier `{0}' is not CLS-compliant", GetSignatureForError () );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -