소스 검색

* mono-api.xsl: Added support for event accessors.
* mono-api-diff.cs: Added support for event accessors.
* mono-api-info.cs: Added support for explicit interface
implementations, and groups event accessors with the corresponding
event.

svn path=/trunk/mcs/; revision=103699

Gert Driesen 17 년 전
부모
커밋
65fef90e92
4개의 변경된 파일138개의 추가작업 그리고 13개의 파일을 삭제
  1. 8 0
      mcs/tools/corcompare/ChangeLog
  2. 24 0
      mcs/tools/corcompare/mono-api-diff.cs
  3. 99 13
      mcs/tools/corcompare/mono-api-info.cs
  4. 7 0
      mcs/tools/corcompare/mono-api.xsl

+ 8 - 0
mcs/tools/corcompare/ChangeLog

@@ -1,3 +1,11 @@
+2008-05-21  Gert Driesen  <[email protected]>
+
+	* mono-api.xsl: Added support for event accessors.
+	* mono-api-diff.cs: Added support for event accessors.
+	* mono-api-info.cs: Added support for explicit interface
+	implementations, and groups event accessors with the corresponding
+	event.
+
 2008-05-19  Atsushi Enomoto  <[email protected]>
 
 	* mono-api-diff.cs : do not report CompilerGeneratedAttribute which

+ 24 - 0
mcs/tools/corcompare/mono-api-diff.cs

@@ -1575,6 +1575,7 @@ namespace Mono.AssemblyCompare
 	class XMLEvents : XMLMember
 	{
 		Hashtable eventTypes;
+		Hashtable nameToMethod = new Hashtable ();
 
 		protected override void LoadExtraData (string name, XmlNode node)
 		{
@@ -1586,6 +1587,19 @@ namespace Mono.AssemblyCompare
 				eventTypes [name] = xatt.Value;
 			}
 
+			XmlNode child = node.FirstChild;
+			while (child != null) {
+				if (child != null && child.Name == "methods") {
+					XMLMethods m = new XMLMethods ();
+					XmlNode parent = child.ParentNode;
+					string key = GetNodeKey (name, parent);
+					m.LoadData (child);
+					nameToMethod [key] = m;
+					break;
+				}
+				child = child.NextSibling;
+			}
+
 			base.LoadExtraData (name, node);
 		}
 
@@ -1608,6 +1622,16 @@ namespace Mono.AssemblyCompare
 
 				if (etype != oetype)
 					AddWarning (parent, "Event type is {0} and should be {1}", oetype, etype);
+
+				XMLMethods m = nameToMethod [name] as XMLMethods;
+				XMLMethods om = evt.nameToMethod [name] as XMLMethods;
+				if (m != null || om != null) {
+					if (m == null)
+						m = new XMLMethods ();
+
+					m.CompareTo (document, parent, om);
+					counters.AddPartialToPartial (m.Counters);
+				}
 			} finally {
 				AddCountersAttributes (parent);
 				copy.AddPartialToPartial (counters);

+ 99 - 13
mcs/tools/corcompare/mono-api-info.cs

@@ -412,10 +412,77 @@ namespace Mono.AssemblyInfo
 			return ((int) type.Attributes).ToString (CultureInfo.InvariantCulture);
 		}
 
-		public static bool MustDocumentMethod(MethodBase method)
+		/// <summary>
+		/// The includeExplicit bool was introduced to ignore explicit interface
+		/// implementations for properties and events.
+		///
+		/// When a property / event implements an explicit interface, then
+		/// the MS class libraries only have the accessors; the corresponding
+		/// property/event is not emitted.
+		/// 
+		/// For an example of a property, see System.Windows.Forms.TreeNodeCollection's
+		/// implementation of ICollection.IsSynchronized.
+		/// 
+		/// For an example of an event, see System.Windows.Forms.PropertyGrid's
+		/// implementation of IComPropertyBrowser.ComComponentNameChanged.
+		/// 
+		/// Both our C# compiler and that of MS always emit the property/event,
+		/// so MS must be using another language and/or compiler for (part of)
+		/// the BCL.
+		///
+		/// To avoid numerous extra reports in the Class Status Pages, we'll
+		/// ignore properties/events that are explictly implemented.
+		/// 
+		/// The getters/setters themselves are included in the generated API info
+		/// though.
+		/// </summary>
+		public static bool MustDocumentMethod (MethodBase method, bool includeExplicit, out bool explicitImpl)
 		{
-			// All other methods
-			return (method.IsPublic || method.IsFamily || method.IsFamilyOrAssembly);
+			explicitImpl = false;
+
+			if (method.IsPublic || method.IsFamily || method.IsFamilyOrAssembly)
+				return true;
+
+			if (!includeExplicit || method.DeclaringType.IsInterface)
+				return false;
+
+			Type [] interfaces = method.DeclaringType.GetInterfaces ();
+			foreach (Type interfaceType in interfaces) {
+				if (!IsPublicType (interfaceType))
+					continue;
+
+				InterfaceMapping map = method.DeclaringType.GetInterfaceMap (
+					interfaceType);
+				if (Array.IndexOf (map.TargetMethods, method) != -1) {
+					explicitImpl = true;
+					return true;
+				}
+			}
+
+			return false;
+		}
+
+		public static bool MustDocumentMethod (MethodBase method, bool includeExplicit)
+		{
+			bool explicitImpl;
+			return MustDocumentMethod (method, includeExplicit, out explicitImpl);
+		}
+
+		static bool IsPublicType (Type t)
+		{
+			if (t.IsPublic)
+				return true;
+			else if (!t.IsNestedPublic)
+				return false;
+
+			while (t.DeclaringType != null) {
+				t = t.DeclaringType;
+
+				if (!t.IsPublic && !(t.IsNestedPublic || t.IsNestedFamily || t.IsNestedFamORAssem))
+					return false;
+			}
+
+			return true;
 		}
 
 		static string GetClassType (Type t)
