Merge pull request #1633 from BrzVlad/fix-w32-pinvoke
[mono.git] / mcs / tools / corcompare / mono-api-html / FieldComparer.cs
index 54942b64043d5a95f942f6363930d65cfa656644..c8a6e0a777262a1b43807f0decb5a5a58d315484 100644 (file)
@@ -2,7 +2,7 @@
 // Authors
 //    Sebastien Pouliot  <sebastien@xamarin.com>
 //
-// Copyright 2013 Xamarin Inc. http://www.xamarin.com
+// Copyright 2013-2014 Xamarin Inc. http://www.xamarin.com
 // 
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
@@ -25,6 +25,8 @@
 //
 
 using System;
+using System.Collections.Generic;
+using System.Linq;
 using System.Reflection;
 using System.Text;
 using System.Xml.Linq;
@@ -41,10 +43,99 @@ namespace Xamarin.ApiDiff {
                        get { return "field"; }
                }
 
+               void RenderFieldAttributes (FieldAttributes source, FieldAttributes target, ApiChange change)
+               {
+                       // the visibility values are the same for MethodAttributes and FieldAttributes, so just use the same method.
+                       RenderVisibility ((MethodAttributes) source, (MethodAttributes) target, change);
+                       // same for the static flag
+                       RenderStatic ((MethodAttributes) source, (MethodAttributes) target, change);
+
+                       var srcLiteral = (source & FieldAttributes.Literal) != 0;
+                       var tgtLiteral = (target & FieldAttributes.Literal) != 0;
+
+                       if (srcLiteral) {
+                               if (tgtLiteral) {
+                                       change.Append ("const ");
+                               } else {
+                                       change.AppendRemoved ("const", true).Append (" ");
+                               }
+                       } else if (tgtLiteral) {
+                               change.AppendAdded ("const", true).Append (" ");
+                       }
+
+                       var srcInitOnly = (source & FieldAttributes.InitOnly) != 0;
+                       var tgtInitOnly = (target & FieldAttributes.InitOnly) != 0;
+                       if (srcInitOnly) {
+                               if (tgtInitOnly) {
+                                       change.Append ("readonly ");
+                               } else {
+                                       change.AppendRemoved ("readonly", false).Append (" ");
+                               }
+                       } else if (tgtInitOnly) {
+                               change.AppendAdded ("readonly", true).Append (" ");
+                       }
+               }
+
+               public override bool Equals (XElement source, XElement target, ApiChanges changes)
+               {
+                       if (base.Equals (source, target, changes))
+                               return true;
+
+                       var name = source.GetAttribute ("name");
+                       var srcValue = source.GetAttribute ("value");
+                       var tgtValue = target.GetAttribute ("value");
+                       var change = new ApiChange ();
+                       change.Header = "Modified " + GroupName;
+
+                       if (State.BaseType == "System.Enum") {
+                               change.Append (name).Append (" = ");
+                               if (srcValue != tgtValue) {
+                                       change.AppendModified (srcValue, tgtValue, true);
+                               } else {
+                                       change.Append (srcValue);
+                               }
+                       } else {
+                               RenderFieldAttributes (source.GetFieldAttributes (), target.GetFieldAttributes (), change);
+
+                               var srcType = source.GetTypeName ("fieldtype");
+                               var tgtType = target.GetTypeName ("fieldtype");
+
+                               if (srcType != tgtType) {
+                                       change.AppendModified (srcType, tgtType, true);
+                               } else {
+                                       change.Append (srcType);
+                               }
+                               change.Append (" ");
+                               change.Append (name);
+
+                               if (srcType == "string" && srcValue != null)
+                                       srcValue = "\"" + srcValue + "\"";
+
+                               if (tgtType == "string" && tgtValue != null)
+                                       tgtValue = "\"" + tgtValue + "\"";
+
+                               if (srcValue != tgtValue) {
+                                       change.Append (" = ");
+                                       if (srcValue == null)
+                                               srcValue = "null";
+                                       if (tgtValue == null)
+                                               tgtValue = "null";
+                                       change.AppendModified (srcValue, tgtValue, true);
+                               } else if (srcValue != null) {
+                                       change.Append (" = ");
+                                       change.Append (srcValue);
+                               }
+                               change.Append (";");
+                       }
+
+                       changes.Add (source, target, change);
+
+                       return false;
+               }
+
                public override string GetDescription (XElement e)
                {
-                       var sb = GetObsoleteMessage (e);
-                       bool obsolete = sb.Length > 0;
+                       var sb = new StringBuilder ();
 
                        string name = e.GetAttribute ("name");
                        string value = e.GetAttribute ("value");
@@ -71,30 +162,40 @@ namespace Xamarin.ApiDiff {
                                string ftype = e.GetTypeName ("fieldtype");
                                sb.Append (ftype).Append (' ');
                                sb.Append (name);
-                               if (ftype == "string")
-                                       sb.Append (" = \"").Append (e.Attribute ("value").Value).Append ('"');
+                               if (ftype == "string" && e.Attribute ("value") != null) {
+                                       if (value == null)
+                                               sb.Append (" = null");
+                                       else
+                                               sb.Append (" = \"").Append (value).Append ('"');
+                               }
                                sb.Append (';');
                        }
 
-                       if (obsolete)
-                               sb.AppendLine (); // more readable output
                        return sb.ToString ();
                }
 
-               public override void BeforeAdding ()
+               public override void BeforeAdding (IEnumerable<XElement> list)
                {
-                       if (State.BaseType == "System.Enum")
-                               Output.WriteLine ("<p>Added values:</p><pre>");
-                       else
-                               base.BeforeAdding ();
+                       first = true;
+                       if (State.BaseType == "System.Enum") {
+                               Output.WriteLine ("<p>Added value{0}:</p><pre>", list.Count () > 1 ? "s" : String.Empty);
+                               if (State.Colorize)
+                                       Output.Write ("<font color='green'>");
+                       } else {
+                               base.BeforeAdding (list);
+                       }
                }
 
-               public override void BeforeRemoving ()
+               public override void BeforeRemoving (IEnumerable<XElement> list)
                {
-                       if (State.BaseType == "System.Enum")
-                               Output.WriteLine ("<p>Removed values:</p><pre>");
-                       else
-                               base.BeforeRemoving ();
+                       first = true;
+                       if (State.BaseType == "System.Enum") {
+                               Output.WriteLine ("<p>Removed value{0}:</p><pre>", list.Count () > 1 ? "s" : String.Empty);
+                               if (State.Colorize)
+                                       Output.Write ("<font color='red'>");
+                       } else {
+                               base.BeforeRemoving (list);
+                       }
                }
        }
 }
\ No newline at end of file