public override bool Equals(XElement source, XElement target, ApiChanges changes) { if (base.Equals(source, target, changes)) { return(true); } var change = new ApiChange(GetDescription(source), State); change.Header = "Modified " + GroupName; change.Append("public event "); var srcEventType = source.GetTypeName("eventtype", State); var tgtEventType = target.GetTypeName("eventtype", State); if (srcEventType != tgtEventType) { change.AppendModified(srcEventType, tgtEventType, true); } else { change.Append(srcEventType); } change.Append(" "); change.Append(source.GetAttribute("name")).Append(";"); return(false); }
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", State); var tgtType = target.GetTypeName("type", State); 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 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(" "); }
void RenderPropertyType(XElement source, XElement target, ApiChange change) { var srcType = source.GetTypeName("ptype", State); var tgtType = target.GetTypeName("ptype", State); if (srcType == tgtType) { change.Append(tgtType); } else { change.AppendModified(srcType, tgtType, true); } change.Append(" "); }
void RenderReturnType(XElement source, XElement target, ApiChange change) { var srcType = source.GetTypeName("returntype", State); var tgtType = target.GetTypeName("returntype", State); 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(" "); } }
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(Formatter.LesserThan); for (int i = 0; i < System.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(Formatter.GreaterThan); }
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) { if (State.IgnoreVirtualChanges) { change.HasIgnoredChanges = true; } else { change.AppendModified(srcWord, tgtWord, breaking).Append(" "); } } } else if (tgtWord.Length > 0) { change.Append(tgtWord).Append(" "); } else if (srcWord.Length > 0) { change.AppendRemoved(srcWord, breaking).Append(" "); } } if (srcFinal) { if (tgtFinal) { change.Append("final "); } else { if (srcVirtual && !tgtVirtual && State.IgnoreVirtualChanges) { change.HasIgnoredChanges = true; } else { change.AppendRemoved("final", false).Append(" "); // removing 'final' is not a breaking change. } } } else { if (tgtFinal && srcVirtual) { 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 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 < System.Math.Max(srcCount, tgtCount); i++) { if (i > 0) { change.Append(", "); } string mods_tgt = tgt [i].GetAttribute("direction") ?? ""; string mods_src = src [i].GetAttribute("direction") ?? ""; if (mods_tgt.Length > 0) { mods_tgt = mods_tgt + " "; } if (mods_src.Length > 0) { mods_src = mods_src + " "; } if (i >= srcCount) { change.AppendAdded(mods_tgt + tgt [i].GetTypeName("type", State) + " " + tgt [i].GetAttribute("name"), true); } else if (i >= tgtCount) { change.AppendRemoved(mods_src + src [i].GetTypeName("type", State) + " " + src [i].GetAttribute("name"), true); } else { 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"); if (mods_src != mods_tgt) { change.AppendModified(mods_src, mods_tgt, true); } else { change.Append(mods_src); } if (paramSourceType != paramTargetType) { change.AppendModified(paramSourceType, paramTargetType, true); } else { change.Append(paramSourceType); } change.Append(" "); if (!State.IgnoreParameterNameChanges && paramSourceName != paramTargetName) { change.AppendModified(paramSourceName, paramTargetName, true); } 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(")"); }
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(GetDescription(source), State); 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", State); var tgtType = target.GetTypeName("fieldtype", State); 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); }