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

📄 class.cs

📁 C#编译器源代码。Micorsoft开放源代码
💻 CS
📖 第 1 页 / 共 5 页
字号:
//// class.cs: Class and Struct handlers//// Authors: Miguel de Icaza (miguel@gnu.org)//          Martin Baulig (martin@ximian.com)//          Marek Safar (marek.safar@seznam.cz)//// Licensed under the terms of the GNU GPL//// (C) 2001, 2002, 2003 Ximian, Inc (http://www.ximian.com)// (C) 2004 Novell, Inc//////  2002-10-11  Miguel de Icaza  <miguel@ximian.com>////	* class.cs: Following the comment from 2002-09-26 to AddMethod, I//	have fixed a remaining problem: not every AddXXXX was adding a//	fully qualified name.  ////	Now everyone registers a fully qualified name in the DeclSpace as//	being defined instead of the partial name.  ////	Downsides: we are slower than we need to be due to the excess//	copies and the names being registered this way.  ////	The reason for this is that we currently depend (on the corlib//	bootstrap for instance) that types are fully qualified, because//	we dump all the types in the namespace, and we should really have//	types inserted into the proper namespace, so we can only store the//	basenames in the defined_names array.////#define CACHEusing System;using System.Collections;using System.Collections.Specialized;using System.Reflection;using System.Reflection.Emit;using System.Runtime.CompilerServices;using System.Runtime.InteropServices;using System.Security;using System.Security.Permissions;using System.Text;#if BOOTSTRAP_WITH_OLDLIBusing XmlElement = System.Object;#elseusing System.Xml;#endifusing Mono.CompilerServices.SymbolWriter;namespace Mono.CSharp {	public enum Kind {		Root,		Struct,		Class,		Interface	}	/// <summary>	///   This is the base class for structs and classes.  	/// </summary>	public abstract class TypeContainer : DeclSpace, IMemberContainer { 		public class MemberCoreArrayList: ArrayList 		{			/// <summary>			///   Defines the MemberCore objects that are in this array			/// </summary>			public virtual void DefineContainerMembers ()			{				foreach (MemberCore mc in this) {					mc.Define ();				}			}			public virtual void Emit ()			{				foreach (MemberCore mc in this)					mc.Emit ();			} 		} 		public class MethodArrayList : MemberCoreArrayList 		{ 			[Flags] 			enum CachedMethods { 				Equals			= 1, 				GetHashCode		= 1 << 1 			}  			CachedMethods cached_method;			TypeContainer container;			public MethodArrayList (TypeContainer container)			{				this.container = container;			}  			/// <summary> 			/// Method container contains Equals method 			/// </summary> 			public bool HasEquals { 				set { 					cached_method |= CachedMethods.Equals; 				}  				get { 					return (cached_method & CachedMethods.Equals) != 0; 				} 			}  			/// <summary> 			/// Method container contains GetHashCode method 			/// </summary> 			public bool HasGetHashCode { 				set { 					cached_method |= CachedMethods.GetHashCode; 				}  				get { 					return (cached_method & CachedMethods.GetHashCode) != 0; 				} 			}  			public override void DefineContainerMembers () 			{ 				base.DefineContainerMembers ();  				if ((RootContext.WarningLevel >= 3) && HasEquals && !HasGetHashCode) { 					Report.Warning (659, container.Location, "`{0}' overrides Object.Equals(object) but does not override Object.GetHashCode()", container.GetSignatureForError ()); 				} 			}  		}		public sealed class IndexerArrayList : MemberCoreArrayList		{			/// <summary>			/// The indexer name for this container			/// </summary> 			public string IndexerName = DefaultIndexerName;			bool seen_normal_indexers = false;			TypeContainer container;			public IndexerArrayList (TypeContainer container)			{				this.container = container;			}			/// <summary>			/// Defines the indexers, and also verifies that the IndexerNameAttribute in the			/// class is consistent.  Either it is `Item' or it is the name defined by all the			/// indexers with the `IndexerName' attribute.			///			/// Turns out that the IndexerNameAttribute is applied to each indexer,			/// but it is never emitted, instead a DefaultMember attribute is attached			/// to the class.			/// </summary>			public override void DefineContainerMembers()			{				base.DefineContainerMembers ();				string class_indexer_name = null;				//				// If there's both an explicit and an implicit interface implementation, the				// explicit one actually implements the interface while the other one is just				// a normal indexer.  See bug #37714.				//				// Invariant maintained by AddIndexer(): All explicit interface indexers precede normal indexers				foreach (Indexer i in this) {					if (i.InterfaceType != null) {						if (seen_normal_indexers)							throw new Exception ("Internal Error: 'Indexers' array not sorted properly.");						continue;					}					seen_normal_indexers = true;					if (class_indexer_name == null) {						class_indexer_name = i.ShortName;						continue;					}					if (i.ShortName != class_indexer_name)						Report.Error (668, i.Location, "Two indexers have different names; the IndexerName attribute must be used with the same name on every indexer within a type");				}				if (class_indexer_name != null)					IndexerName = class_indexer_name;			}			public override void Emit ()			{				base.Emit ();				if (!seen_normal_indexers)					return;				CustomAttributeBuilder cb = new CustomAttributeBuilder (TypeManager.default_member_ctor, new string [] { IndexerName });				container.TypeBuilder.SetCustomAttribute (cb);			}		} 		public class OperatorArrayList: MemberCoreArrayList		{			TypeContainer container;			public OperatorArrayList (TypeContainer container)			{				this.container = container;			}			//			// Operator pair checking			//			class OperatorEntry			{				public int flags;				public Type ret_type;				public Type type1, type2;				public Operator op;				public Operator.OpType ot;								public OperatorEntry (int f, Operator o)				{					flags = f;					ret_type = o.OperatorMethod.ReturnType;					Type [] pt = o.OperatorMethod.ParameterTypes;					type1 = pt [0];					type2 = pt [1];					op = o;					ot = o.OperatorType;				}				public override int GetHashCode ()				{						return ret_type.GetHashCode ();				}				public override bool Equals (object o)				{					OperatorEntry other = (OperatorEntry) o;					if (other.ret_type != ret_type)						return false;					if (other.type1 != type1)						return false;					if (other.type2 != type2)						return false;					return true;				}			}							//			// Checks that some operators come in pairs:			//  == and !=			// > and <			// >= and <=			// true and false			//			// They are matched based on the return type and the argument types			//			void CheckPairedOperators ()			{				IDictionary pairs = new HybridDictionary ();				Operator true_op = null;				Operator false_op = null;				bool has_equality_or_inequality = false;								// Register all the operators we care about.				foreach (Operator op in this){					int reg = 0;					// Skip erroneous code.					if (op.OperatorMethod == null)						continue;					switch (op.OperatorType){					case Operator.OpType.Equality:						reg = 1;						has_equality_or_inequality = true;						break;					case Operator.OpType.Inequality:						reg = 2;						has_equality_or_inequality = true;						break;					case Operator.OpType.True:						true_op = op;						break;					case Operator.OpType.False:						false_op = op;						break;											case Operator.OpType.GreaterThan:						reg = 1; break;					case Operator.OpType.LessThan:						reg = 2; break;											case Operator.OpType.GreaterThanOrEqual:						reg = 1; break;					case Operator.OpType.LessThanOrEqual:						reg = 2; break;					}					if (reg == 0)						continue;					OperatorEntry oe = new OperatorEntry (reg, op);					object o = pairs [oe];					if (o == null)						pairs [oe] = oe;					else {						oe = (OperatorEntry) o;						oe.flags |= reg;					}				}				if (true_op != null){					if (false_op == null)						Report.Error (216, true_op.Location, "The operator `{0}' requires a matching operator `false' to also be defined",							true_op.GetSignatureForError ());				} else if (false_op != null)					Report.Error (216, false_op.Location, "The operator `{0}' requires a matching operator `true' to also be defined",						false_op.GetSignatureForError ());								//				// Look for the mistakes.				//				foreach (DictionaryEntry de in pairs){					OperatorEntry oe = (OperatorEntry) de.Key;					if (oe.flags == 3)						continue;					string s = "";					switch (oe.ot){					case Operator.OpType.Equality:						s = "!=";						break;					case Operator.OpType.Inequality: 						s = "==";						break;					case Operator.OpType.GreaterThan: 						s = "<";						break;					case Operator.OpType.LessThan:						s = ">";						break;					case Operator.OpType.GreaterThanOrEqual:						s = "<=";						break;					case Operator.OpType.LessThanOrEqual:						s = ">=";						break;					}					Report.Error (216, oe.op.Location,						"The operator `{0}' requires a matching operator `{1}' to also be defined",						oe.op.GetSignatureForError (), s);				} 				if (has_equality_or_inequality && (RootContext.WarningLevel > 2)) { 					if (container.Methods == null || !container.Methods.HasEquals) 						Report.Warning (660, container.Location, "`{0}' defines operator == or operator != but does not override Object.Equals(object o)", container.GetSignatureForError ());  					if (container.Methods == null || !container.Methods.HasGetHashCode) 						Report.Warning (661, container.Location, "`{0}' defines operator == or operator != but does not override Object.GetHashCode()", container.GetSignatureForError ()); 				}			}	 		public override void DefineContainerMembers ()	 		{	 			base.DefineContainerMembers ();	 			CheckPairedOperators ();			}		}		// Whether this is a struct, class or interface		public readonly Kind Kind;		// Holds a list of classes and structures		ArrayList types;		// Holds the list of properties		MemberCoreArrayList properties;		// Holds the list of enumerations		MemberCoreArrayList enums;		// Holds the list of delegates		MemberCoreArrayList delegates;				// Holds the list of constructors		protected MemberCoreArrayList instance_constructors;		// Holds the list of fields		MemberCoreArrayList fields;		// Holds a list of fields that have initializers		protected ArrayList initialized_fields;		// Holds a list of static fields that have initializers		protected ArrayList initialized_static_fields;		// Holds the list of constants		MemberCoreArrayList constants;		// Holds the list of		MemberCoreArrayList interfaces;		// Holds the methods.		MethodArrayList methods;		// Holds the events		protected MemberCoreArrayList events;		// Holds the indexers		IndexerArrayList indexers;		// Holds the operators		MemberCoreArrayList operators;		// Holds the iterators		ArrayList iterators;		// Holds the parts of a partial class;		ArrayList parts;		//		// Pointers to the default constructor and the default static constructor		//		protected Constructor default_constructor;		protected Constructor default_static_constructor;		//		// Points to the first non-static field added to the container.		//		// This is an arbitrary choice.  We are interested in looking at _some_ non-static field,		// and the first one's as good as any.		//		FieldBase first_nonstatic_field = null;		//		// This one is computed after we can distinguish interfaces		// from classes from the arraylist `type_bases' 		//		string base_class_name;		TypeExpr base_type;		TypeExpr[] iface_exprs;		ArrayList type_bases;		bool members_defined;		bool members_defined_ok;		// The interfaces we implement.		protected Type[] ifaces;		protected Type ptype;		// The base member cache and our member cache		MemberCache base_cache;		MemberCache member_cache;		public const string DefaultIndexerName = "Item";		public TypeContainer (NamespaceEntry ns, TypeContainer parent, MemberName name,				      Attributes attrs, Kind kind)			: base (ns, parent, name, attrs)		{			if (parent != null && parent != RootContext.Tree.Types && parent.NamespaceEntry != ns)				throw new InternalErrorException ("A nested type should be in the same NamespaceEntry as its enclosing class");			this.Kind = kind;			types = new ArrayList ();			base_class_name = null;		}		public bool AddToMemberContainer (MemberCore symbol)		{			return AddToContainer (symbol, symbol.Name);		}		protected virtual bool AddToTypeContainer (DeclSpace ds)		{			return AddToContainer (ds, ds.Basename);		}		public void AddConstant (Const constant)		{			if (!AddToMemberContainer (constant))				return;			if (constants == null)				constants = new MemberCoreArrayList ();						constants.Add (constant);		}		public void AddEnum (Mono.CSharp.Enum e)		{			if (!AddToTypeContainer (e))				return;			if (enums == null)				enums = new MemberCoreArrayList ();			enums.Add (e);		}		

⌨️ 快捷键说明

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