@@ -500,8 +567,8 @@ namespace Mono.AssemblyInfo
 					catch (System.Security.SecurityException) { }
 				}
 
-				bool hasGetter = (getMethod != null) && MustDocumentMethod (getMethod);
-				bool hasSetter = (setMethod != null) && MustDocumentMethod (setMethod);
+				bool hasGetter = (getMethod != null) && MustDocumentMethod (getMethod, false);
+				bool hasSetter = (setMethod != null) && MustDocumentMethod (setMethod, false);
 
 				// if neither the getter or setter should be documented, then
 				// skip the property
@@ -521,11 +588,13 @@ namespace Mono.AssemblyInfo
 
 			MethodInfo[] methods = type.GetMethods (flags);
 			foreach (MethodInfo method in methods) {
-				if (method.IsSpecialName && !method.Name.StartsWith ("op_"))
+				bool explicitImpl;
+
+				if (!MustDocumentMethod (method, true, out explicitImpl))
 					continue;
 
-				// we're only interested in public or protected members
-				if (!MustDocumentMethod(method))
+				// avoid writing (property/event) accessors twice
+				if (!explicitImpl && method.IsSpecialName && !method.Name.StartsWith ("op_"))
 					continue;
 
 				list.Add (method);
@@ -558,7 +627,7 @@ namespace Mono.AssemblyInfo
 			foreach (EventInfo eventInfo in events) {
 				MethodInfo addMethod = eventInfo.GetAddMethod (true);
 
-				if (addMethod == null || !MustDocumentMethod (addMethod))
+				if (addMethod == null || !MustDocumentMethod (addMethod, false))
 					continue;
 
 				list.Add (eventInfo);
@@ -636,12 +705,11 @@ namespace Mono.AssemblyInfo
 		{
 			base.AddExtraData (p, member);
 			PropertyInfo prop = (PropertyInfo) member;
-			Type t = prop.PropertyType;
 			AddAttribute (p, "ptype", prop.PropertyType.ToString ());
 			MethodInfo _get = prop.GetGetMethod (true);
 			MethodInfo _set = prop.GetSetMethod (true);
-			bool haveGet = (_get != null && TypeData.MustDocumentMethod(_get));
-			bool haveSet = (_set != null && TypeData.MustDocumentMethod(_set));
+			bool haveGet = (_get != null && TypeData.MustDocumentMethod(_get, false));
+			bool haveSet = (_set != null && TypeData.MustDocumentMethod(_set, false));
 			MethodInfo [] methods;
 
 			if (haveGet && haveSet) {
@@ -702,6 +770,25 @@ namespace Mono.AssemblyInfo
 			base.AddExtraData (p, member);
 			EventInfo evt = (EventInfo) member;
 			AddAttribute (p, "eventtype", evt.EventHandlerType.ToString ());
+
+			MethodInfo _add = evt.GetAddMethod (true);
+			MethodInfo _remove = evt.GetRemoveMethod (true);
+			bool haveAdd = (_add != null && TypeData.MustDocumentMethod (_add, true));
+			bool haveRemove = (_remove != null && TypeData.MustDocumentMethod (_remove, true));
+			MethodInfo [] methods;
+
+			if (haveAdd && haveRemove) {
+				methods = new MethodInfo [] { _add, _remove };
+			} else if (haveAdd) {
+				methods = new MethodInfo [] { _add };
+			} else if (haveRemove) {
+				methods = new MethodInfo [] { _remove };
+			} else {
+				return;
+			}
+
+			MethodData data = new MethodData (document, p, methods);
+			data.DoOutput ();
 		}
 
 		public override string ParentTag {
@@ -1070,4 +1157,3 @@ namespace Mono.AssemblyInfo
 		}
 	}
 }
-

+ 7 - 0
mcs/tools/corcompare/mono-api.xsl

@@ -321,6 +321,13 @@
 		</xsl:apply-templates>
 	</xsl:template>
 
+	<!-- accessor -->
+	<xsl:template match="event/methods">
+		<xsl:apply-templates select="method">
+			<xsl:sort select="@name"/>
+		</xsl:apply-templates>
+	</xsl:template>
+
 	<xsl:template match="event[@missing_total or @todo_total or @extra_total or @warning_total or @error or @presence]">
 		<div>
 			<xsl:call-template name="ELEMENT">