Merge branch 'upstream'

Former-commit-id: d4b7501d09bd543ab2c6366f93320f9314418dbb
This commit is contained in:
Xamarin Public Jenkins (auto-signing) 2018-06-02 09:02:10 +00:00
commit 7af66c45bb
48 changed files with 710 additions and 260 deletions

View File

@ -1 +1 @@
f2975e434fb9a78dbc5f2ccc946c7cbf285a3a46
9c6dc460572d6a61d53cad8962f5f2cbc2bf2744

View File

@ -1 +1 @@
71862039cdd700167d24ff50835960834c3faaf5
de061369386bf75c7f5de5d21bc81daffaac357e

View File

@ -34,7 +34,7 @@ static class Consts
// Use these assembly version constants to make code more maintainable.
//
public const string MonoVersion = "5.14.0.116";
public const string MonoVersion = "5.14.0.121";
public const string MonoCompany = "Mono development team";
public const string MonoProduct = "Mono Common Language Infrastructure";
public const string MonoCopyright = "(c) Various Mono authors";

View File

@ -1 +1 @@
88463079f1bc9e293ff4eeffc52b8fe7ddb4b61d
09ec0df8466f5935dd3109d5702a6e5a0e7d11cc

View File

@ -1 +1 @@
69022cbbe03b81539b541184bb204f1027e88e47
a5407a65a42139eac82ff8531f3941a3c30b3c6e

View File

@ -1 +1 @@
abf20bddd551faa4c03903b90d5ef125923a6a58
f1e8c1f280e9ff9af702f512cdbca81dc786a827

View File

@ -1 +1 @@
3a253a3488929d890119bb844ed58e36e6a9b20d
edaf454cb91d45a177854f2fb969577a7dd2e73e

View File

@ -1 +1 @@
f9d99688c9ea9c2a3c6d751ebcc47a65e35f4cd1
c30b91929a614ec4b2e8d7c5e1450292ad0e927d

View File

@ -1 +1 @@
d5beee2f9672bee46acd54553c2a6cf4f66d4a57
a256efa8af047b3a388540cf6f2c6d89220b2907

View File

@ -1 +1 @@
fccf96191cc72249f43f2d18d25931f1aba8b06b
c6ad5451a7b726d21eed3052d4f9ec42d4ebf2ad

View File

@ -1 +1 @@
88463079f1bc9e293ff4eeffc52b8fe7ddb4b61d
09ec0df8466f5935dd3109d5702a6e5a0e7d11cc

View File

@ -1 +1 @@
69022cbbe03b81539b541184bb204f1027e88e47
a5407a65a42139eac82ff8531f3941a3c30b3c6e

View File

@ -1 +1 @@
abf20bddd551faa4c03903b90d5ef125923a6a58
f1e8c1f280e9ff9af702f512cdbca81dc786a827

View File

@ -1 +1 @@
3a253a3488929d890119bb844ed58e36e6a9b20d
edaf454cb91d45a177854f2fb969577a7dd2e73e

View File

@ -1 +1 @@
f9d99688c9ea9c2a3c6d751ebcc47a65e35f4cd1
c30b91929a614ec4b2e8d7c5e1450292ad0e927d

View File

@ -1 +1 @@
d5beee2f9672bee46acd54553c2a6cf4f66d4a57
a256efa8af047b3a388540cf6f2c6d89220b2907

View File

@ -1 +1 @@
fccf96191cc72249f43f2d18d25931f1aba8b06b
c6ad5451a7b726d21eed3052d4f9ec42d4ebf2ad

View File

@ -1 +1 @@
88463079f1bc9e293ff4eeffc52b8fe7ddb4b61d
09ec0df8466f5935dd3109d5702a6e5a0e7d11cc

View File

@ -1 +1 @@
69022cbbe03b81539b541184bb204f1027e88e47
a5407a65a42139eac82ff8531f3941a3c30b3c6e

View File

@ -1 +1 @@
abf20bddd551faa4c03903b90d5ef125923a6a58
f1e8c1f280e9ff9af702f512cdbca81dc786a827

View File

@ -1 +1 @@
3a253a3488929d890119bb844ed58e36e6a9b20d
edaf454cb91d45a177854f2fb969577a7dd2e73e

View File

@ -1 +1 @@
f9d99688c9ea9c2a3c6d751ebcc47a65e35f4cd1
c30b91929a614ec4b2e8d7c5e1450292ad0e927d

View File

@ -1 +1 @@
d5beee2f9672bee46acd54553c2a6cf4f66d4a57
a256efa8af047b3a388540cf6f2c6d89220b2907

View File

@ -1 +1 @@
fccf96191cc72249f43f2d18d25931f1aba8b06b
c6ad5451a7b726d21eed3052d4f9ec42d4ebf2ad

View File

