Exemple #1
0
		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;
		}
Exemple #4
0
		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 (" ");
			}
		}
Exemple #5
0
		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;
		}
Exemple #6
0
		protected void RenderMethodAttributes (XElement source, XElement target, ApiChange diff)
		{
			RenderMethodAttributes (source.GetMethodAttributes (), target.GetMethodAttributes (), diff);
		}
Exemple #7
0
		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 (" ");
				}
			}
		}
Exemple #8
0
		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);
		}
Exemple #9
0
		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;
		}
Exemple #10
0
		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 (" ");
		}
Exemple #11
0
		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 ("&gt;");
		}
Exemple #12
0
		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;
			}
		}
Exemple #13
0
		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;
			}
		}
Exemple #14
0
		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 ("]");
		}
Exemple #15
0
		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?
			}
		}
Exemple #16
0
		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?
			}
		}
Exemple #17
0
		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;
		}
Exemple #18
0
		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;
		}
Exemple #19
0
		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 (" ");
		}
Exemple #20
0
		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);
		}
Exemple #21
0
		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;
		}