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

📄 attribute.cs

📁 C#编译器源代码。Micorsoft开放源代码
💻 CS
📖 第 1 页 / 共 4 页
字号:
		public void AddAttributes (ArrayList attrs)		{			Attrs.AddRange (attrs);		}		/// <summary>		/// Checks whether attribute target is valid for the current element		/// </summary>		public bool CheckTargets (Attributable member)		{			string[] valid_targets = member.ValidAttributeTargets;			foreach (Attribute a in Attrs) {				if (a.ExplicitTarget == null || a.ExplicitTarget == valid_targets [0]) {					a.Target = member.AttributeTargets;					continue;				}				// TODO: we can skip the first item				if (((IList) valid_targets).Contains (a.ExplicitTarget)) {					switch (a.ExplicitTarget) {					case "return": a.Target = AttributeTargets.ReturnValue; continue;					case "param": a.Target = AttributeTargets.Parameter; continue;					case "field": a.Target = AttributeTargets.Field; continue;					case "method": a.Target = AttributeTargets.Method; continue;					case "property": a.Target = AttributeTargets.Property; continue;					}					throw new InternalErrorException ("Unknown explicit target: " + a.ExplicitTarget);				}								StringBuilder sb = new StringBuilder ();				foreach (string s in valid_targets) {					sb.Append (s);					sb.Append (", ");				}				sb.Remove (sb.Length - 2, 2);				Report.Error (657, a.Location, "`{0}' is not a valid attribute location for this declaration. " +					      "Valid attribute locations for this declaration are `{1}'", a.ExplicitTarget, sb.ToString ());				return false;			}			return true;		}		public Attribute Search (Type t, EmitContext ec)		{			foreach (Attribute a in Attrs) {				if (a.ResolveType (ec) == t)					return a;			}			return null;		}		/// <summary>		/// Returns all attributes of type 't'. Use it when attribute is AllowMultiple = true		/// </summary>		public Attribute[] SearchMulti (Type t, EmitContext ec)		{			ArrayList ar = null;			foreach (Attribute a in Attrs) {				if (a.ResolveType (ec) == t) {					if (ar == null)						ar = new ArrayList ();					ar.Add (a);				}			}			return ar == null ? null : ar.ToArray (typeof (Attribute)) as Attribute[];		}		public void Emit (EmitContext ec, Attributable ias)		{			CheckTargets (ias);			ListDictionary ld = new ListDictionary ();			foreach (Attribute a in Attrs)				a.Emit (ec, ias, ld);		}		public bool Contains (Type t, EmitContext ec)		{                        return Search (t, ec) != null;		}	}	/// <summary>	/// Helper class for attribute verification routine.	/// </summary>	sealed class AttributeTester	{		static PtrHashtable analyzed_types = new PtrHashtable ();		static PtrHashtable analyzed_types_obsolete = new PtrHashtable ();		static PtrHashtable analyzed_member_obsolete = new PtrHashtable ();		static PtrHashtable analyzed_method_excluded = new PtrHashtable ();#if NET_2_0		static PtrHashtable fixed_buffer_cache = new PtrHashtable ();#endif		static object TRUE = new object ();		static object FALSE = new object ();		private AttributeTester ()		{		}		public enum Result {			Ok,			RefOutArrayError,			ArrayArrayError		}		/// <summary>		/// Returns true if parameters of two compared methods are CLS-Compliant.		/// It tests differing only in ref or out, or in array rank.		/// </summary>		public static Result AreOverloadedMethodParamsClsCompliant (Type[] types_a, Type[] types_b) 		{			if (types_a == null || types_b == null)				return Result.Ok;			if (types_a.Length != types_b.Length)				return Result.Ok;			Result result = Result.Ok;			for (int i = 0; i < types_b.Length; ++i) {				Type aType = types_a [i];				Type bType = types_b [i];				if (aType.IsArray && bType.IsArray) {					Type a_el_type = aType.GetElementType ();					Type b_el_type = bType.GetElementType ();					if (aType.GetArrayRank () != bType.GetArrayRank () && a_el_type == b_el_type) {						result = Result.RefOutArrayError;						continue;					}					if (a_el_type.IsArray || b_el_type.IsArray) {						result = Result.ArrayArrayError;						continue;					}				}				Type aBaseType = aType;				bool is_either_ref_or_out = false;				if (aType.IsByRef || aType.IsPointer) {					aBaseType = aType.GetElementType ();					is_either_ref_or_out = true;				}				Type bBaseType = bType;				if (bType.IsByRef || bType.IsPointer) 				{					bBaseType = bType.GetElementType ();					is_either_ref_or_out = !is_either_ref_or_out;				}				if (aBaseType != bBaseType)					return Result.Ok;				if (is_either_ref_or_out)					result = Result.RefOutArrayError;			}			return result;		}		/// <summary>		/// Goes through all parameters and test if they are CLS-Compliant.		/// </summary>		public static bool AreParametersCompliant (Parameter[] fixedParameters, Location loc)		{			if (fixedParameters == null)				return true;			foreach (Parameter arg in fixedParameters) {				if (!AttributeTester.IsClsCompliant (arg.ParameterType)) {					Report.Error (3001, loc, "Argument type `{0}' is not CLS-compliant", arg.GetSignatureForError ());					return false;				}			}			return true;		}		/// <summary>		/// This method tests the CLS compliance of external types. It doesn't test type visibility.		/// </summary>		public static bool IsClsCompliant (Type type) 		{			if (type == null)				return true;			object type_compliance = analyzed_types[type];			if (type_compliance != null)				return type_compliance == TRUE;			if (type.IsPointer) {				analyzed_types.Add (type, null);				return false;			}			bool result;			if (type.IsArray || type.IsByRef)	{				result = IsClsCompliant (TypeManager.GetElementType (type));			} else {				result = AnalyzeTypeCompliance (type);			}			analyzed_types.Add (type, result ? TRUE : FALSE);			return result;		}                		/// <summary>		/// Returns IFixedBuffer implementation if field is fixed buffer else null.		/// </summary>		public static IFixedBuffer GetFixedBuffer (FieldInfo fi)		{			FieldBase fb = TypeManager.GetField (fi);			if (fb != null) {				return fb as IFixedBuffer;			}#if NET_2_0			object o = fixed_buffer_cache [fi];			if (o == null) {				if (System.Attribute.GetCustomAttribute (fi, TypeManager.fixed_buffer_attr_type) == null) {					fixed_buffer_cache.Add (fi, FALSE);					return null;				}								IFixedBuffer iff = new FixedFieldExternal (fi);				fixed_buffer_cache.Add (fi, iff);				return iff;			}			if (o == FALSE)				return null;			return (IFixedBuffer)o;#else			return null;#endif		}		public static void VerifyModulesClsCompliance ()		{			Module[] modules = RootNamespace.Global.Modules;			if (modules == null)				return;			// The first module is generated assembly			for (int i = 1; i < modules.Length; ++i) {				Module module = modules [i];				if (!IsClsCompliant (module)) {					Report.Error (3013, "Added modules must be marked with the CLSCompliant attribute " +						      "to match the assembly", module.Name);					return;				}			}		}		public static Type GetImportedIgnoreCaseClsType (string name)		{			foreach (Assembly a in RootNamespace.Global.Assemblies) {				Type t = a.GetType (name, false, true);				if (t == null)					continue;				if (IsClsCompliant (t))					return t;			}			return null;		}		static bool IsClsCompliant (ICustomAttributeProvider attribute_provider) 		{			object[] CompliantAttribute = attribute_provider.GetCustomAttributes (TypeManager.cls_compliant_attribute_type, false);			if (CompliantAttribute.Length == 0)				return false;			return ((CLSCompliantAttribute)CompliantAttribute[0]).IsCompliant;		}		static bool AnalyzeTypeCompliance (Type type)		{			DeclSpace ds = TypeManager.LookupDeclSpace (type);			if (ds != null) {				return ds.IsClsCompliaceRequired (ds.Parent);			}			object[] CompliantAttribute = type.GetCustomAttributes (TypeManager.cls_compliant_attribute_type, false);			if (CompliantAttribute.Length == 0) 				return IsClsCompliant (type.Assembly);			return ((CLSCompliantAttribute)CompliantAttribute[0]).IsCompliant;		}		/// <summary>		/// Returns instance of ObsoleteAttribute when type is obsolete		/// </summary>		public static ObsoleteAttribute GetObsoleteAttribute (Type type)		{			object type_obsolete = analyzed_types_obsolete [type];			if (type_obsolete == FALSE)				return null;			if (type_obsolete != null)				return (ObsoleteAttribute)type_obsolete;			ObsoleteAttribute result = null;			if (type.IsByRef || type.IsArray || type.IsPointer) {				result = GetObsoleteAttribute (TypeManager.GetElementType (type));			} else {				DeclSpace type_ds = TypeManager.LookupDeclSpace (type);				// Type is external, we can get attribute directly				if (type_ds == null) {					object[] attribute = type.GetCustomAttributes (TypeManager.obsolete_attribute_type, false);					if (attribute.Length == 1)						result = (ObsoleteAttribute)attribute [0];				} else {					result = type_ds.GetObsoleteAttribute ();				}			}			// Cannot use .Add because of corlib bootstrap			analyzed_types_obsolete [type] = result == null ? FALSE : result;			return result;		}		/// <summary>		/// Returns instance of ObsoleteAttribute when method is obsolete		/// </summary>		public static ObsoleteAttribute GetMethodObsoleteAttribute (MethodBase mb)		{			IMethodData mc = TypeManager.GetMethod (mb);			if (mc != null) 				return mc.GetObsoleteAttribute ();			// compiler generated methods are not registered by AddMethod			if (mb.DeclaringType is TypeBuilder)				return null;			if (mb.IsSpecialName) {				PropertyInfo pi = PropertyExpr.AccessorTable [mb] as PropertyInfo;				if (pi != null) {					// FIXME: This is buggy as properties from this assembly are included as well					return null;					//return GetMemberObsoleteAttribute (pi);				}			}			return GetMemberObsoleteAttribute (mb);		}		/// <summary>		/// Returns instance of ObsoleteAttribute when member is obsolete		/// </summary>		public static ObsoleteAttribute GetMemberObsoleteAttribute (MemberInfo mi)		{			object type_obsolete = analyzed_member_obsolete [mi];			if (type_obsolete == FALSE)				return null;			if (type_obsolete != null)				return (ObsoleteAttribute)type_obsolete;			ObsoleteAttribute oa = System.Attribute.GetCustomAttribute (mi, TypeManager.obsolete_attribute_type, false)				as ObsoleteAttribute;			analyzed_member_obsolete.Add (mi, oa == null ? FALSE : oa);			return oa;		}		/// <summary>		/// Common method for Obsolete error/warning reporting.		/// </summary>		public static void Report_ObsoleteMessage (ObsoleteAttribute oa, string member, Location loc)		{			if (oa.IsError) {				Report.Error (619, loc, "`{0}' is obsolete: `{1}'", member, oa.Message);				return;			}			if (oa.Message == null) {				Report.Warning (612, loc, "`{0}' is obsolete", member);				return;			}			if (RootContext.WarningLevel >= 2)				Report.Warning (618, loc, "`{0}' is obsolete: `{1}'", member, oa.Message);		}		public static bool IsConditionalMethodExcluded (MethodBase mb)		{			object excluded = analyzed_method_excluded [mb];			if (excluded != null)				return excluded == TRUE ? true : false;						ConditionalAttribute[] attrs = mb.GetCustomAttributes (TypeManager.conditional_attribute_type, true)				as ConditionalAttribute[];			if (attrs.Length == 0) {				analyzed_method_excluded.Add (mb, FALSE);				return false;			}			foreach (ConditionalAttribute a in attrs) {				if (RootContext.AllDefines.Contains (a.ConditionString)) {					analyzed_method_excluded.Add (mb, FALSE);					return false;				}			}			analyzed_method_excluded.Add (mb, TRUE);			return true;		}		/// <summary>		/// Analyzes class whether it has attribute which has ConditionalAttribute		/// and its condition is not defined.		/// </summary>		public static bool IsAttributeExcluded (Type type)		{			if (!type.IsClass)				return false;			Class class_decl = TypeManager.LookupDeclSpace (type) as Class;			// TODO: add caching			// TODO: merge all Type bases attribute caching to one cache to save memory			if (class_decl == null) {				object[] attributes = type.GetCustomAttributes (TypeManager.conditional_attribute_type, false);				foreach (ConditionalAttribute ca in attributes) {					if (RootContext.AllDefines.Contains (ca.ConditionString))						return false;				}				return attributes.Length > 0;			}			return class_decl.IsExcluded ();		}		public static Type GetCoClassAttribute (Type type)		{			TypeContainer tc = TypeManager.LookupInterface (type);			if (tc == null) {				object[] o = type.GetCustomAttributes (TypeManager.coclass_attr_type, false);				return ((System.Runtime.InteropServices.CoClassAttribute)o[0]).CoClass;			}			if (tc.OptAttributes == null)				return null;			Attribute a = tc.OptAttributes.Search (TypeManager.coclass_attr_type, tc.EmitContext);			if (a == null)				return null;			return a.GetCoClassAttributeValue (tc.EmitContext);		}	}}

⌨️ 快捷键说明

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