Imported Upstream version 4.8.0.309

Former-commit-id: 5f9c6ae75f295e057a7d2971f3a6df4656fa8850
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2016-11-10 13:04:39 +00:00
parent ee1447783b
commit 94b2861243
4912 changed files with 390737 additions and 49310 deletions

View File

@ -78,10 +78,11 @@ namespace Xamarin.ApiDiff {
public static bool IgnoreVirtualChanges { get; set; }
public static bool IgnoreAddedPropertySetters { get; set; }
public static bool IgnoreNonbreaking { get; set; }
public static bool Lax;
public static bool Colorize = true;
}
class Program {
public static int Main (string[] args)
@ -120,7 +121,8 @@ namespace Xamarin.ApiDiff {
v => State.IgnoreVirtualChanges = v != null
},
{ "c|colorize:", "Colorize HTML output", v => State.Colorize = string.IsNullOrEmpty (v) ? true : bool.Parse (v) },
{ "x|lax", "Ignore duplicate XML entries", v => State.Lax = true }
{ "x|lax", "Ignore duplicate XML entries", v => State.Lax = true },
{ "ignore-nonbreaking", "Ignore all nonbreaking changes", v => State.IgnoreNonbreaking = true }
};
try {
@ -130,6 +132,13 @@ namespace Xamarin.ApiDiff {
showHelp = true;
}
if (State.IgnoreNonbreaking) {
State.IgnoreAddedPropertySetters = true;
State.IgnoreVirtualChanges = true;
State.IgnoreNew.Add (new Regex (".*"));
State.IgnoreAdded.Add (new Regex (".*"));
}
if (showHelp || extra == null || extra.Count < 2 || extra.Count > 3) {
Console.WriteLine (@"Usage: mono-api-html [options] <reference.xml> <assembly.xml> [diff.html]");
Console.WriteLine ();
@ -253,9 +262,11 @@ namespace Xamarin.ApiDiff {
} else {
file.WriteLine ("<h1>{0}.dll vs {1}.dll</h1>", ac.SourceAssembly, ac.TargetAssembly);
}
file.WriteLine ("<a href='javascript: hideNonBreakingChanges (); ' class='hide-nonbreaking'>Hide non-breaking changes</a>");
file.WriteLine ("<a href='javascript: showNonBreakingChanges (); ' class='restore-nonbreaking' style='display: none;'>Show non-breaking changes</a>");
file.WriteLine ("<br/>");
if (!State.IgnoreNonbreaking) {
file.WriteLine ("<a href='javascript: hideNonBreakingChanges (); ' class='hide-nonbreaking'>Hide non-breaking changes</a>");
file.WriteLine ("<a href='javascript: showNonBreakingChanges (); ' class='restore-nonbreaking' style='display: none;'>Show non-breaking changes</a>");
file.WriteLine ("<br/>");
}
file.WriteLine ("<div data-is-topmost>");
file.Write (diffHtml);
file.WriteLine ("</div> <!-- end topmost div -->");

View File

@ -66,7 +66,13 @@ namespace Xamarin.ApiDiff {
{
SourceAssembly = source.GetAttribute ("name");
TargetAssembly = target.GetAttribute ("name");
// TODO: version
var sb = source.GetAttribute ("version");
var tb = target.GetAttribute ("version");
if (sb != tb) {
Output.WriteLine ("<h4>Assembly Version Changed: {0} vs {1}</h4>", tb, sb);
}
// ? custom attributes ?
comparer.Compare (source, target);
}

View File

@ -198,6 +198,20 @@ namespace Xamarin.ApiDiff {
Indent ().WriteLine ("}");
}
//HACK: we don't have hierarchy information here so just check some basic heuristics for now
bool IsBaseChangeCompatible (string source, string target)
{
if (source == "System.Object")
return true;
if (source == "System.Exception" && target.EndsWith ("Exception", StringComparison.Ordinal))
return true;
if (source == "System.EventArgs" && target.EndsWith ("EventArgs", StringComparison.Ordinal))
return true;
if (source == "System.Runtime.InteropServices.SafeHandle" && target.StartsWith ("Microsoft.Win32.SafeHandles.SafeHandle", StringComparison.Ordinal))
return true;
return false;
}
public override void Modified (XElement source, XElement target, ApiChanges diff)
{
// hack - there could be changes that we're not monitoring (e.g. attributes properties)
@ -206,7 +220,7 @@ namespace Xamarin.ApiDiff {
var sb = source.GetAttribute ("base");
var tb = target.GetAttribute ("base");
if (sb != tb) {
if (sb != tb && !(State.IgnoreNonbreaking && IsBaseChangeCompatible (sb, tb))) {
Output.Write ("Modified base type: ");
Output.WriteLine (new ApiChange ().AppendModified (sb, tb, true).Member.ToString ());
}

View File

@ -45,14 +45,16 @@ namespace Xamarin.ApiDiff {
void RenderFieldAttributes (FieldAttributes source, FieldAttributes target, ApiChange change)
{
var srcNotSerialized = (source & FieldAttributes.NotSerialized) == FieldAttributes.NotSerialized;
var tgtNotSerialized = (target & FieldAttributes.NotSerialized) == FieldAttributes.NotSerialized;
if (srcNotSerialized != tgtNotSerialized) {
// this is not a breaking change, so only render it if it changed.
if (srcNotSerialized) {
change.AppendRemoved ("[NonSerialized]\n");
} else {
change.AppendAdded ("[NonSerialized]\n");
if (!State.IgnoreNonbreaking) {
var srcNotSerialized = (source & FieldAttributes.NotSerialized) == FieldAttributes.NotSerialized;
var tgtNotSerialized = (target & FieldAttributes.NotSerialized) == FieldAttributes.NotSerialized;
if (srcNotSerialized != tgtNotSerialized) {
// this is not a breaking change, so only render it if it changed.
if (srcNotSerialized) {
change.AppendRemoved ("[NonSerialized]\n");
} else {
change.AppendAdded ("[NonSerialized]\n");
}
}
}

View File

@ -138,9 +138,13 @@ namespace Xamarin.ApiDiff {
void Modify (ApiChanges modified)
{
foreach (var changes in modified) {
if (State.IgnoreNonbreaking && changes.Value.All (c => !c.Breaking))
continue;
Output.WriteLine ("<p>{0}:</p>", changes.Key);
Output.WriteLine ("<pre>");
foreach (var element in changes.Value) {
if (State.IgnoreNonbreaking && !element.Breaking)
continue;
Output.Write ("<div {0}>", element.Breaking ? "data-is-breaking" : "data-is-non-breaking");
foreach (var line in element.Member.ToString ().Split ('\n'))
Output.WriteLine ("\t{0}", line);
@ -158,6 +162,8 @@ namespace Xamarin.ApiDiff {
if (State.IgnoreRemoved.Any (re => re.IsMatch (GetDescription (item))))
continue;
SetContext (item);
if (State.IgnoreNonbreaking && !IsBreakingRemoval (item))
continue;
if (!r) {
BeforeRemoving (elements);
r = true;
@ -336,10 +342,19 @@ namespace Xamarin.ApiDiff {
if (i > 0)
change.Append (", ");
string mods_tgt = tgt [i].GetAttribute ("direction") ?? "";
string mods_src = src [i].GetAttribute ("direction") ?? "";
if (mods_tgt.Length > 0)
mods_tgt = mods_tgt + " ";
if (mods_src.Length > 0)
mods_src = mods_src + " ";
if (i >= srcCount) {
change.AppendAdded (tgt [i].GetTypeName ("type") + " " + tgt [i].GetAttribute ("name"), true);
change.AppendAdded (mods_tgt + tgt [i].GetTypeName ("type") + " " + tgt [i].GetAttribute ("name"), true);
} else if (i >= tgtCount) {
change.AppendRemoved (src [i].GetTypeName ("type") + " " + src [i].GetAttribute ("name"), true);
change.AppendRemoved (mods_src + src [i].GetTypeName ("type") + " " + src [i].GetAttribute ("name"), true);
} else {
var paramSourceType = src [i].GetTypeName ("type");
var paramTargetType = tgt [i].GetTypeName ("type");
@ -347,6 +362,12 @@ namespace Xamarin.ApiDiff {
var paramSourceName = src [i].GetAttribute ("name");
var paramTargetName = tgt [i].GetAttribute ("name");
if (mods_src != mods_tgt) {
change.AppendModified (mods_src, mods_tgt, true);
} else {
change.Append (mods_src);
}
if (paramSourceType != paramTargetType) {
change.AppendModified (paramSourceType, paramTargetType, true);
} else {
@ -354,7 +375,7 @@ namespace Xamarin.ApiDiff {
}
change.Append (" ");
if (paramSourceName != paramTargetName) {
change.AppendModified (paramSourceName, paramTargetName, false);
change.AppendModified (paramSourceName, paramTargetName, true);
} else {
change.Append (paramSourceName);
}
@ -418,8 +439,13 @@ namespace Xamarin.ApiDiff {
if (tgtAbstract) {
change.AppendAdded ("abstract", true).Append (" ");
} else if (srcWord != tgtWord) {
if (!tgtFinal)
change.AppendModified (srcWord, tgtWord, breaking).Append (" ");
if (!tgtFinal) {
if (State.IgnoreVirtualChanges) {
change.HasIgnoredChanges = true;
} else {
change.AppendModified (srcWord, tgtWord, breaking).Append (" ");
}
}
} else if (tgtWord.Length > 0) {
change.Append (tgtWord).Append (" ");
} else if (srcWord.Length > 0) {
@ -431,7 +457,11 @@ namespace Xamarin.ApiDiff {
if (tgtFinal) {
change.Append ("final ");
} else {
change.AppendRemoved ("final", false).Append (" "); // removing 'final' is not a breaking change.
if (srcVirtual && !tgtVirtual && State.IgnoreVirtualChanges) {
change.HasIgnoredChanges = true;
} else {
change.AppendRemoved ("final", false).Append (" "); // removing 'final' is not a breaking change.
}
}
} else {
if (tgtFinal && srcVirtual) {