public abstract string GroupName { get; }
public abstract string ElementName { get; }
+ protected virtual bool IsBreakingRemoval (XElement e)
+ {
+ return true;
+ }
+
public void Compare (XElement source, XElement target)
{
var s = source.Element (GroupName);
{
}
+ string GetContainingType (XElement el)
+ {
+ return el.Ancestors ("class").First ().Attribute ("type").Value;
+ }
+
+ bool IsInInterface (XElement el)
+ {
+ return GetContainingType (el) == "interface";
+ }
+
public XElement Source { get; set; }
public virtual bool Find (XElement e)
BeforeAdding (elements);
a = true;
}
- Added (item);
+ Added (item, false);
}
if (a)
AfterAdding ();
Output.WriteLine ("<p>{0}:</p>", changes.Key);
Output.WriteLine ("<pre>");
foreach (var element in changes.Value) {
+ 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>");
}
Output.WriteLine ("</pre>");
public virtual void BeforeAdding (IEnumerable<XElement> list)
{
first = true;
- Output.WriteLine ("<p>Added {0}:</p><pre>", list.Count () > 1 ? GroupName : ElementName);
- if (State.Colorize)
- Output.Write ("<font color='green'>");
+ Output.WriteLine ("<div>");
+ Output.WriteLine ("<p>Added {0}:</p>", list.Count () > 1 ? GroupName : ElementName);
+ Output.WriteLine ("<pre>");
}
- public override void Added (XElement target)
+ public override void Added (XElement target, bool wasParentAdded)
{
var o = GetObsoleteMessage (target);
if (!first && (o.Length > 0))
Output.WriteLine ();
- Indent ().WriteLine ("\t{0}{1}", o, GetDescription (target));
+ 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>");
first = false;
}
public virtual void AfterAdding ()
{
- if (State.Colorize)
- Output.Write ("</font>");
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<pre>", list.Count () > 1 ? GroupName : ElementName);
- if (State.Colorize)
- Output.Write ("<font color='red'>");
+ 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);
if (!first && (o.Length > 0))
Output.WriteLine ();
- Indent ().WriteLine ("\t{0}{1}", o, GetDescription (source));
+
+ 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>");
first = false;
}
public virtual void AfterRemoving ()
{
- if (State.Colorize)
- Output.Write ("</font>");
- Output.WriteLine ("</pre>");
+ Output.WriteLine ("</pre>");;
+ }
+
+ string RenderGenericParameter (XElement gp)
+ {
+ var sb = new StringBuilder ();
+ sb.Append (gp.GetTypeName ("name"));
+
+ var constraints = gp.DescendantList ("generic-parameter-constraints", "generic-parameter-constraint");
+ if (constraints != null && constraints.Count > 0) {
+ sb.Append (" : ");
+ for (int i = 0; i < constraints.Count; i++) {
+ if (i > 0)
+ sb.Append (", ");
+ sb.Append (constraints [i].GetTypeName ("name"));
+ }
+ }
+ return sb.ToString ();
}
protected void RenderGenericParameters (XElement source, XElement target, ApiChange change)
if (i > 0)
change.Append (", ");
if (i >= srcCount) {
- change.AppendAdded (tgt [i].GetTypeName ("name"), true);
+ change.AppendAdded (RenderGenericParameter (tgt [i]), true);
} else if (i >= tgtCount) {
- change.AppendRemoved (src [i].GetTypeName ("name"), true);
+ change.AppendRemoved (RenderGenericParameter (src [i]), true);
} else {
- var srcName = src [i].GetTypeName ("name");
- var tgtName = tgt [i].GetTypeName ("name");
+ var srcName = RenderGenericParameter (src [i]);
+ var tgtName = RenderGenericParameter (tgt [i]);
if (srcName != tgtName) {
change.AppendModified (srcName, tgtName, true);
change.AnyChange = false;
change.HasIgnoredChanges = true;
}
+
+ var tgtSecurity = (source & MethodAttributes.HasSecurity) == MethodAttributes.HasSecurity;
+ var srcSecurity = (target & MethodAttributes.HasSecurity) == MethodAttributes.HasSecurity;
+
+ if (tgtSecurity != srcSecurity)
+ change.HasIgnoredChanges = true;
+
+ var srcPInvoke = (source & MethodAttributes.PinvokeImpl) == MethodAttributes.PinvokeImpl;
+ var tgtPInvoke = (target & MethodAttributes.PinvokeImpl) == MethodAttributes.PinvokeImpl;
+ if (srcPInvoke != tgtPInvoke)
+ change.HasIgnoredChanges = true;
}
protected string GetVisibility (MethodAttributes attr)
return; // neither is obsolete
var change = new ApiChange ();
change.Header = "Obsoleted " + GroupName;
- if (State.Colorize)
- change.Append ("<font color='gray'>");
+ 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 (")]\n");
change.Append (GetDescription (target));
- if (State.Colorize)
- change.Append ("</font>");
+ change.Append ("</span>");
change.AnyChange = true;
changes.Add (source, target, change);
} else if (tgtObsolete == null) {