Imported Upstream version 5.18.0.142

Former-commit-id: 7467d4b717762eeaf652d77f1486dd11ffb1ff1f
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2018-10-09 08:20:59 +00:00
parent e52655b4dc
commit 0abdbe5a7d
1547 changed files with 93792 additions and 47893 deletions

View File

@@ -4,9 +4,9 @@ using System.Linq;
using System.Text;
using System.Xml.Linq;
namespace Xamarin.ApiDiff
{
public class ApiChange
namespace Mono.ApiTools {
class ApiChange
{
public string Header;
public StringBuilder Member = new StringBuilder ();
@@ -14,10 +14,12 @@ namespace Xamarin.ApiDiff
public bool AnyChange;
public bool HasIgnoredChanges;
public string SourceDescription;
public State State;
public ApiChange (string sourceDescription)
public ApiChange (string sourceDescription, State state)
{
SourceDescription = sourceDescription;
State = state;
}
public ApiChange Append (string text)
@@ -28,7 +30,7 @@ namespace Xamarin.ApiDiff
public ApiChange AppendAdded (string text, bool breaking = false)
{
Formatter.Current.DiffAddition (Member, text, breaking);
State.Formatter.DiffAddition (Member, text, breaking);
Breaking |= breaking;
AnyChange = true;
return this;
@@ -36,7 +38,7 @@ namespace Xamarin.ApiDiff
public ApiChange AppendRemoved (string text, bool breaking = true)
{
Formatter.Current.DiffRemoval (Member, text, breaking);
State.Formatter.DiffRemoval (Member, text, breaking);
Breaking |= breaking;
AnyChange = true;
return this;
@@ -44,14 +46,22 @@ namespace Xamarin.ApiDiff
public ApiChange AppendModified (string old, string @new, bool breaking = true)
{
Formatter.Current.DiffModification (Member, old, @new, breaking);
State.Formatter.DiffModification (Member, old, @new, breaking);
Breaking |= breaking;
AnyChange = true;
return this;
}
}
public class ApiChanges : Dictionary<string, List<ApiChange>> {
class ApiChanges : Dictionary<string, List<ApiChange>> {
public State State;
public ApiChanges (State state)
{
State = state;
}
public void Add (XElement source, XElement target, ApiChange change)
{
if (!change.AnyChange) {
@@ -59,9 +69,9 @@ namespace Xamarin.ApiDiff
if (!change.HasIgnoredChanges) {
var isField = source.Name.LocalName == "field";
if (isField) {
Console.WriteLine ("Comparison resulting in no changes (src: {2} dst: {3}) :\n{0}\n{1}\n\n", source.ToString (), target.ToString (), source.GetFieldAttributes (), target.GetFieldAttributes ());
State.LogDebugMessage ($"Comparison resulting in no changes (src: {source.GetFieldAttributes ()} dst: {target.GetFieldAttributes ()}) :\n{source}\n{target}\n\n");
} else {
Console.WriteLine ("Comparison resulting in no changes (src: {2} dst: {3}) :\n{0}\n{1}\n\n", source.ToString (), target.ToString (), source.GetMethodAttributes (), target.GetMethodAttributes ());
State.LogDebugMessage ($"Comparison resulting in no changes (src: {source.GetMethodAttributes ()} dst: {target.GetMethodAttributes ()}) :\n{source}\n{target}\n\n");
}
}
return;

View File

@@ -37,63 +37,39 @@ using System.IO;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using Mono.Options;
namespace Mono.ApiTools {
namespace Xamarin.ApiDiff {
class State {
public TextWriter Output { get; set; }
public Formatter Formatter { get; set; }
public string Assembly { get; set; }
public string Namespace { get; set; }
public string Type { get; set; }
public string BaseType { get; set; }
public string Parent { get; set; }
public int Indent { get; set; }
public List<Regex> IgnoreAdded { get; } = new List<Regex> ();
public List<Regex> IgnoreNew { get; } = new List<Regex> ();
public List<Regex> IgnoreRemoved { get; } = new List<Regex> ();
public bool IgnoreParameterNameChanges { get; set; }
public bool IgnoreVirtualChanges { get; set; }
public bool IgnoreAddedPropertySetters { get; set; }
public bool IgnoreNonbreaking { get; set; }
public bool Lax { get; set; }
public bool Colorize { get; set; } = true;
public int Verbosity { get; set; }
public static class State {
static TextWriter output;
public static TextWriter Output {
get {
if (output == null)
output = Console.Out;
return output;
}
set { output = value; }
}
public static string Assembly { get; set; }
public static string Namespace { get; set; }
public static string Type { get; set; }
public static string BaseType { get; set; }
public static string Parent { get; set; }
public static int Indent { get; set; }
static List<Regex> ignoreAdded = new List<Regex> ();
public static List<Regex> IgnoreAdded {
get { return ignoreAdded; }
}
static List<Regex> ignoreNew = new List<Regex> ();
public static List<Regex> IgnoreNew {
get { return ignoreNew; }
}
static List<Regex> ignoreRemoved = new List<Regex> ();
public static List<Regex> IgnoreRemoved {
get { return ignoreRemoved; }
}
public static bool IgnoreParameterNameChanges { get; set; }
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;
public static int Verbosity;
public static void LogDebugMessage (string value)
public void LogDebugMessage (string value)
{
#if !EXCLUDE_DRIVER
if (Verbosity == 0)
return;
Console.WriteLine (value);
#endif
}
}
#if !EXCLUDE_DRIVER
class Program {
public static int Main (string[] args)
@@ -101,61 +77,51 @@ namespace Xamarin.ApiDiff {
var showHelp = false;
string diff = null;
List<string> extra = null;
var config = new ApiDiffFormattedConfig ();
var options = new OptionSet {
var options = new Mono.Options.OptionSet {
{ "h|help", "Show this help", v => showHelp = true },
{ "d|diff=", "HTML diff file out output (omit for stdout)", v => diff = v },
{ "d|o|out=|output=|diff=", "HTML diff file out output (omit for stdout)", v => diff = v },
{ "i|ignore=", "Ignore new, added, and removed members whose description matches a given C# regular expression (see below).",
v => {
var r = new Regex (v);
State.IgnoreAdded.Add (r);
State.IgnoreRemoved.Add (r);
State.IgnoreNew.Add (r);
config.IgnoreAdded.Add (r);
config.IgnoreRemoved.Add (r);
config.IgnoreNew.Add (r);
}
},
{ "a|ignore-added=", "Ignore added members whose description matches a given C# regular expression (see below).",
v => State.IgnoreAdded.Add (new Regex (v))
v => config.IgnoreAdded.Add (new Regex (v))
},
{ "r|ignore-removed=", "Ignore removed members whose description matches a given C# regular expression (see below).",
v => State.IgnoreRemoved.Add (new Regex (v))
v => config.IgnoreRemoved.Add (new Regex (v))
},
{ "n|ignore-new=", "Ignore new namespaces and types whose description matches a given C# regular expression (see below).",
v => State.IgnoreNew.Add (new Regex (v))
v => config.IgnoreNew.Add (new Regex (v))
},
{ "ignore-changes-parameter-names", "Ignore changes to parameter names for identically prototyped methods.",
v => State.IgnoreParameterNameChanges = v != null
v => config.IgnoreParameterNameChanges = v != null
},
{ "ignore-changes-property-setters", "Ignore adding setters to properties.",
v => State.IgnoreAddedPropertySetters = v != null
v => config.IgnoreAddedPropertySetters = v != null
},
{ "ignore-changes-virtual", "Ignore changing non-`virtual` to `virtual` or adding `override`.",
v => State.IgnoreVirtualChanges = v != null
v => config.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 },
{ "ignore-nonbreaking", "Ignore all nonbreaking changes", v => State.IgnoreNonbreaking = true },
{ "c|colorize:", "Colorize HTML output", v => config.Colorize = string.IsNullOrEmpty (v) ? true : bool.Parse (v) },
{ "x|lax", "Ignore duplicate XML entries", v => config.IgnoreDuplicateXml = true },
{ "ignore-nonbreaking", "Ignore all nonbreaking changes", v => config.IgnoreNonbreaking = true },
{ "v|verbose:", "Verbosity level; when set, will print debug messages",
(int? v) => State.Verbosity = v ?? (State.Verbosity + 1)},
{ "md|markdown", "Output markdown instead of HTML", v => Formatter.Current = new MarkdownFormatter () },
new ResponseFileSource (),
(int? v) => config.Verbosity = v ?? (config.Verbosity + 1)},
{ "md|markdown", "Output markdown instead of HTML", v => config.Formatter = ApiDiffFormatter.Markdown },
new Mono.Options.ResponseFileSource (),
};
try {
extra = options.Parse (args);
} catch (OptionException e) {
} catch (Mono.Options.OptionException e) {
Console.WriteLine ("Option error: {0}", e.Message);
showHelp = true;
}
// unless specified default to HTML
if (Formatter.Current == null)
Formatter.Current = new HtmlFormatter ();
if (State.IgnoreNonbreaking) {
State.IgnoreAddedPropertySetters = true;
State.IgnoreVirtualChanges = true;
State.IgnoreNew.Add (new Regex (".*"));
State.IgnoreAdded.Add (new Regex (".*"));
extra = null;
}
if (showHelp || extra == null || extra.Count < 2 || extra.Count > 3) {
@@ -177,7 +143,7 @@ namespace Xamarin.ApiDiff {
Console.WriteLine (" The regular expressions will match any member description ending with");
Console.WriteLine (" 'INSCopying' or 'INSCoding'.");
Console.WriteLine ();
return 1;
return showHelp ? 0 : 1;
}
var input = extra [0];
@@ -185,37 +151,136 @@ namespace Xamarin.ApiDiff {
if (extra.Count == 3 && diff == null)
diff = extra [2];
TextWriter outputStream = null;
try {
var ac = new AssemblyComparer (input, output);
if (diff != null) {
string diffHtml = String.Empty;
using (var writer = new StringWriter ()) {
State.Output = writer;
ac.Compare ();
diffHtml = State.Output.ToString ();
}
if (diffHtml.Length > 0) {
using (var file = new StreamWriter (diff)) {
var title = $"{ac.SourceAssembly}.dll";
if (ac.SourceAssembly != ac.TargetAssembly)
title += $" vs {ac.TargetAssembly}.dll";
Formatter.Current.BeginDocument (file, $"API diff: {title}");
Formatter.Current.BeginAssembly (file);
file.Write (diffHtml);
Formatter.Current.EndAssembly (file);
Formatter.Current.EndDocument (file);
}
}
} else {
State.Output = Console.Out;
ac.Compare ();
}
}
catch (Exception e) {
if (!string.IsNullOrEmpty (diff))
outputStream = new StreamWriter (diff);
ApiDiffFormatted.Generate (input, output, outputStream ?? Console.Out, config);
} catch (Exception e) {
Console.WriteLine (e);
return 1;
} finally {
outputStream?.Dispose ();
}
return 0;
}
}
#endif
public enum ApiDiffFormatter {
Html,
Markdown,
}
public class ApiDiffFormattedConfig {
public ApiDiffFormatter Formatter { get; set; }
public List<Regex> IgnoreAdded { get; set; } = new List<Regex> ();
public List<Regex> IgnoreNew { get; set; } = new List<Regex> ();
public List<Regex> IgnoreRemoved { get; set; } = new List<Regex> ();
public bool IgnoreParameterNameChanges { get; set; }
public bool IgnoreVirtualChanges { get; set; }
public bool IgnoreAddedPropertySetters { get; set; }
public bool IgnoreNonbreaking { get; set; }
public bool IgnoreDuplicateXml { get; set; }
public bool Colorize { get; set; } = true;
internal int Verbosity { get; set; }
}
public static class ApiDiffFormatted {
public static void Generate (Stream firstInfo, Stream secondInfo, TextWriter outStream, ApiDiffFormattedConfig config = null)
{
var state = CreateState (config);
Generate (firstInfo, secondInfo, outStream, state);
}
public static void Generate (string firstInfo, string secondInfo, TextWriter outStream, ApiDiffFormattedConfig config = null)
{
var state = CreateState (config);
Generate (firstInfo, secondInfo, outStream, state);
}
internal static void Generate (string firstInfo, string secondInfo, TextWriter outStream, State state)
{
var ac = new AssemblyComparer (firstInfo, secondInfo, state);
Generate (ac, outStream, state);
}
internal static void Generate (Stream firstInfo, Stream secondInfo, TextWriter outStream, State state)
{
var ac = new AssemblyComparer (firstInfo, secondInfo, state);
Generate (ac, outStream, state);
}
static void Generate (AssemblyComparer ac, TextWriter outStream, State state)
{
var diffHtml = String.Empty;
using (var writer = new StringWriter ()) {
state.Output = writer;
ac.Compare ();
diffHtml = state.Output.ToString ();
}
if (diffHtml.Length > 0) {
var title = $"{ac.SourceAssembly}.dll";
if (ac.SourceAssembly != ac.TargetAssembly)
title += $" vs {ac.TargetAssembly}.dll";
state.Formatter.BeginDocument (outStream, $"API diff: {title}");
state.Formatter.BeginAssembly (outStream);
outStream.Write (diffHtml);
state.Formatter.EndAssembly (outStream);
state.Formatter.EndDocument (outStream);
}
}
static State CreateState (ApiDiffFormattedConfig config)
{
if (config == null)
config = new ApiDiffFormattedConfig ();
var state = new State {
Colorize = config.Colorize,
Formatter = null,
IgnoreAddedPropertySetters = config.IgnoreAddedPropertySetters,
IgnoreVirtualChanges = config.IgnoreVirtualChanges,
IgnoreNonbreaking = config.IgnoreNonbreaking,
IgnoreParameterNameChanges = config.IgnoreParameterNameChanges,
Lax = config.IgnoreDuplicateXml,
Verbosity = config.Verbosity
};
state.IgnoreAdded.AddRange (config.IgnoreAdded);
state.IgnoreNew.AddRange (config.IgnoreNew);
state.IgnoreRemoved.AddRange (config.IgnoreRemoved);
switch (config.Formatter)
{
case ApiDiffFormatter.Html:
state.Formatter = new HtmlFormatter(state);
break;
case ApiDiffFormatter.Markdown:
state.Formatter = new MarkdownFormatter(state);
break;
default:
throw new ArgumentException("Invlid formatter specified.");
}
// unless specified default to HTML
if (state.Formatter == null)
state.Formatter = new HtmlFormatter (state);
if (state.IgnoreNonbreaking) {
state.IgnoreAddedPropertySetters = true;
state.IgnoreVirtualChanges = true;
state.IgnoreNew.Add (new Regex (".*"));
state.IgnoreAdded.Add (new Regex (".*"));
}
return state;
}
}
}

View File

@@ -26,21 +26,33 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Linq;
namespace Xamarin.ApiDiff {
namespace Mono.ApiTools {
public class AssemblyComparer : Comparer {
class AssemblyComparer : Comparer {
XDocument source;
XDocument target;
NamespaceComparer comparer;
public AssemblyComparer (string sourceFile, string targetFile)
public AssemblyComparer (string sourceFile, string targetFile, State state)
: this (XDocument.Load(sourceFile), XDocument.Load(targetFile), state)
{
source = XDocument.Load (sourceFile);
target = XDocument.Load (targetFile);
comparer = new NamespaceComparer ();
}
public AssemblyComparer (Stream sourceFile, Stream targetFile, State state)
: this (XDocument.Load(sourceFile), XDocument.Load(targetFile), state)
{
}
public AssemblyComparer (XDocument sourceFile, XDocument targetFile, State state)
: base (state)
{
source = sourceFile;
target = targetFile;
comparer = new NamespaceComparer (state);
}
public string SourceAssembly { get; private set; }

View File

@@ -30,9 +30,9 @@ using System.IO;
using System.Linq;
using System.Xml.Linq;
namespace Xamarin.ApiDiff {
namespace Mono.ApiTools {
public class ClassComparer : Comparer {
class ClassComparer : Comparer {
InterfaceComparer icomparer;
ConstructorComparer ccomparer;
@@ -42,14 +42,15 @@ namespace Xamarin.ApiDiff {
MethodComparer mcomparer;
ClassComparer kcomparer;
public ClassComparer ()
public ClassComparer (State state)
: base (state)
{
icomparer = new InterfaceComparer ();
ccomparer = new ConstructorComparer ();
fcomparer = new FieldComparer ();
pcomparer = new PropertyComparer ();
ecomparer = new EventComparer ();
mcomparer = new MethodComparer ();
icomparer = new InterfaceComparer (state);
ccomparer = new ConstructorComparer (state);
fcomparer = new FieldComparer (state);
pcomparer = new PropertyComparer (state);
ecomparer = new EventComparer (state);
mcomparer = new MethodComparer (state);
}
public override void SetContext (XElement current)
@@ -190,7 +191,7 @@ namespace Xamarin.ApiDiff {
Output.WriteLine ();
Indent ().WriteLine ("// inner types");
State.Parent = State.Type;
kcomparer = new NestedClassComparer ();
kcomparer = new NestedClassComparer (State);
foreach (var inner in t.Elements ("class"))
kcomparer.AddedInner (inner);
State.Type = State.Parent;
@@ -227,7 +228,7 @@ namespace Xamarin.ApiDiff {
!State.IgnoreRemoved.Any (re => re.IsMatch (rm)) &&
!(State.IgnoreNonbreaking && IsBaseChangeCompatible (sb, tb))) {
Formatter.BeginMemberModification (Output, "Modified base type");
var apichange = new ApiChange ($"{State.Namespace}.{State.Type}").AppendModified (sb, tb, true);
var apichange = new ApiChange ($"{State.Namespace}.{State.Type}", State).AppendModified (sb, tb, true);
Formatter.Diff (Output, apichange);
Formatter.EndMemberModification (Output);
}
@@ -242,7 +243,7 @@ namespace Xamarin.ApiDiff {
var si = source.Element ("classes");
if (si != null) {
var ti = target.Element ("classes");
kcomparer = new NestedClassComparer ();
kcomparer = new NestedClassComparer (State);
State.Parent = State.Type;
kcomparer.Compare (si.Elements ("class"), ti == null ? null : ti.Elements ("class"));
State.Type = State.Parent;
@@ -280,7 +281,12 @@ namespace Xamarin.ApiDiff {
}
}
public class NestedClassComparer : ClassComparer {
class NestedClassComparer : ClassComparer {
public NestedClassComparer (State state)
: base (state)
{
}
public override void SetContext (XElement current)
{

View File

@@ -30,19 +30,28 @@ using System.IO;
using System.Linq;
using System.Xml.Linq;
namespace Xamarin.ApiDiff {
namespace Mono.ApiTools {
public abstract class Comparer {
abstract class Comparer {
protected List<XElement> removed = new List<XElement> ();
protected ApiChanges modified = new ApiChanges ();
protected List<XElement> removed;
protected ApiChanges modified;
public Comparer (State state)
{
State = state;
removed = new List<XElement> ();
modified = new ApiChanges (state);
}
public State State { get; }
public TextWriter Output {
get { return State.Output; }
}
public Formatter Formatter {
get { return Formatter.Current; }
get { return State.Formatter; }
}
protected TextWriter Indent ()

View File

@@ -30,10 +30,15 @@ using System.Reflection;
using System.Text;
using System.Xml.Linq;
namespace Xamarin.ApiDiff {
namespace Mono.ApiTools {
// MethodComparer inherits from this one
public class ConstructorComparer : MemberComparer {
class ConstructorComparer : MemberComparer {
public ConstructorComparer (State state)
: base (state)
{
}
public override string GroupName {
get { return "constructors"; }
@@ -50,8 +55,8 @@ namespace Xamarin.ApiDiff {
void RenderReturnType (XElement source, XElement target, ApiChange change)
{
var srcType = source.GetTypeName ("returntype");
var tgtType = target.GetTypeName ("returntype");
var srcType = source.GetTypeName ("returntype", State);
var tgtType = target.GetTypeName ("returntype", State);
if (srcType != tgtType) {
change.AppendModified (srcType, tgtType, true);
@@ -68,7 +73,7 @@ namespace Xamarin.ApiDiff {
if (base.Equals (source, target, changes))
return true;
var change = new ApiChange (GetDescription (source));
var change = new ApiChange (GetDescription (source), State);
change.Header = "Modified " + GroupName;
RenderMethodAttributes (source, target, change);
RenderReturnType (source, target, change);
@@ -106,7 +111,7 @@ namespace Xamarin.ApiDiff {
string name = e.GetAttribute ("name");
var r = e.GetTypeName ("returntype");
var r = e.GetTypeName ("returntype", State);
if (r != null) {
// ctor dont' have a return type
sb.Append (r).Append (' ');
@@ -123,7 +128,7 @@ namespace Xamarin.ApiDiff {
if (genericp != null) {
var list = new List<string> ();
foreach (var p in genericp.Elements ("generic-parameter")) {
list.Add (p.GetTypeName ("name"));
list.Add (p.GetTypeName ("name", State));
}
sb.Append (Formatter.LesserThan).Append (String.Join (", ", list)).Append (Formatter.GreaterThan);
}
@@ -133,7 +138,7 @@ namespace Xamarin.ApiDiff {
if (parameters != null) {
var list = new List<string> ();
foreach (var p in parameters.Elements ("parameter")) {
var param = p.GetTypeName ("type");
var param = p.GetTypeName ("type", State);
if (!State.IgnoreParameterNameChanges)
param += " " + p.GetAttribute ("name");

View File

@@ -28,9 +28,14 @@ using System;
using System.Text;
using System.Xml.Linq;
namespace Xamarin.ApiDiff {
namespace Mono.ApiTools {
public class EventComparer : MemberComparer {
class EventComparer : MemberComparer {
public EventComparer (State state)
: base (state)
{
}
public override string GroupName {
get { return "events"; }
@@ -45,12 +50,12 @@ namespace Xamarin.ApiDiff {
if (base.Equals (source, target, changes))
return true;
var change = new ApiChange (GetDescription (source));
var change = new ApiChange (GetDescription (source), State);
change.Header = "Modified " + GroupName;
change.Append ("public event ");
var srcEventType = source.GetTypeName ("eventtype");
var tgtEventType = target.GetTypeName ("eventtype");
var srcEventType = source.GetTypeName ("eventtype", State);
var tgtEventType = target.GetTypeName ("eventtype", State);
if (srcEventType != tgtEventType) {
change.AppendModified (srcEventType, tgtEventType, true);
@@ -67,7 +72,7 @@ namespace Xamarin.ApiDiff {
StringBuilder sb = new StringBuilder ();
// TODO: attribs
sb.Append ("public event ");
sb.Append (e.GetTypeName ("eventtype")).Append (' ');
sb.Append (e.GetTypeName ("eventtype", State)).Append (' ');
sb.Append (e.GetAttribute ("name")).Append (';');
return sb.ToString ();
}

View File

@@ -31,9 +31,14 @@ using System.Reflection;
using System.Text;
using System.Xml.Linq;
namespace Xamarin.ApiDiff {
namespace Mono.ApiTools {
public class FieldComparer : MemberComparer {
class FieldComparer : MemberComparer {
public FieldComparer (State state)
: base (state)
{
}
public override string GroupName {
get { return "fields"; }
@@ -109,7 +114,7 @@ namespace Xamarin.ApiDiff {
var name = source.GetAttribute ("name");
var srcValue = source.GetAttribute ("value");
var tgtValue = target.GetAttribute ("value");
var change = new ApiChange (GetDescription (source));
var change = new ApiChange (GetDescription (source), State);
change.Header = "Modified " + GroupName;
if (State.BaseType == "System.Enum") {
@@ -122,8 +127,8 @@ namespace Xamarin.ApiDiff {
} else {
RenderFieldAttributes (source.GetFieldAttributes (), target.GetFieldAttributes (), change);
var srcType = source.GetTypeName ("fieldtype");
var tgtType = target.GetTypeName ("fieldtype");
var srcType = source.GetTypeName ("fieldtype", State);
var tgtType = target.GetTypeName ("fieldtype", State);
if (srcType != tgtType) {
change.AppendModified (srcType, tgtType, true);
@@ -184,7 +189,7 @@ namespace Xamarin.ApiDiff {
sb.Append ("const ");
}
string ftype = e.GetTypeName ("fieldtype");
string ftype = e.GetTypeName ("fieldtype", State);
sb.Append (ftype).Append (' ');
sb.Append (name);
if (ftype == "string" && e.Attribute ("value") != null) {

View File

@@ -30,11 +30,16 @@ using System.Collections.Generic;
using System.Xml.Linq;
using System.Text;
namespace Xamarin.ApiDiff {
namespace Mono.ApiTools {
public abstract class Formatter {
abstract class Formatter {
public static Formatter Current { get; set; }
public Formatter(State state)
{
State = state;
}
public State State { get; }
public abstract string LesserThan { get; }
public abstract string GreaterThan { get; }

View File

@@ -31,9 +31,9 @@ using System.Reflection;
using System.Text;
using System.Xml.Linq;
namespace Xamarin.ApiDiff {
namespace Mono.ApiTools {
public static class Helper {
static class Helper {
public static bool IsTrue (this XElement self, string name)
{
return (self.GetAttribute (name) == "true");
@@ -92,7 +92,7 @@ namespace Xamarin.ApiDiff {
}
// make it beautiful (.NET -> C#)
public static string GetTypeName (this XElement self, string name)
public static string GetTypeName (this XElement self, string name, State state)
{
string type = self.GetAttribute (name);
if (type == null)
@@ -121,7 +121,7 @@ namespace Xamarin.ApiDiff {
if (is_pointer)
sb.Remove (sb.Length - 1, 1);
type = GetTypeName (sb.Replace ('+', '.').ToString ());
type = GetTypeName (sb.Replace ('+', '.').ToString (), state);
sb.Length = 0;
if (is_ref)
sb.Append (self.GetAttribute ("direction")).Append (' ');
@@ -137,13 +137,13 @@ namespace Xamarin.ApiDiff {
return sb.ToString ();
}
static string GetTypeName (string type)
static string GetTypeName (string type, State state)
{
int pos = type.IndexOf ('`');
if (pos >= 0) {
int end = type.LastIndexOf (']');
string subtype = type.Substring (pos + 3, end - pos - 3);
return type.Substring (0, pos) + Formatter.Current.LesserThan + GetTypeName (subtype) + Formatter.Current.GreaterThan;
return type.Substring (0, pos) + state.Formatter.LesserThan + GetTypeName (subtype, state) + state.Formatter.GreaterThan;
}
switch (type) {
@@ -180,14 +180,14 @@ namespace Xamarin.ApiDiff {
case "System.nint":
return "nint";
case "System.nuint":
return "uint";
return "nuint";
case "System.nfloat":
return "nfloat";
case "System.IntPtr":
return "IntPtr";
default:
if (type.StartsWith (State.Namespace, StringComparison.Ordinal))
type = type.Substring (State.Namespace.Length + 1);
if (type.StartsWith (state.Namespace, StringComparison.Ordinal))
type = type.Substring (state.Namespace.Length + 1);
return type;
}
}

View File

@@ -32,9 +32,14 @@ using System.Linq;
using System.Xml.Linq;
using System.Text;
namespace Xamarin.ApiDiff {
namespace Mono.ApiTools {
public class HtmlFormatter : Formatter {
class HtmlFormatter : Formatter {
public HtmlFormatter (State state)
: base (state)
{
}
public override string LesserThan => "&lt;";
public override string GreaterThan => "&gt;";

View File

@@ -27,9 +27,14 @@
using System;
using System.Xml.Linq;
namespace Xamarin.ApiDiff {
namespace Mono.ApiTools {
public class InterfaceComparer : MemberComparer {
class InterfaceComparer : MemberComparer {
public InterfaceComparer (State state)
: base (state)
{
}
public override string GroupName {
get { return "interfaces"; }
@@ -41,7 +46,7 @@ namespace Xamarin.ApiDiff {
public override string GetDescription (XElement e)
{
return e.GetTypeName ("name");
return e.GetTypeName ("name", State);
}
}
}

View File

@@ -31,9 +31,14 @@ using System.Linq;
using System.Xml.Linq;
using System.Text;
namespace Xamarin.ApiDiff {
namespace Mono.ApiTools {
public class MarkdownFormatter : Formatter {
class MarkdownFormatter : Formatter {
public MarkdownFormatter (State state)
: base (state)
{
}
public override string LesserThan => "<";
public override string GreaterThan => ">";

View File

@@ -31,13 +31,18 @@ using System.Reflection;
using System.Text;
using System.Xml.Linq;
namespace Xamarin.ApiDiff {
namespace Mono.ApiTools {
public abstract class MemberComparer : Comparer {
abstract class MemberComparer : Comparer {
// true if this is the first element being added or removed in the group being rendered
protected bool first;
public MemberComparer (State state)
: base (state)
{
}
public abstract string GroupName { get; }
public abstract string ElementName { get; }
@@ -230,7 +235,7 @@ namespace Xamarin.ApiDiff {
string RenderGenericParameter (XElement gp)
{
var sb = new StringBuilder ();
sb.Append (gp.GetTypeName ("name"));
sb.Append (gp.GetTypeName ("name", State));
var constraints = gp.DescendantList ("generic-parameter-constraints", "generic-parameter-constraint");
if (constraints != null && constraints.Count > 0) {
@@ -238,7 +243,7 @@ namespace Xamarin.ApiDiff {
for (int i = 0; i < constraints.Count; i++) {
if (i > 0)
sb.Append (", ");
sb.Append (constraints [i].GetTypeName ("name"));
sb.Append (constraints [i].GetTypeName ("name", State));
}
}
return sb.ToString ();
@@ -255,7 +260,7 @@ namespace Xamarin.ApiDiff {
return;
change.Append (Formatter.LesserThan);
for (int i = 0; i < Math.Max (srcCount, tgtCount); i++) {
for (int i = 0; i < System.Math.Max (srcCount, tgtCount); i++) {
if (i > 0)
change.Append (", ");
if (i >= srcCount) {
@@ -305,7 +310,7 @@ namespace Xamarin.ApiDiff {
var tgtCount = tgt == null ? 0 : tgt.Count;
change.Append (" (");
for (int i = 0; i < Math.Max (srcCount, tgtCount); i++) {
for (int i = 0; i < System.Math.Max (srcCount, tgtCount); i++) {
if (i > 0)
change.Append (", ");
@@ -319,12 +324,12 @@ namespace Xamarin.ApiDiff {
mods_src = mods_src + " ";
if (i >= srcCount) {
change.AppendAdded (mods_tgt + tgt [i].GetTypeName ("type") + " " + tgt [i].GetAttribute ("name"), true);
change.AppendAdded (mods_tgt + tgt [i].GetTypeName ("type", State) + " " + tgt [i].GetAttribute ("name"), true);
} else if (i >= tgtCount) {
change.AppendRemoved (mods_src + src [i].GetTypeName ("type") + " " + src [i].GetAttribute ("name"), true);
change.AppendRemoved (mods_src + src [i].GetTypeName ("type", State) + " " + src [i].GetAttribute ("name"), true);
} else {
var paramSourceType = src [i].GetTypeName ("type");
var paramTargetType = tgt [i].GetTypeName ("type");
var paramSourceType = src [i].GetTypeName ("type", State);
var paramTargetType = tgt [i].GetTypeName ("type", State);
var paramSourceName = src [i].GetAttribute ("name");
var paramTargetName = tgt [i].GetAttribute ("name");
@@ -564,7 +569,7 @@ namespace Xamarin.ApiDiff {
if (srcObsolete == null) {
if (tgtObsolete == null)
return; // neither is obsolete
var change = new ApiChange (GetDescription (source));
var change = new ApiChange (GetDescription (source), State);
change.Header = "Obsoleted " + GroupName;
Formatter.RenderObsoleteMessage (change.Member, this, GetDescription (target), tgtObsolete);
change.AnyChange = true;

View File

@@ -29,9 +29,14 @@ using System.Linq;
using System.Reflection;
using System.Xml.Linq;
namespace Xamarin.ApiDiff {
namespace Mono.ApiTools {
public class MethodComparer : ConstructorComparer {
class MethodComparer : ConstructorComparer {
public MethodComparer (State state)
: base (state)
{
}
public override string GroupName {
get { return "methods"; }

View File

@@ -30,15 +30,16 @@ using System.IO;
using System.Linq;
using System.Xml.Linq;
namespace Xamarin.ApiDiff {
namespace Mono.ApiTools {
public class NamespaceComparer : Comparer {
class NamespaceComparer : Comparer {
ClassComparer comparer;
public NamespaceComparer ()
public NamespaceComparer (State state)
: base (state)
{
comparer = new ClassComparer ();
comparer = new ClassComparer (state);
}
public void Compare (XElement source, XElement target)

View File

@@ -30,9 +30,14 @@ using System.Reflection;
using System.Text;
using System.Xml.Linq;
namespace Xamarin.ApiDiff {
namespace Mono.ApiTools {
public class PropertyComparer : MemberComparer {
class PropertyComparer : MemberComparer {
public PropertyComparer (State state)
: base (state)
{
}
public override string GroupName {
get { return "properties"; }
@@ -83,7 +88,7 @@ namespace Xamarin.ApiDiff {
var s = sAttr & MethodAttributes.MemberAccessMask;
// Visibility is ordered numerically (higher value = more visible).
// We want the most visible.
var visibility = (MethodAttributes) Math.Max ((int) g, (int) s);
var visibility = (MethodAttributes) System.Math.Max ((int) g, (int) s);
// Do a bitwise or with the rest of the flags
var g_no_visibility = gAttr & ~MethodAttributes.MemberAccessMask;
var s_no_visibility = sAttr & ~MethodAttributes.MemberAccessMask;
@@ -92,8 +97,8 @@ namespace Xamarin.ApiDiff {
void RenderPropertyType (XElement source, XElement target, ApiChange change)
{
var srcType = source.GetTypeName ("ptype");
var tgtType = target.GetTypeName ("ptype");
var srcType = source.GetTypeName ("ptype", State);
var tgtType = target.GetTypeName ("ptype", State);
if (srcType == tgtType) {
change.Append (tgtType);
@@ -146,8 +151,8 @@ namespace Xamarin.ApiDiff {
if (i > 0)
change.Append (", ");
var srcType = source.GetTypeName ("type");
var tgtType = target.GetTypeName ("type");
var srcType = source.GetTypeName ("type", State);
var tgtType = target.GetTypeName ("type", State);
if (srcType == tgtType) {
change.Append (tgtType);
} else {
@@ -185,7 +190,7 @@ namespace Xamarin.ApiDiff {
isIndexer = srcIndexers != null && srcIndexers.Count > 0;
}
var change = new ApiChange (GetDescription (source));
var change = new ApiChange (GetDescription (source), State);
change.Header = "Modified " + GroupName;
RenderMethodAttributes (GetMethodAttributes (srcGetter, srcSetter), GetMethodAttributes (tgtGetter, tgtSetter), change);
RenderPropertyType (source, target, change);
@@ -224,7 +229,7 @@ namespace Xamarin.ApiDiff {
public override string GetDescription (XElement e)
{
string name = e.Attribute ("name").Value;
string ptype = e.GetTypeName ("ptype");
string ptype = e.GetTypeName ("ptype", State);
bool virt = false;
bool over = false;