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 (" "); } }
void RenderReturnType (XElement source, XElement target, ApiChange change) { var srcType = source.GetTypeName ("returntype"); var tgtType = target.GetTypeName ("returntype"); if (srcType != tgtType) { change.AppendModified (srcType, tgtType, true); change.Append (" "); } else if (srcType != null) { // ctor don't have a return type change.Append (srcType); change.Append (" "); } }
public override bool Equals (XElement source, XElement target, ApiChanges changes) { if (base.Equals (source, target, changes)) return true; var change = new ApiChange (); change.Header = "Modified " + GroupName; RenderMethodAttributes (source, target, change); RenderReturnType (source, target, change); RenderName (source, target, change); RenderGenericParameters (source, target, change); RenderParameters (source, target, change); changes.Add (source, target, change); return false; }
void RenderFieldAttributes (FieldAttributes source, FieldAttributes target, ApiChange change) { 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"); } } } // 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 change = new ApiChange (); change.Header = "Modified " + GroupName; change.Append ("public event "); var srcEventType = source.GetTypeName ("eventtype"); var tgtEventType = target.GetTypeName ("eventtype"); if (srcEventType != tgtEventType) { change.AppendModified (srcEventType, tgtEventType, true); } else { change.Append (srcEventType); } change.Append (" "); change.Append (source.GetAttribute ("name")).Append (";"); return false; }
protected void RenderMethodAttributes (XElement source, XElement target, ApiChange diff) { RenderMethodAttributes (source.GetMethodAttributes (), target.GetMethodAttributes (), diff); }
protected void RenderStatic (MethodAttributes src, MethodAttributes tgt, ApiChange diff) { var srcStatic = (src & MethodAttributes.Static) == MethodAttributes.Static; var tgtStatic = (tgt & MethodAttributes.Static) == MethodAttributes.Static; if (srcStatic != tgtStatic) { if (srcStatic) { diff.AppendRemoved ("static", true).Append (" "); } else { diff.AppendAdded ("static", true).Append (" "); } } }
protected void RenderMethodAttributes (MethodAttributes src, MethodAttributes tgt, ApiChange diff) { RenderStatic (src, tgt, diff); RenderVisibility (src & MethodAttributes.MemberAccessMask, tgt & MethodAttributes.MemberAccessMask, diff); RenderVTable (src, tgt, diff); }
void RenderVTable (MethodAttributes source, MethodAttributes target, ApiChange change) { var srcAbstract = (source & MethodAttributes.Abstract) == MethodAttributes.Abstract; var tgtAbstract = (target & MethodAttributes.Abstract) == MethodAttributes.Abstract; var srcFinal = (source & MethodAttributes.Final) == MethodAttributes.Final; var tgtFinal = (target & MethodAttributes.Final) == MethodAttributes.Final; var srcVirtual = (source & MethodAttributes.Virtual) == MethodAttributes.Virtual; var tgtVirtual = (target & MethodAttributes.Virtual) == MethodAttributes.Virtual; var srcOverride = (source & MethodAttributes.VtableLayoutMask) != MethodAttributes.NewSlot; var tgtOverride = (target & MethodAttributes.VtableLayoutMask) != MethodAttributes.NewSlot; var srcWord = srcVirtual ? (srcOverride ? "override" : "virtual") : string.Empty; var tgtWord = tgtVirtual ? (tgtOverride ? "override" : "virtual") : string.Empty; var breaking = srcWord.Length > 0 && tgtWord.Length == 0; if (srcAbstract) { if (tgtAbstract) { change.Append ("abstract "); } else if (tgtVirtual) { change.AppendModified ("abstract", tgtWord, false).Append (" "); } else { change.AppendRemoved ("abstract").Append (" "); } } else { if (tgtAbstract) { change.AppendAdded ("abstract", true).Append (" "); } else if (srcWord != tgtWord) { if (!tgtFinal) change.AppendModified (srcWord, tgtWord, breaking).Append (" "); } else if (tgtWord.Length > 0) { change.Append (tgtWord).Append (" "); } else if (srcWord.Length > 0) { change.AppendRemoved (srcWord, breaking).Append (" "); } } if (srcFinal) { if (tgtFinal) { change.Append ("final "); } else { change.AppendRemoved ("final", false).Append (" "); // removing 'final' is not a breaking change. } } else { if (tgtFinal && srcVirtual) { change.AppendModified ("virtual", "final", true).Append (" "); // adding 'final' is a breaking change if the member was virtual } } if (!srcVirtual && !srcFinal && tgtVirtual && tgtFinal) { // existing member implements a member from a new interface // this would show up as 'virtual final', which is redundant, so show nothing at all. change.HasIgnoredChanges = true; } // Ignore non-breaking virtual changes. if (State.IgnoreVirtualChanges && !change.Breaking) { 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 void RenderVisibility (MethodAttributes source, MethodAttributes target, ApiChange diff) { source = source & MethodAttributes.MemberAccessMask; target = target & MethodAttributes.MemberAccessMask; if (source == target) { diff.Append (GetVisibility (target)); } else { var breaking = false; switch (source) { case MethodAttributes.Private: case MethodAttributes.Assembly: case MethodAttributes.FamANDAssem: break; // these are not publicly visible, thus not breaking case MethodAttributes.FamORAssem: case MethodAttributes.Family: switch (target) { case MethodAttributes.Public: // to public is not a breaking change break; case MethodAttributes.Family: case MethodAttributes.FamORAssem: // not a breaking change, but should still show up in diff break; default: // anything else is a breaking change breaking = true; break; } break; case MethodAttributes.Public: default: // any change from public is breaking. breaking = true; break; } diff.AppendModified (GetVisibility (source), GetVisibility (target), breaking); } diff.Append (" "); }
protected void RenderGenericParameters (XElement source, XElement target, ApiChange change) { var src = source.DescendantList ("generic-parameters", "generic-parameter"); var tgt = target.DescendantList ("generic-parameters", "generic-parameter"); var srcCount = src == null ? 0 : src.Count; var tgtCount = tgt == null ? 0 : tgt.Count; if (srcCount == 0 && tgtCount == 0) return; change.Append ("<"); for (int i = 0; i < Math.Max (srcCount, tgtCount); i++) { if (i > 0) change.Append (", "); if (i >= srcCount) { change.AppendAdded (RenderGenericParameter (tgt [i]), true); } else if (i >= tgtCount) { change.AppendRemoved (RenderGenericParameter (src [i]), true); } else { var srcName = RenderGenericParameter (src [i]); var tgtName = RenderGenericParameter (tgt [i]); if (srcName != tgtName) { change.AppendModified (srcName, tgtName, true); } else { change.Append (srcName); } } } change.Append (">"); }
protected void RenderParameters (XElement source, XElement target, ApiChange change) { var src = source.DescendantList ("parameters", "parameter"); var tgt = target.DescendantList ("parameters", "parameter"); var srcCount = src == null ? 0 : src.Count; var tgtCount = tgt == null ? 0 : tgt.Count; change.Append (" ("); for (int i = 0; i < Math.Max (srcCount, tgtCount); i++) { if (i > 0) change.Append (", "); if (i >= srcCount) { change.AppendAdded (tgt [i].GetTypeName ("type") + " " + tgt [i].GetAttribute ("name"), true); } else if (i >= tgtCount) { change.AppendRemoved (src [i].GetTypeName ("type") + " " + src [i].GetAttribute ("name"), true); } else { var paramSourceType = src [i].GetTypeName ("type"); var paramTargetType = tgt [i].GetTypeName ("type"); var paramSourceName = src [i].GetAttribute ("name"); var paramTargetName = tgt [i].GetAttribute ("name"); if (paramSourceType != paramTargetType) { change.AppendModified (paramSourceType, paramTargetType, true); } else { change.Append (paramSourceType); } change.Append (" "); if (paramSourceName != paramTargetName) { change.AppendModified (paramSourceName, paramTargetName, false); } else { change.Append (paramSourceName); } var optSource = src [i].Attribute ("optional"); var optTarget = tgt [i].Attribute ("optional"); var srcValue = FormatValue (paramSourceType, src [i].GetAttribute ("defaultValue")); var tgtValue = FormatValue (paramTargetType, tgt [i].GetAttribute ("defaultValue")); if (optSource != null) { if (optTarget != null) { change.Append (" = "); if (srcValue != tgtValue) { change.AppendModified (srcValue, tgtValue, false); } else { change.Append (tgtValue); } } else { change.AppendRemoved (" = " + srcValue); } } else { if (optTarget != null) change.AppendAdded (" = " + tgtValue); } } } change.Append (")"); // Ignore any parameter name changes if requested. if (State.IgnoreParameterNameChanges && !change.Breaking) { change.AnyChange = false; change.HasIgnoredChanges = true; } }
void RenderAccessors (XElement srcGetter, XElement tgtGetter, XElement srcSetter, XElement tgtSetter, ApiChange change) { // FIXME: this doesn't render changes in the accessor visibility (a protected setter can become public for instance). change.Append (" {"); if (tgtGetter != null) { if (srcGetter != null) { change.Append (" ").Append ("get;"); } else { change.Append (" ").AppendAdded ("get;"); } } else if (srcGetter != null) { change.Append (" ").AppendRemoved ("get;"); } if (tgtSetter != null) { if (srcSetter != null) { change.Append (" ").Append ("set;"); } else { change.Append (" ").AppendAdded ("set;"); } } else if (srcSetter != null) { change.Append (" ").AppendRemoved ("set;"); } change.Append (" }"); // Ignore added property setters if asked to if (srcSetter == null && tgtSetter != null && State.IgnoreAddedPropertySetters && !change.Breaking) { change.AnyChange = false; change.HasIgnoredChanges = true; } }
void RenderIndexers (List<XElement> srcIndexers, List<XElement> tgtIndexers, ApiChange change) { change.Append ("this ["); for (int i = 0; i < srcIndexers.Count; i++) { var source = srcIndexers [i]; var target = tgtIndexers [i]; if (i > 0) change.Append (", "); var srcType = source.GetTypeName ("type"); var tgtType = target.GetTypeName ("type"); if (srcType == tgtType) { change.Append (tgtType); } else { change.AppendModified (srcType, tgtType, true); } change.Append (" "); var srcName = source.GetAttribute ("name"); var tgtName = target.GetAttribute ("name"); if (srcName == tgtName) { change.Append (tgtName); } else { change.AppendModified (srcName, tgtName, true); } } change.Append ("]"); }
protected void RenderAttributes (XElement source, XElement target, ApiChanges changes) { var srcObsolete = source.GetObsoleteMessage (); var tgtObsolete = target.GetObsoleteMessage (); if (srcObsolete == tgtObsolete) return; // nothing changed if (srcObsolete == null) { if (tgtObsolete == null) return; // neither is obsolete var change = new ApiChange (); 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>"); change.AnyChange = true; changes.Add (source, target, change); } else if (tgtObsolete == null) { // Made non-obsolete. Do we care to report this? } else { // Obsolete message changed. Do we care to report this? } }
protected void RenderAttributes (XElement source, XElement target, ApiChanges changes) { var srcObsolete = source.GetObsoleteMessage (); var tgtObsolete = target.GetObsoleteMessage (); if (srcObsolete == tgtObsolete) return; // nothing changed if (srcObsolete == null) { if (tgtObsolete == null) return; // neither is obsolete var change = new ApiChange (); change.Header = "Obsoleted " + GroupName; if (State.Colorize) change.Append ("<span style='color:gray'>"); change.Append ("[Obsolete ("); if (tgtObsolete != string.Empty) change.Append ("\"").Append (tgtObsolete).Append ("\""); change.Append ("]\n"); change.Append (GetDescription (target)); if (State.Colorize) change.Append ("</span>"); change.AnyChange = true; changes.Add (source, target, change); } else if (tgtObsolete == null) { // Made non-obsolete. Do we care to report this? } else { // Obsolete message changed. Do we care to report this? } }
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 bool Equals (XElement source, XElement target, ApiChanges changes) { if (base.Equals (source, target, changes)) return true; XElement srcGetter, srcSetter; XElement tgtGetter, tgtSetter; GetAccessors (source, out srcGetter, out srcSetter); GetAccessors (target, out tgtGetter, out tgtSetter); List<XElement> srcIndexers = null; List<XElement> tgtIndexers = null; bool isIndexer = false; if (srcGetter != null) { srcIndexers = srcGetter.DescendantList ("parameters", "parameter"); tgtIndexers = tgtGetter.DescendantList ("parameters", "parameter"); isIndexer = srcIndexers != null && srcIndexers.Count > 0; } var change = new ApiChange (); change.Header = "Modified " + GroupName; RenderMethodAttributes (GetMethodAttributes (srcGetter, srcSetter), GetMethodAttributes (tgtGetter, tgtSetter), change); RenderPropertyType (source, target, change); if (isIndexer) { RenderIndexers (srcIndexers, tgtIndexers, change); } else { RenderName (source, target, change); } RenderGenericParameters (source, target, change); RenderAccessors (srcGetter, tgtGetter, srcSetter, tgtSetter, change); changes.Add (source, target, change); return false; }
void RenderPropertyType (XElement source, XElement target, ApiChange change) { var srcType = source.GetTypeName ("ptype"); var tgtType = target.GetTypeName ("ptype"); if (srcType == tgtType) { change.Append (tgtType); } else { change.AppendModified (srcType, tgtType, true); } change.Append (" "); }
protected void RenderName (XElement source, XElement target, ApiChange change) { var name = target.GetAttribute ("name"); // show the constructor as it would be defined in C# name = name.Replace (".ctor", State.Type); var p = name.IndexOf ('('); if (p >= 0) name = name.Substring (0, p); change.Append (name); }
public override bool Equals (XElement source, XElement target, ApiChanges changes) { if (base.Equals (source, target, changes)) return true; XElement srcGetter, srcSetter; XElement tgtGetter, tgtSetter; GetAccessors (source, out srcGetter, out srcSetter); GetAccessors (target, out tgtGetter, out tgtSetter); var change = new ApiChange (); change.Header = "Modified " + GroupName; RenderMethodAttributes (GetMethodAttributes (srcGetter, srcSetter), GetMethodAttributes (tgtGetter, tgtSetter), change); RenderPropertyType (source, target, change); RenderName (source, target, change); RenderGenericParameters (source, target, change); RenderAccessors (srcGetter, tgtGetter, srcSetter, tgtSetter, change); changes.Add (source, target, change); return false; }