@ -28,9 +28,7 @@ namespace Xamarin.ApiDiff
public ApiChange AppendAdded (string text, bool breaking = false)
{
Member.Append ("<span class='added ").Append (breaking ? "added-breaking-inline" : string.Empty).Append ("'>");
Member.Append (text);
Member.Append ("</span>");
Formatter.Current.DiffAddition (Member, text, breaking);
Breaking |= breaking;
AnyChange = true;
return this;
@ -38,9 +36,7 @@ namespace Xamarin.ApiDiff
public ApiChange AppendRemoved (string text, bool breaking = true)
{
Member.Append ("<span class='removed removed-inline ").Append (breaking ? "removed-breaking-inline" : string.Empty).Append ("'>");
Member.Append (text);
Member.Append ("</span>");
Formatter.Current.DiffRemoval (Member, text, breaking);
Breaking |= breaking;
AnyChange = true;
return this;
@ -48,12 +44,7 @@ namespace Xamarin.ApiDiff
public ApiChange AppendModified (string old, string @new, bool breaking = true)
{
if (old.Length > 0)
AppendRemoved (old, breaking);
if (old.Length > 0 && @new.Length > 0)
Append (" ");
if (@new.Length > 0)
AppendAdded (@new);
Formatter.Current.DiffModification (Member, old, @new, breaking);
Breaking |= breaking;
AnyChange = true;
return this;

View File

@ -7,9 +7,10 @@
// that gdiff.sh produced
//
// Authors
// Sebastien Pouliot <sebastien@xamarin.com>
// Sebastien Pouliot <sebastien.pouliot@microsoft.com>
//
// Copyright 2013-2014 Xamarin Inc. http://www.xamarin.com
// Copyright 2018 Microsoft Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
@ -56,6 +57,7 @@ namespace Xamarin.ApiDiff {
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; }
@ -134,6 +136,7 @@ namespace Xamarin.ApiDiff {
{ "ignore-nonbreaking", "Ignore all nonbreaking changes", v => State.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 (),
};
@ -144,6 +147,10 @@ namespace Xamarin.ApiDiff {
showHelp = true;
}
// unless specified default to HTML
if (Formatter.Current == null)
Formatter.Current = new HtmlFormatter ();
if (State.IgnoreNonbreaking) {
State.IgnoreAddedPropertySetters = true;
State.IgnoreVirtualChanges = true;
@ -189,100 +196,14 @@ namespace Xamarin.ApiDiff {
}
if (diffHtml.Length > 0) {
using (var file = new StreamWriter (diff)) {
file.WriteLine ("<div>");
if (State.Colorize) {
file.WriteLine ("<style scoped>");
file.WriteLine ("\t.obsolete { color: gray; }");
file.WriteLine ("\t.added { color: green; }");
file.WriteLine ("\t.removed-inline { text-decoration: line-through; }");
file.WriteLine ("\t.removed-breaking-inline { color: red;}");
file.WriteLine ("\t.added-breaking-inline { text-decoration: underline; }");
file.WriteLine ("\t.nonbreaking { color: black; }");
file.WriteLine ("\t.breaking { color: red; }");
file.WriteLine ("</style>");
}
file.WriteLine (
@"<script type=""text/javascript"">
// Only some elements have 'data-is-[non-]breaking' attributes. Here we
// iterate over all descendents elements, and set 'data-is-[non-]breaking'
// depending on whether there are any descendents with that attribute.
function propagateDataAttribute (element)
{
if (element.hasAttribute ('data-is-propagated'))
return;
var i;
var any_breaking = element.hasAttribute ('data-is-breaking');
var any_non_breaking = element.hasAttribute ('data-is-non-breaking');
for (i = 0; i < element.children.length; i++) {
var el = element.children [i];
propagateDataAttribute (el);
any_breaking |= el.hasAttribute ('data-is-breaking');
any_non_breaking |= el.hasAttribute ('data-is-non-breaking');
}
if (any_breaking)
element.setAttribute ('data-is-breaking', null);
else if (any_non_breaking)
element.setAttribute ('data-is-non-breaking', null);
element.setAttribute ('data-is-propagated', null);
}
function hideNonBreakingChanges ()
{
var topNodes = document.querySelectorAll ('[data-is-topmost]');
var n;
var i;
for (n = 0; n < topNodes.length; n++) {
propagateDataAttribute (topNodes [n]);
var elements = topNodes [n].querySelectorAll ('[data-is-non-breaking]');
for (i = 0; i < elements.length; i++) {
var el = elements [i];
if (!el.hasAttribute ('data-original-display'))
el.setAttribute ('data-original-display', el.style.display);
el.style.display = 'none';
}
}
var links = document.getElementsByClassName ('hide-nonbreaking');
for (i = 0; i < links.length; i++)
links [i].style.display = 'none';
links = document.getElementsByClassName ('restore-nonbreaking');
for (i = 0; i < links.length; i++)
links [i].style.display = '';
}
function showNonBreakingChanges ()
{
var elements = document.querySelectorAll ('[data-original-display]');
var i;
for (i = 0; i < elements.length; i++) {
var el = elements [i];
el.style.display = el.getAttribute ('data-original-display');
}
var links = document.getElementsByClassName ('hide-nonbreaking');
for (i = 0; i < links.length; i++)
links [i].style.display = '';
links = document.getElementsByClassName ('restore-nonbreaking');
for (i = 0; i < links.length; i++)
links [i].style.display = 'none';
}
</script>");
if (ac.SourceAssembly == ac.TargetAssembly) {
file.WriteLine ("<h1>{0}.dll</h1>", ac.SourceAssembly);
} else {
file.WriteLine ("<h1>{0}.dll vs {1}.dll</h1>", ac.SourceAssembly, ac.TargetAssembly);
}
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>");
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);
file.WriteLine ("</div> <!-- end topmost div -->");
file.WriteLine ("</div>");
Formatter.Current.EndAssembly (file);
Formatter.Current.EndDocument (file);
}
}
} else {

View File

@ -69,18 +69,15 @@ namespace Xamarin.ApiDiff {
public override void Added (XElement target, bool wasParentAdded)
{
string name = target.Attribute ("name").Value;
var addedDescription = $"{State.Namespace}.{name}: Added type";
var addedDescription = $"{State.Namespace}.{State.Type}: Added type";
State.LogDebugMessage ($"Possible -n value: {addedDescription}");
if (State.IgnoreNew.Any (re => re.IsMatch (addedDescription)))
return;
Output.WriteLine ("<div> <!-- start type {0} -->", name);
Output.WriteLine ("<h3>New Type {0}.{1}</h3>", State.Namespace, name);
Output.WriteLine ("<pre class='added' data-is-non-breaking>");
Formatter.BeginTypeAddition (Output);
State.Indent = 0;
AddedInner (target);
Output.WriteLine ("</pre>");
Output.WriteLine ("</div> <!-- end type {0} -->", name);
Formatter.EndTypeAddition (Output);
}
public void AddedInner (XElement target)
@ -149,9 +146,10 @@ namespace Xamarin.ApiDiff {
Output.WriteLine (" {");
State.Indent++;
var t = target.Element ("constructors");
if (t != null) {
Indent ().WriteLine ("\t// constructors");
Indent ().WriteLine ("// constructors");
foreach (var ctor in t.Elements ("constructor"))
ccomparer.Added (ctor, true);
}
@ -159,7 +157,7 @@ namespace Xamarin.ApiDiff {
t = target.Element ("fields");
if (t != null) {
if (type != "enum")
Indent ().WriteLine ("\t// fields");
Indent ().WriteLine ("// fields");
else
SetContext (target);
foreach (var field in t.Elements ("field"))
@ -168,21 +166,21 @@ namespace Xamarin.ApiDiff {
t = target.Element ("properties");
if (t != null) {
Indent ().WriteLine ("\t// properties");
Indent ().WriteLine ("// properties");
foreach (var property in t.Elements ("property"))
pcomparer.Added (property, true);
}
t = target.Element ("events");
if (t != null) {
Indent ().WriteLine ("\t// events");
Indent ().WriteLine ("// events");
foreach (var evnt in t.Elements ("event"))
ecomparer.Added (evnt, true);
}
t = target.Element ("methods");
if (t != null) {
Indent ().WriteLine ("\t// methods");
Indent ().WriteLine ("// methods");
foreach (var method in t.Elements ("method"))
mcomparer.Added (method, true);
}
@ -190,13 +188,14 @@ namespace Xamarin.ApiDiff {
t = target.Element ("classes");
if (t != null) {
Output.WriteLine ();
Indent ().WriteLine ("\t// inner types");
Indent ().WriteLine ("// inner types");
State.Parent = State.Type;
kcomparer = new NestedClassComparer ();
State.Indent++;
foreach (var inner in t.Elements ("class"))
kcomparer.AddedInner (inner);
State.Indent--;
State.Type = State.Parent;
}
State.Indent--;
Indent ().WriteLine ("}");
}
@ -227,8 +226,10 @@ namespace Xamarin.ApiDiff {
if (sb != tb &&
!State.IgnoreRemoved.Any (re => re.IsMatch (rm)) &&
!(State.IgnoreNonbreaking && IsBaseChangeCompatible (sb, tb))) {
Output.Write ("Modified base type: ");
Output.WriteLine (new ApiChange ($"{State.Namespace}.{State.Type}").AppendModified (sb, tb, true).Member.ToString ());
Formatter.BeginMemberModification (Output, "Modified base type");
var apichange = new ApiChange ($"{State.Namespace}.{State.Type}").AppendModified (sb, tb, true);
Formatter.Diff (Output, apichange);
Formatter.EndMemberModification (Output);
}
ccomparer.Compare (source, target);
@ -242,17 +243,18 @@ namespace Xamarin.ApiDiff {
if (si != null) {
var ti = target.Element ("classes");
kcomparer = new NestedClassComparer ();
State.Parent = State.Type;
kcomparer.Compare (si.Elements ("class"), ti == null ? null : ti.Elements ("class"));
State.Type = State.Parent;
}
var s = (Output as StringWriter).ToString ();
State.Output = output;
if (s.Length > 0) {
var tn = GetTypeName (target);
Output.WriteLine ("<!-- start type {0} --> <div>", tn);
Output.WriteLine ("<h3>Type Changed: {0}.{1}</h3>", State.Namespace, GetTypeName (target));
SetContext (target);
Formatter.BeginTypeModification (Output);
Output.WriteLine (s);
Output.WriteLine ("</div> <!-- end type {0} -->", tn);
Formatter.EndTypeModification (Output);
}
}
@ -261,14 +263,15 @@ namespace Xamarin.ApiDiff {
if (source.Elements ("attributes").SelectMany (a => a.Elements ("attribute")).Any (c => c.Attribute ("name")?.Value == "System.ObsoleteAttribute"))
return;
string name = State.Namespace + "." + GetTypeName (source);
string name = State.Namespace + "." + State.Type;
var memberDescription = $"{name}: Removed type";
State.LogDebugMessage ($"Possible -r value: {memberDescription}");
if (State.IgnoreRemoved.Any (re => re.IsMatch (name)))
return;
Output.Write ("<h3>Removed Type <span class='breaking' data-is-breaking>{0}</span></h3>", name);
Formatter.BeginTypeRemoval (Output);
Formatter.EndTypeRemoval (Output);
}
public virtual string GetTypeName (XElement type)
@ -281,11 +284,13 @@ namespace Xamarin.ApiDiff {
public override void SetContext (XElement current)
{
State.Type = State.Parent + "." + current.GetAttribute ("name");
State.BaseType = current.GetAttribute ("base");
}
public override string GetTypeName (XElement type)
{
return State.Type + "." + base.GetTypeName (type);
return State.Parent + "." + base.GetTypeName (type);
}
}
}
}

View File

@ -41,6 +41,10 @@ namespace Xamarin.ApiDiff {
get { return State.Output; }
}
public Formatter Formatter {
get { return Formatter.Current; }
}
protected TextWriter Indent ()
{
for (int i = 0; i < State.Indent; i++)

View File

@ -125,7 +125,7 @@ namespace Xamarin.ApiDiff {
foreach (var p in genericp.Elements ("generic-parameter")) {
list.Add (p.GetTypeName ("name"));
}
sb.Append ("&lt;").Append (String.Join (", ", list)).Append ("&gt;");
sb.Append (Formatter.LesserThan).Append (String.Join (", ", list)).Append (Formatter.GreaterThan);
}
sb.Append (" (");

View File

@ -186,28 +186,5 @@ namespace Xamarin.ApiDiff {
return sb.ToString ();
}
public override void BeforeAdding (IEnumerable<XElement> list)
{
first = true;
if (State.BaseType == "System.Enum") {
Output.WriteLine ("<div>");
Output.WriteLine ("<p>Added value{0}:</p>", list.Count () > 1 ? "s" : String.Empty);
Output.WriteLine ("<pre class='added' data-is-non-breaking>");
} else {
base.BeforeAdding (list);
}
}
public override void BeforeRemoving (IEnumerable<XElement> list)
{
first = true;
if (State.BaseType == "System.Enum") {
Output.WriteLine ("<p>Removed value{0}:</p>", list.Count () > 1 ? "s" : String.Empty);
Output.WriteLine ("<pre class='removed' data-is-breaking>");
} else {
base.BeforeRemoving (list);
}
}
}
}

View File

@ -0,0 +1,88 @@
//
// Authors
// Sebastien Pouliot <sebastien@xamarin.com>
//
// Copyright 2018 Microsoft Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.IO;
using System.Collections.Generic;
using System.Xml.Linq;
using System.Text;
namespace Xamarin.ApiDiff {
public abstract class Formatter {
public static Formatter Current { get; set; }
public abstract string LesserThan { get; }
public abstract string GreaterThan { get; }
public abstract void BeginDocument (TextWriter output, string title);
public virtual void EndDocument (TextWriter output)
{
}
public abstract void BeginAssembly (TextWriter output);
public virtual void EndAssembly (TextWriter output)
{
}
public abstract void BeginNamespace (TextWriter output, string action = "");
public virtual void EndNamespace (TextWriter output)
{
}
public abstract void BeginTypeAddition (TextWriter output);
public abstract void EndTypeAddition (TextWriter output);
public abstract void BeginTypeModification (TextWriter output);
public virtual void EndTypeModification (TextWriter output)
{
}
public abstract void BeginTypeRemoval (TextWriter output);
public virtual void EndTypeRemoval (TextWriter output)
{
}
public abstract void BeginMemberAddition (TextWriter output, IEnumerable<XElement> list, MemberComparer member);
public abstract void AddMember (TextWriter output, MemberComparer member, bool isInterfaceBreakingChange, string obsolete, string description);
public abstract void EndMemberAddition (TextWriter output);
public abstract void BeginMemberModification (TextWriter output, string sectionName);
public abstract void EndMemberModification (TextWriter output);
public abstract void BeginMemberRemoval (TextWriter output, IEnumerable<XElement> list, MemberComparer member);
public abstract void RemoveMember (TextWriter output, MemberComparer member, bool breaking, string obsolete, string description);
public abstract void EndMemberRemoval (TextWriter output);
public abstract void RenderObsoleteMessage (StringBuilder output, MemberComparer member, string description, string optionalObsoleteMessage);
public abstract void DiffAddition (StringBuilder output, string text, bool breaking);
public abstract void DiffModification (StringBuilder output, string old, string @new, bool breaking);
public abstract void DiffRemoval (StringBuilder output, string text, bool breaking);
public abstract void Diff (TextWriter output, ApiChange apichange);
}
}

View File

@ -143,7 +143,7 @@ namespace Xamarin.ApiDiff {
if (pos >= 0) {
int end = type.LastIndexOf (']');
string subtype = type.Substring (pos + 3, end - pos - 3);
return type.Substring (0, pos) + "&lt;" + GetTypeName (subtype) + "&gt;";
return type.Substring (0, pos) + Formatter.Current.LesserThan + GetTypeName (subtype) + Formatter.Current.GreaterThan;
}
switch (type) {

View File

@ -0,0 +1,308 @@
//
// Authors
// Sebastien Pouliot <sebastien@xamarin.com>
//
// Copyright 2013 Xamarin Inc. http://www.xamarin.com
// Copyright 2018 Microsoft Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using System.Text;
namespace Xamarin.ApiDiff {
public class HtmlFormatter : Formatter {
public override string LesserThan => "&lt;";
public override string GreaterThan => "&gt;";
protected void Indent (TextWriter output)
{
for (int i = 0; i < State.Indent; i++)
output.Write ("\t");
}
public override void BeginDocument (TextWriter output, string title)
{
output.WriteLine ("<div>");
if (State.Colorize) {
output.WriteLine ("<style scoped>");
output.WriteLine ("\t.obsolete { color: gray; }");
output.WriteLine ("\t.added { color: green; }");
output.WriteLine ("\t.removed-inline { text-decoration: line-through; }");
output.WriteLine ("\t.removed-breaking-inline { color: red;}");
output.WriteLine ("\t.added-breaking-inline { text-decoration: underline; }");
output.WriteLine ("\t.nonbreaking { color: black; }");
output.WriteLine ("\t.breaking { color: red; }");
output.WriteLine ("</style>");
}
output.WriteLine (
@"<script type=""text/javascript"">
// Only some elements have 'data-is-[non-]breaking' attributes. Here we
// iterate over all descendents elements, and set 'data-is-[non-]breaking'
// depending on whether there are any descendents with that attribute.
function propagateDataAttribute (element)
{
if (element.hasAttribute ('data-is-propagated'))
return;
var i;
var any_breaking = element.hasAttribute ('data-is-breaking');
var any_non_breaking = element.hasAttribute ('data-is-non-breaking');
for (i = 0; i < element.children.length; i++) {
var el = element.children [i];
propagateDataAttribute (el);
any_breaking |= el.hasAttribute ('data-is-breaking');
any_non_breaking |= el.hasAttribute ('data-is-non-breaking');
}
if (any_breaking)
element.setAttribute ('data-is-breaking', null);
else if (any_non_breaking)
element.setAttribute ('data-is-non-breaking', null);
element.setAttribute ('data-is-propagated', null);
}
function hideNonBreakingChanges ()
{
var topNodes = document.querySelectorAll ('[data-is-topmost]');
var n;
var i;
for (n = 0; n < topNodes.length; n++) {
propagateDataAttribute (topNodes [n]);
var elements = topNodes [n].querySelectorAll ('[data-is-non-breaking]');
for (i = 0; i < elements.length; i++) {
var el = elements [i];
if (!el.hasAttribute ('data-original-display'))
el.setAttribute ('data-original-display', el.style.display);
el.style.display = 'none';
}
}
var links = document.getElementsByClassName ('hide-nonbreaking');
for (i = 0; i < links.length; i++)
links [i].style.display = 'none';
links = document.getElementsByClassName ('restore-nonbreaking');
for (i = 0; i < links.length; i++)
links [i].style.display = '';
}
function showNonBreakingChanges ()
{
var elements = document.querySelectorAll ('[data-original-display]');
var i;
for (i = 0; i < elements.length; i++) {
var el = elements [i];
el.style.display = el.getAttribute ('data-original-display');
}
var links = document.getElementsByClassName ('hide-nonbreaking');
for (i = 0; i < links.length; i++)
links [i].style.display = '';
links = document.getElementsByClassName ('restore-nonbreaking');
for (i = 0; i < links.length; i++)
links [i].style.display = 'none';
}
</script>");
}
public override void BeginAssembly (TextWriter output)
{
output.WriteLine ($"<h1>{State.Assembly}.dll</h1>");
if (!State.IgnoreNonbreaking) {
output.WriteLine ("<a href='javascript: hideNonBreakingChanges (); ' class='hide-nonbreaking'>Hide non-breaking changes</a>");
output.WriteLine ("<a href='javascript: showNonBreakingChanges (); ' class='restore-nonbreaking' style='display: none;'>Show non-breaking changes</a>");
output.WriteLine ("<br/>");
}
output.WriteLine ("<div data-is-topmost>");
}
public override void EndAssembly (TextWriter output)
{
output.WriteLine ("</div> <!-- end topmost div -->");
output.WriteLine ("</div>");
}
public override void BeginNamespace (TextWriter output, string action)
{
output.WriteLine ($"<!-- start namespace {State.Namespace} --> <div>");
output.WriteLine ($"<h2>{action}Namespace {State.Namespace}</h2>");
}
public override void EndNamespace (TextWriter output)
{
output.WriteLine ($"</div> <!-- end namespace {State.Namespace} -->");
}
public override void BeginTypeAddition (TextWriter output)
{
output.WriteLine ($"<div> <!-- start type {State.Type} -->");
output.WriteLine ($"<h3>New Type {State.Namespace}.{State.Type}</h3>");
output.WriteLine ("<pre class='added' data-is-non-breaking>");
}
public override void EndTypeAddition (TextWriter output)
{
output.WriteLine ("</pre>");
output.WriteLine ($"</div> <!-- end type {State.Type} -->");
}
public override void BeginTypeModification (TextWriter output)
{
output.WriteLine ($"<!-- start type {State.Type} --> <div>");
output.WriteLine ($"<h3>Type Changed: {State.Namespace}.{State.Type}</h3>");
}
public override void EndTypeModification (TextWriter output)
{
output.WriteLine ($"</div> <!-- end type {State.Type} -->");
}
public override void BeginTypeRemoval (TextWriter output)
{
output.Write ($"<h3>Removed Type <span class='breaking' data-is-breaking>{State.Namespace}.{State.Type}</span></h3>");
}
public override void BeginMemberAddition (TextWriter output, IEnumerable<XElement> list, MemberComparer member)
{
output.WriteLine ("<div>");
if (State.BaseType == "System.Enum") {
output.WriteLine ("<p>Added value{0}:</p>", list.Count () > 1 ? "s" : String.Empty);
output.WriteLine ("<pre class='added' data-is-non-breaking>");
} else {
output.WriteLine ("<p>Added {0}:</p>", list.Count () > 1 ? member.GroupName : member.ElementName);
output.WriteLine ("<pre>");
}
State.Indent++;
}
public override void AddMember (TextWriter output, MemberComparer member, bool isInterfaceBreakingChange, string obsolete, string description)
{
output.Write ("<span class='added added-{0} {1}' {2}>", member.ElementName, isInterfaceBreakingChange ? "breaking" : string.Empty, isInterfaceBreakingChange ? "data-is-breaking" : "data-is-non-breaking");
output.Write ($"{obsolete}{description}");
output.WriteLine ("</span>");
}
public override void EndMemberAddition (TextWriter output)
{
State.Indent--;
output.WriteLine ("</pre>");
output.WriteLine ("</div>");
}
public override void BeginMemberModification (TextWriter output, string sectionName)
{
output.WriteLine ($"<p>{sectionName}:</p>");
output.WriteLine ("<pre>");
}
public override void EndMemberModification (TextWriter output)
{
output.WriteLine ("</pre>");
}
public override void BeginMemberRemoval (TextWriter output, IEnumerable<XElement> list, MemberComparer member)
{
if (State.BaseType == "System.Enum") {
output.WriteLine ("<p>Removed value{0}:</p>", list.Count () > 1 ? "s" : String.Empty);
output.WriteLine ("<pre class='removed' data-is-breaking>");
} else {
output.WriteLine ("<p>Removed {0}:</p>\n", list.Count () > 1 ? member.GroupName : member.ElementName);
output.WriteLine ("<pre>");
}
State.Indent++;
}
public override void RemoveMember (TextWriter output, MemberComparer member, bool breaking, string obsolete, string description)
{
Indent (output);
output.Write ("<span class='removed removed-{0} {2}' {1}>", member.ElementName, breaking ? "data-is-breaking" : "data-is-non-breaking", breaking ? "breaking" : string.Empty);
if (obsolete.Length > 0) {
output.Write (obsolete);
Indent (output);
}
output.Write (description);
output.WriteLine ("</span>");
}
public override void RenderObsoleteMessage (StringBuilder output, MemberComparer member, string description, string optionalObsoleteMessage)
{
output.Append ($"<span class='obsolete obsolete-{member.ElementName}' data-is-non-breaking>");
output.Append ("[Obsolete (");
if (!String.IsNullOrEmpty (optionalObsoleteMessage))
output.Append ('"').Append (optionalObsoleteMessage).Append ('"');
output.AppendLine (")]");
output.Append (description);
output.Append ("</span>");
}
public override void EndMemberRemoval (TextWriter output)
{
State.Indent--;
output.WriteLine ("</pre>");;
}
public override void DiffAddition (StringBuilder output, string text, bool breaking)
{
output.Append ("<span class='added ");
if (breaking)
output.Append ("added-breaking-inline");
output.Append ("'>");
output.Append (text);
output.Append ("</span>");
}
public override void DiffModification (StringBuilder output, string old, string @new, bool breaking)
{
if (old.Length > 0)
DiffRemoval (output, old, breaking);
if (old.Length > 0 && @new.Length > 0)
output.Append (' ');
if (@new.Length > 0)
DiffAddition (output, @new, false);
}
public override void DiffRemoval (StringBuilder output, string text, bool breaking)
{
output.Append ("<span class='removed removed-inline ");
if (breaking)
output.Append ("removed-breaking-inline");
output.Append ("'>");
output.Append (text);
output.Append ("</span>");
}
public override void Diff (TextWriter output, ApiChange apichange)
{
output.Write ("<div {0}>", apichange.Breaking ? "data-is-breaking" : "data-is-non-breaking");
foreach (var line in apichange.Member.ToString ().Split ('\n')) {
output.Write ('\t');
output.WriteLine (line);
}
output.Write ("</div>");
}
}
}

View File

@ -0,0 +1,199 @@
//
// Authors
// Sebastien Pouliot <sebastien.pouliot@microsoft.com>
//
// Copyright 2018 Microsoft Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using System.Text;
namespace Xamarin.ApiDiff {
public class MarkdownFormatter : Formatter {
public override string LesserThan => "<";
public override string GreaterThan => ">";
public override void BeginDocument (TextWriter output, string title)
{
output.WriteLine ($"# {title}");
output.WriteLine ();
}
public override void BeginAssembly (TextWriter output)
{
// this serves as ToC (table of content) entries so we skip the "Assembly: " prefix
output.WriteLine ($"## {State.Assembly}.dll");
output.WriteLine ();
}
public override void BeginNamespace (TextWriter output, string action)
{
output.WriteLine ($"### {action}Namespace {State.Namespace}");
output.WriteLine ();
}
public override void BeginTypeAddition (TextWriter output)
{
output.WriteLine ($"#### New Type: {@State.Namespace}.{State.Type}");
output.WriteLine ();
output.WriteLine ("```csharp");
}
public override void EndTypeAddition (TextWriter output)
{
output.WriteLine ("```");
output.WriteLine ();
}
public override void BeginTypeModification (TextWriter output)
{
output.WriteLine ($"#### Type Changed: {State.Namespace}.{State.Type}");
output.WriteLine ();
}
public override void BeginTypeRemoval (TextWriter output)
{
output.WriteLine ($"#### Removed Type {State.Namespace}.{State.Type}");
}
public override void BeginMemberAddition (TextWriter output, IEnumerable<XElement> list, MemberComparer member)
{
if (State.BaseType == "System.Enum") {
output.WriteLine ("Added value{0}:", list.Count () > 1 ? "s" : String.Empty);
} else {
output.WriteLine ("Added {0}:", list.Count () > 1 ? member.GroupName : member.ElementName);
}
output.WriteLine ();
output.WriteLine ("```csharp");
}
public override void AddMember (TextWriter output, MemberComparer member, bool isInterfaceBreakingChange, string obsolete, string description)
{
output.Write (obsolete);
output.WriteLine (description);
}
public override void EndMemberAddition (TextWriter output)
{
output.WriteLine ("```");
output.WriteLine ();
}
public override void BeginMemberModification (TextWriter output, string sectionName)
{
output.WriteLine ($"{sectionName}:");
output.WriteLine ();
output.WriteLine ("```diff");
}
public override void EndMemberModification (TextWriter output)
{
output.WriteLine ("```");
output.WriteLine ();
}
public override void BeginMemberRemoval (TextWriter output, IEnumerable<XElement> list, MemberComparer member)
{
if (State.BaseType == "System.Enum") {
output.WriteLine ("Removed value{0}:", list.Count () > 1 ? "s" : String.Empty);
} else {
output.WriteLine ("Removed {0}:", list.Count () > 1 ? member.GroupName : member.ElementName);
}
output.WriteLine ();
output.WriteLine ("```csharp");
}
public override void RemoveMember (TextWriter output, MemberComparer member, bool is_breaking, string obsolete, string description)
{
output.Write (obsolete);
output.WriteLine (description);
}
public override void EndMemberRemoval (TextWriter output)
{
output.WriteLine ("```");
output.WriteLine ();
}
public override void RenderObsoleteMessage (StringBuilder output, MemberComparer member, string description, string optionalObsoleteMessage)
{
output.Append ("[Obsolete (");
if (!String.IsNullOrEmpty (optionalObsoleteMessage))
output.Append ('"').Append (optionalObsoleteMessage).Append ('"');
output.AppendLine (")]");
output.Append (description);
}
string Clean (string line, string remove, string keep)
{
var cleaned = line.Replace (remove, String.Empty);
int s = cleaned.IndexOf (keep, StringComparison.Ordinal);
if (s != -1) {
int e = cleaned.IndexOf (keep, s + keep.Length, StringComparison.Ordinal);
cleaned = cleaned.Remove (s, e - s + keep.Length);
}
while (cleaned.Contains (" "))
cleaned = cleaned.Replace (" ", " ");
return cleaned;
}
public override void DiffAddition (StringBuilder output, string text, bool breaking)
{
output.Append ("+++");
output.Append (text);
output.Append ("+++");
}
public override void DiffModification (StringBuilder output, string old, string @new, bool breaking)
{
if (old.Length > 0)
DiffAddition (output, old, breaking);
if (@new.Length > 0)
DiffRemoval (output, @new, true);
}
public override void DiffRemoval (StringBuilder output, string text, bool breaking)
{
output.Append ("---");
output.Append (text);
output.Append ("---");
}
public override void Diff (TextWriter output, ApiChange apichange)
{
foreach (var line in apichange.Member.ToString ().Split ('\n')) {
if (line.Contains ("+++")) {
output.WriteLine ("-{0}", Clean (line, "+++", "---"));
output.WriteLine ("+{0}", Clean (line, "---", "+++"));
} else {
output.WriteLine (" {0}", line);
}
}
}
}
}

View File

@ -128,13 +128,13 @@ namespace Xamarin.ApiDiff {
if (State.IgnoreAdded.Any (re => re.IsMatch (memberDescription)))
continue;
if (!a) {
BeforeAdding (elements);
Formatter.BeginMemberAddition (Output, elements, this);
a = true;
}
Added (item, false);
}
if (a)
AfterAdding ();
Formatter.EndMemberAddition (Output);
}
void Modify (ApiChanges modified)
@ -142,18 +142,13 @@ namespace Xamarin.ApiDiff {
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>");
Formatter.BeginMemberModification (Output, changes.Key);
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);
Output.Write ("</div>");
Formatter.Diff (Output, element);
}
Output.WriteLine ("</pre>");
Formatter.EndMemberModification (Output);
}
}
@ -169,13 +164,14 @@ namespace Xamarin.ApiDiff {
if (State.IgnoreNonbreaking && !IsBreakingRemoval (item))
continue;
if (!r) {
BeforeRemoving (elements);
Formatter.BeginMemberRemoval (Output, elements, this);
first = true;
r = true;
}
Removed (item);
}
if (r)
AfterRemoving ();
Formatter.EndMemberRemoval (Output);
}
public abstract string GetDescription (XElement e);
@ -189,8 +185,6 @@ namespace Xamarin.ApiDiff {
if (o.Length > 0)
sb.Append (" (\"").Append (o).Append ("\")");
sb.AppendLine ("]");
for (int i = 0; i < State.Indent + 1; i++)
sb.Append ('\t');
}
return sb;
}
@ -206,14 +200,6 @@ namespace Xamarin.ApiDiff {
return base.Equals (source, target, changes);
}
public virtual void BeforeAdding (IEnumerable<XElement> list)
{
first = true;
Output.WriteLine ("<div>");
Output.WriteLine ("<p>Added {0}:</p>", list.Count () > 1 ? GroupName : ElementName);
Output.WriteLine ("<pre>");
}
public override void Added (XElement target, bool wasParentAdded)
{
var o = GetObsoleteMessage (target);
@ -221,29 +207,14 @@ namespace Xamarin.ApiDiff {
Output.WriteLine ();
Indent ();
bool isInterfaceBreakingChange = !wasParentAdded && IsInInterface (target);
Output.Write ("\t<span class='added added-{0} {1}' {2}>", ElementName, isInterfaceBreakingChange ? "breaking" : string.Empty, isInterfaceBreakingChange ? "data-is-breaking" : "data-is-non-breaking");
Output.Write ("{0}{1}", o, GetDescription (target));
Output.WriteLine ("</span>");
Formatter.AddMember (Output, this, isInterfaceBreakingChange, o.ToString (), GetDescription (target));
first = false;
}
public virtual void AfterAdding ()
{
Output.WriteLine ("</pre>");
Output.WriteLine ("</div>");
}
public override void Modified (XElement source, XElement target, ApiChanges change)
{
}
public virtual void BeforeRemoving (IEnumerable<XElement> list)
{
first = true;
Output.WriteLine ("<p>Removed {0}:</p>\n", list.Count () > 1 ? GroupName : ElementName);
Output.WriteLine ("<pre>");
}
public override void Removed (XElement source)
{
var o = GetObsoleteMessage (source);
@ -252,18 +223,10 @@ namespace Xamarin.ApiDiff {
bool is_breaking = IsBreakingRemoval (source);
Indent ();
Output.Write ("\t<span class='removed removed-{0} {2}' {1}>", ElementName, is_breaking ? "data-is-breaking" : "data-is-non-breaking", is_breaking ? "breaking" : string.Empty);
Output.Write ("{0}{1}", o, GetDescription (source));
Output.WriteLine ("</span>");
Formatter.RemoveMember (Output, this, is_breaking, o.ToString (), GetDescription (source));
first = false;
}
public virtual void AfterRemoving ()
{
Output.WriteLine ("</pre>");;
}
string RenderGenericParameter (XElement gp)
{
var sb = new StringBuilder ();
@ -291,7 +254,7 @@ namespace Xamarin.ApiDiff {
if (srcCount == 0 && tgtCount == 0)
return;
change.Append ("&lt;");
change.Append (Formatter.LesserThan);
for (int i = 0; i < Math.Max (srcCount, tgtCount); i++) {
if (i > 0)
change.Append (", ");
@ -310,7 +273,7 @@ namespace Xamarin.ApiDiff {
}
}
}
change.Append ("&gt;");
change.Append (Formatter.GreaterThan);
}
protected string FormatValue (string type, string value)
@ -603,13 +566,7 @@ namespace Xamarin.ApiDiff {
return; // neither is obsolete
var change = new ApiChange (GetDescription (source));
change.Header = "Obsoleted " + GroupName;
change.Append (string.Format ("<span class='obsolete obsolete-{0}' data-is-non-breaking>", ElementName));
change.Append ("[Obsolete (");
if (tgtObsolete != string.Empty)
change.Append ("\"").Append (tgtObsolete).Append ("\"");
change.Append (")]\n");
change.Append (GetDescription (target));
change.Append ("</span>");
Formatter.RenderObsoleteMessage (change.Member, this, GetDescription (target), tgtObsolete);
change.AnyChange = true;
changes.Add (source, target, change);
} else if (tgtObsolete == null) {

View File

@ -57,20 +57,18 @@ namespace Xamarin.ApiDiff {
public override void Added (XElement target, bool wasParentAdded)
{
string name = target.Attribute ("name").Value;
var namespaceDescription = $"{name}: Added namespace";
var namespaceDescription = $"{State.Namespace}: Added namespace";
State.LogDebugMessage ($"Possible -n value: {namespaceDescription}");
if (State.IgnoreNew.Any (re => re.IsMatch (namespaceDescription)))
return;
Output.WriteLine ("<!-- start namespace {0} --> <div> ", name);
Output.WriteLine ("<h2>New Namespace {0}</h2>", name);
Output.WriteLine ();
Formatter.BeginNamespace (Output, "New ");
// list all new types
foreach (var addedType in target.Element ("classes").Elements ("class"))
foreach (var addedType in target.Element ("classes").Elements ("class")) {
State.Type = addedType.Attribute ("name").Value;
comparer.Added (addedType, true);
Output.WriteLine ("</div> <!-- end namespace {0} -->", name);
Output.WriteLine ();
}
Formatter.EndNamespace (Output);
}
public override void Modified (XElement source, XElement target, ApiChanges differences)
@ -83,10 +81,9 @@ namespace Xamarin.ApiDiff {
State.Output = output;
if (s.Length > 0) {
var name = target.Attribute ("name").Value;
Output.WriteLine ("<!-- start namespace {0} --> <div> ", name);
Output.WriteLine ("<h2>Namespace {0}</h2>", name);
Formatter.BeginNamespace (Output);
Output.WriteLine (s);
Output.WriteLine ("</div> <!-- end namespace {0} -->", name);
Formatter.EndNamespace (Output);
}
}
@ -99,14 +96,14 @@ namespace Xamarin.ApiDiff {
if (State.IgnoreRemoved.Any (re => re.IsMatch (namespaceDescription)))
return;
Output.WriteLine ("<!-- start namespace {0} --> <div>", name);
Output.WriteLine ("<h2>Removed Namespace {0}</h2>", name);
Formatter.BeginNamespace (Output, "Removed ");
Output.WriteLine ();
// list all removed types
foreach (var removedType in source.Element ("classes").Elements ("class"))
foreach (var removedType in source.Element ("classes").Elements ("class")) {
State.Type = comparer.GetTypeName (removedType);
comparer.Removed (removedType);
Output.WriteLine ("</div> <!-- end namespace {0} -->", name);
Output.WriteLine ();
}
Formatter.EndNamespace (Output);
}
}
}

View File

@ -6,8 +6,11 @@ Comparer.cs
ConstructorComparer.cs
EventComparer.cs
FieldComparer.cs
Formatter.cs
Helpers.cs
HtmlFormatter.cs
InterfaceComparer.cs
MarkdownFormatter.cs
MemberComparer.cs
MethodComparer.cs
NamespaceComparer.cs

View File

@ -1 +1 @@
741e2651dcdcdecf5ac93994dfb77b53acf446ba
e6b7b70a3ecfdc193c1fee5bb30558e4224252c8

View File

@ -1 +1 @@
#define FULL_VERSION "explicit/1f3334f"
#define FULL_VERSION "explicit/33a9dca"

Binary file not shown.

View File

@ -1 +1 @@
a5b96637c3a14d3ff54d08a69b9be2dab301459a
d41d73147f2851a5a673fd18b45fceaae78e3025

Binary file not shown.

View File

@ -1 +1 @@
a62d543177eb487ce400a5c919cfc87a7c4b3880
144a82c66e1f0499961ff7c2fbfbd42f298b91db

Binary file not shown.

View File

@ -1 +1 @@
04ee6e6515a55fe2f33a80529c0c3ebab18fc86a
c8f9a61d85ec94cf5bb390a5dfe4cddc3a17b314

View File

@ -6,9 +6,9 @@
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: mono 5.14.0.116\n"
"Project-Id-Version: mono 5.14.0.121\n"
"Report-Msgid-Bugs-To: http://www.mono-project.com/Bugs\n"
"POT-Creation-Date: 2018-06-01 08:17+0000\n"
"POT-Creation-Date: 2018-06-02 08:31+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"

Binary file not shown.

View File

@ -1 +1 @@
da5743e70ab27b9dae6a254153bd1ac41d49b5bf
d9b795430351c1d58879bde8bd04efcf57186470