(DISTFILES): Comment out a few missing files.
[mono-project.git] / mcs / tools / corcompare / MissingType.cs
blob70ce69df31a6f65fc62a02c491c1731365e774b6
1 // Mono.Util.CorCompare.MissingType
2 //
3 // Author(s):
4 // Nick Drochak (ndrochak@gol.com)
5 //
6 // (C) 2001-2002 Nick Drochak
8 using System;
9 using System.Xml;
10 using System.Reflection;
11 using System.Collections;
13 namespace Mono.Util.CorCompare
16 /// <summary>
17 /// Represents a class method that missing.
18 /// </summary>
19 /// <remarks>
20 /// created by - Nick
21 /// created on - 2/20/2002 10:43:57 PM
22 /// </remarks>
23 class MissingType : MissingBase
25 // e.g. <class name="System.Byte" status="missing"/>
26 // e.g. <class name="System.Array" status="todo" missing="5" todo="6" complete="45">
27 Type typeMono, typeMS;
28 // ArrayList rgAttributes = new ArrayList ();
29 ArrayList rgMethods = new ArrayList ();
30 ArrayList rgProperties = new ArrayList ();
31 ArrayList rgEvents = new ArrayList ();
32 ArrayList rgFields = new ArrayList ();
33 ArrayList rgConstructors = new ArrayList ();
34 ArrayList rgNestedTypes = new ArrayList ();
35 ArrayList rgInterfaces = new ArrayList ();
36 // NodeStatus nsAttributes = new NodeStatus ();
37 NodeStatus nsMethods = new NodeStatus ();
38 NodeStatus nsProperties = new NodeStatus ();
39 NodeStatus nsEvents = new NodeStatus ();
40 NodeStatus nsFields = new NodeStatus ();
41 NodeStatus nsConstructors = new NodeStatus ();
42 NodeStatus nsNestedTypes = new NodeStatus ();
43 NodeStatus nsInterfaces = new NodeStatus ();
45 public MissingType (Type _typeMono, Type _typeMS)
47 typeMono = _typeMono;
48 typeMS = _typeMS;
49 m_nodeStatus = new NodeStatus (_typeMono, _typeMS);
52 public override string Name
54 get
56 Type type = TypeInfoBest;
57 if (type.DeclaringType != null)
58 return type.DeclaringType.Name + "+" + type.Name;
59 return type.Name;
63 public override string Type
65 get
67 Type type = TypeInfo;
68 if (type.IsEnum)
69 return "enum";
70 else if (type.IsInterface)
71 return "interface";
72 else if (type.IsValueType)
73 return "struct";
74 else if (IsDelegate)
75 return "delegate";
76 else
77 return "class";
81 public Type TypeInfo
83 get { return (typeMono != null) ? typeMono : typeMS; }
86 public Type TypeInfoBest
88 get { return (typeMS == null) ? typeMono : typeMS; }
91 public bool IsDelegate
93 get
95 Type typeBest = TypeInfoBest;
96 if (typeBest.IsEnum || typeBest.IsInterface || typeBest.IsValueType)
97 return false;
98 Type type = typeBest.BaseType;
99 while (type != null)
101 if (type.FullName == "System.Delegate")
102 return true;
103 type = type.BaseType;
105 return false;
109 public MissingMember CreateMember (MemberInfo infoMono, MemberInfo infoMS)
111 MemberTypes mt = (infoMono != null) ? infoMono.MemberType : infoMS.MemberType;
112 MissingMember mm;
113 switch (mt)
115 case MemberTypes.Method:
116 mm = new MissingMethod (infoMono, infoMS);
117 break;
118 case MemberTypes.Property:
119 mm = new MissingProperty (infoMono, infoMS);
120 break;
121 case MemberTypes.Event:
122 mm = new MissingEvent (infoMono, infoMS);
123 break;
124 case MemberTypes.Field:
125 mm = new MissingField (infoMono, infoMS);
126 break;
127 case MemberTypes.Constructor:
128 mm = new MissingConstructor (infoMono, infoMS);
129 break;
130 case MemberTypes.NestedType:
131 mm = new MissingNestedType (infoMono, infoMS);
132 break;
133 default:
134 throw new Exception ("Unexpected MemberType: " + mt.ToString());
136 mm.Analyze ();
137 return mm;
141 public void AddMember (MissingMember mm)
143 switch (mm.Info.MemberType)
145 case MemberTypes.Method:
146 nsMethods.AddChildren (mm.Status);
147 rgMethods.Add (mm);
148 break;
149 case MemberTypes.Property:
150 nsProperties.AddChildren (mm.Status);
151 rgProperties.Add (mm);
152 break;
153 case MemberTypes.Event:
154 nsEvents.AddChildren (mm.Status);
155 rgEvents.Add (mm);
156 break;
157 case MemberTypes.Field:
158 nsFields.AddChildren (mm.Status);
159 rgFields.Add (mm);
160 break;
161 case MemberTypes.Constructor:
162 nsConstructors.AddChildren (mm.Status);
163 rgConstructors.Add (mm);
164 break;
165 case MemberTypes.NestedType:
166 nsNestedTypes.AddChildren (mm.Status);
167 rgNestedTypes.Add (mm);
168 break;
169 default:
170 throw new Exception ("Unexpected MemberType: " + mm.Info.ToString());
174 public void AddMember (MemberInfo infoMono, MemberInfo infoMS)
176 AddMember (CreateMember (infoMono, infoMS));
179 public override XmlElement CreateXML (XmlDocument doc)
181 XmlElement eltClass = base.CreateXML (doc);
182 XmlElement eltMember;
184 eltMember = MissingBase.CreateMemberCollectionElement ("methods", rgMethods, nsMethods, doc);
185 if (eltMember != null)
186 eltClass.AppendChild (eltMember);
188 eltMember = MissingBase.CreateMemberCollectionElement ("properties", rgProperties, nsProperties, doc);
189 if (eltMember != null)
190 eltClass.AppendChild (eltMember);
192 eltMember = MissingBase.CreateMemberCollectionElement ("events", rgEvents, nsEvents, doc);
193 if (eltMember != null)
194 eltClass.AppendChild (eltMember);
196 eltMember = MissingBase.CreateMemberCollectionElement ("fields", rgFields, nsFields, doc);
197 if (eltMember != null)
198 eltClass.AppendChild (eltMember);
200 eltMember = MissingBase.CreateMemberCollectionElement ("constructors", rgConstructors, nsConstructors, doc);
201 if (eltMember != null)
202 eltClass.AppendChild (eltMember);
204 eltMember = MissingBase.CreateMemberCollectionElement ("nestedTypes", rgNestedTypes, nsNestedTypes, doc);
205 if (eltMember != null)
206 eltClass.AppendChild (eltMember);
208 eltMember = MissingBase.CreateMemberCollectionElement ("interfaces", rgInterfaces, nsInterfaces, doc);
209 if (eltMember != null)
210 eltClass.AppendChild (eltMember);
212 return eltClass;
215 public override NodeStatus Analyze ()
217 Hashtable htMono = new Hashtable ();
218 if (typeMono != null)
220 ArrayList rgIgnoreMono = new ArrayList ();
221 foreach (MemberInfo miMono in typeMono.GetMembers (BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
223 if (typeMono == miMono.DeclaringType)
225 string strName = MissingMember.GetUniqueName (miMono);
226 htMono.Add (strName, miMono);
228 // ignore any property/event accessors
229 if (miMono.MemberType == MemberTypes.Property)
231 PropertyInfo pi = (PropertyInfo) miMono;
232 MemberInfo miGet = pi.GetGetMethod ();
233 if (miGet != null)
234 rgIgnoreMono.Add (miGet);
235 MemberInfo miSet = pi.GetSetMethod ();
236 if (miSet != null)
237 rgIgnoreMono.Add (miSet);
239 else if (miMono.MemberType == MemberTypes.Event)
241 EventInfo ei = (EventInfo) miMono;
242 MemberInfo miAdd = ei.GetAddMethod ();
243 if (miAdd != null)
244 rgIgnoreMono.Add (miAdd);
245 MemberInfo miRemove = ei.GetRemoveMethod ();
246 if (miRemove != null)
247 rgIgnoreMono.Add (miRemove);
248 MemberInfo miRaise = ei.GetRaiseMethod ();
249 if (miRaise != null)
250 rgIgnoreMono.Add (miRaise);
254 foreach (MemberInfo miIgnore in rgIgnoreMono)
255 htMono.Remove (MissingMember.GetUniqueName (miIgnore));
257 Hashtable htMethodsMS = new Hashtable ();
258 if (typeMS != null)
260 ICollection colMembersMS = typeMS.GetMembers (BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
261 Hashtable htIgnoreMS = new Hashtable ();
262 foreach (MemberInfo miMS in colMembersMS)
264 // ignore any property/event accessors
265 if (miMS.MemberType == MemberTypes.Property)
267 PropertyInfo pi = (PropertyInfo) miMS;
268 MemberInfo miGet = pi.GetGetMethod ();
269 if (miGet != null)
270 htIgnoreMS.Add (miGet, miMS);
271 MemberInfo miSet = pi.GetSetMethod ();
272 if (miSet != null)
273 htIgnoreMS.Add (miSet, miMS);
275 else if (miMS.MemberType == MemberTypes.Event)
277 EventInfo ei = (EventInfo) miMS;
278 MemberInfo miAdd = ei.GetAddMethod ();
279 if (miAdd != null)
280 htIgnoreMS.Add (miAdd, miMS);
281 MemberInfo miRemove = ei.GetRemoveMethod ();
282 if (miRemove != null)
283 htIgnoreMS.Add (miRemove, miMS);
284 MemberInfo miRaise = ei.GetRaiseMethod ();
285 if (miRaise != null)
286 htIgnoreMS.Add (miRaise, miMS);
289 foreach (MemberInfo miMS in colMembersMS)
291 if (miMS != null && miMS.DeclaringType == typeMS && !htIgnoreMS.Contains (miMS))
293 string strNameUnique = MissingMember.GetUniqueName (miMS);
294 MemberInfo miMono = (MemberInfo) htMono [strNameUnique];
296 MissingMember mm = CreateMember (miMono, miMS);
298 bool fVisibleMS = IsVisible (miMS);
299 if (miMono == null)
301 if (fVisibleMS)
302 AddMember (mm);
304 else
306 if (miMono.MemberType != miMS.MemberType)
308 //AddMember (null, miMS);
309 //MissingMember mm2 = CreateMember (miMono, null);
310 //mm2.Status.AddWarning ("MemberType mismatch, is: '" + miMono.MemberType.ToString () + "' [should be: '" + miMS.MemberType.ToString ()+"']");
311 //AddMember (mm2);
312 mm.Status.AddWarning ("MemberType mismatch, is: '" + miMono.MemberType.ToString () + "' [should be: '" + miMS.MemberType.ToString ()+"']");
313 AddMember (mm);
315 else if (fVisibleMS || IsVisible (miMono))
317 AddMember (mm);
320 htMono.Remove (strNameUnique);
323 switch (miMS.MemberType)
325 case MemberTypes.Method:
327 string strNameMSFull = miMS.ToString ();
328 int ichMS = strNameMSFull.IndexOf (' ');
329 string strNameMS = strNameMSFull.Substring (ichMS + 1);
330 if (!htMethodsMS.Contains (strNameMS))
331 htMethodsMS.Add (strNameMSFull.Substring (ichMS + 1), miMS);
332 break;
338 foreach (MemberInfo miMono in htMono.Values)
340 if (IsVisible (miMono))
342 MissingMember mm = CreateMember (miMono, null);
343 switch (miMono.MemberType)
345 case MemberTypes.Method:
347 string strNameMonoFull = miMono.ToString ();
348 int ichMono = strNameMonoFull.IndexOf (' ');
349 string strNameMono = strNameMonoFull.Substring (ichMono + 1);
350 MemberInfo miMS = (MemberInfo) htMethodsMS [strNameMono];
351 if (miMS != null)
353 string strNameMSFull = miMS.ToString ();
354 int ichMS = strNameMSFull.IndexOf (' ');
355 string strReturnTypeMS = strNameMSFull.Substring (0, ichMS);
356 string strReturnTypeMono = strNameMonoFull.Substring (0, ichMono);
357 mm.Status.AddWarning ("Return type mismatch, is: '"+strReturnTypeMono+"' [should be: '"+strReturnTypeMS+"']");
358 //Console.WriteLine ("WARNING: Return type mismatch on "+miMS.DeclaringType.FullName+"."+strNameMono+", is: '"+strReturnTypeMono+"' [should be: '"+strReturnTypeMS+"']");
360 break;
363 AddMember (mm);
367 // compare the attributes
368 rgAttributes = new ArrayList ();
369 nsAttributes = MissingAttribute.AnalyzeAttributes (
370 (typeMono == null) ? null : typeMono.GetCustomAttributes (false),
371 ( typeMS == null) ? null : typeMS.GetCustomAttributes (false),
372 rgAttributes);
374 rgInterfaces = new ArrayList ();
375 if (typeMono != null && typeMS != null)
377 // compare base types
378 string strBaseMono = (typeMono.BaseType == null) ? null : typeMono.BaseType.FullName;
379 string strBaseMS = ( typeMS.BaseType == null) ? null : typeMS.BaseType.FullName;
380 if (strBaseMono != strBaseMS)
382 m_nodeStatus.AddWarning ("Base class mismatch, is '"+strBaseMono+"' [should be: '"+strBaseMS+"']");
383 //Console.WriteLine ("WARNING: Base class mismatch on "+typeMono.FullName+", is: '"+strBaseMono+"' [should be: '"+strBaseMS+"']");
386 // compare the interfaces
387 Hashtable htInterfacesMono = new Hashtable ();
388 Type [] rgInterfacesMono = typeMono.GetInterfaces ();
389 foreach (Type ifaceMono in rgInterfacesMono)
391 if (ifaceMono != null)
393 string strName = ifaceMono.FullName;
394 htInterfacesMono.Add (strName, ifaceMono);
397 Type [] rgInterfacesMS = typeMS.GetInterfaces ();
398 foreach (Type ifaceMS in rgInterfacesMS)
400 if (ifaceMS != null)
402 string strName = ifaceMS.FullName;
403 Type ifaceMono = (Type) htInterfacesMono [strName];
404 MissingInterface mi = new MissingInterface (ifaceMono, ifaceMS);
405 mi.Analyze ();
406 rgInterfaces.Add (mi);
407 if (ifaceMono != null)
408 htInterfacesMono.Remove (strName);
409 nsInterfaces.AddChildren (mi.Status);
412 foreach (Type ifaceMono in htInterfacesMono.Values)
414 MissingInterface mi = new MissingInterface (ifaceMono, null);
415 mi.Analyze ();
416 rgInterfaces.Add (mi);
417 //Console.WriteLine ("WARNING: additional interface on "+typeMono.FullName+": '"+ifaceMono.FullName+"'");
418 nsInterfaces.AddChildren (mi.Status);
421 // serializable attribute
422 AddFakeAttribute (typeMono.IsSerializable, typeMS.IsSerializable, "System.SerializableAttribute");
423 AddFakeAttribute (typeMono.IsAutoLayout, typeMS.IsAutoLayout, "System.AutoLayoutAttribute");
424 AddFakeAttribute (typeMono.IsExplicitLayout, typeMS.IsExplicitLayout, "System.ExplicitLayoutAttribute");
425 AddFakeAttribute (typeMono.IsLayoutSequential, typeMS.IsLayoutSequential, "System.SequentialLayoutAttribute");
427 Accessibility accessibilityMono = GetAccessibility (typeMono);
428 Accessibility accessibilityMS = GetAccessibility (typeMS);
429 if (accessibilityMono != accessibilityMS)
430 m_nodeStatus.AddWarning ("Should be "+AccessibilityToString (accessibilityMono));
432 AddFlagWarning (typeMono.IsSealed, typeMS.IsSealed, "sealed");
433 AddFlagWarning (typeMono.IsAbstract, typeMS.IsAbstract, "abstract");
436 // sum up the sub-sections
437 m_nodeStatus.Add (nsAttributes);
438 m_nodeStatus.Add (nsMethods);
439 m_nodeStatus.Add (nsProperties);
440 m_nodeStatus.Add (nsEvents);
441 m_nodeStatus.Add (nsFields);
442 m_nodeStatus.Add (nsConstructors);
443 m_nodeStatus.Add (nsNestedTypes);
444 m_nodeStatus.Add (nsInterfaces);
446 return m_nodeStatus;
449 static bool IsVisible (MemberInfo mi)
451 // this is just embarrasing, couldn't they have virtualized this?
452 switch (mi.MemberType)
454 case MemberTypes.Constructor:
455 case MemberTypes.Method:
456 return !((MethodBase) mi).IsPrivate && !((MethodBase) mi).IsFamilyAndAssembly && !((MethodBase) mi).IsAssembly;
457 case MemberTypes.Field:
458 return !((FieldInfo) mi).IsPrivate && !((FieldInfo) mi).IsFamilyAndAssembly && !((FieldInfo) mi).IsAssembly;
459 case MemberTypes.NestedType:
460 return !((Type) mi).IsNestedPrivate && !((Type) mi).IsNestedAssembly && !((Type) mi).IsNestedFamANDAssem;
461 case MemberTypes.Property: // great, now we have to look at the methods
462 PropertyInfo pi = (PropertyInfo) mi;
463 MethodInfo miAccessor = pi.GetGetMethod ();
464 if (miAccessor == null)
465 miAccessor = pi.GetSetMethod ();
466 if (miAccessor == null)
467 return false;
468 return IsVisible (miAccessor);
469 case MemberTypes.Event: // ditto
470 EventInfo ei = (EventInfo) mi;
471 MethodInfo eiAccessor = ei.GetAddMethod ();
472 if (eiAccessor == null)
473 eiAccessor = ei.GetRemoveMethod ();
474 if (eiAccessor == null)
475 eiAccessor = ei.GetRaiseMethod ();
476 if (eiAccessor == null)
477 return false;
478 return IsVisible (eiAccessor);
479 default:
480 throw new Exception ("Missing handler for MemberType: "+mi.MemberType.ToString ());
484 static Accessibility GetAccessibility (Type type)
486 if (type.IsPublic)
487 return Accessibility.Public;
488 else if (type.IsNotPublic)
489 return Accessibility.Private;
490 return MissingMember.GetAccessibility (type);