From 6dceae79b2e9f7c2d1425f494f01a912788d6c23 Mon Sep 17 00:00:00 2001 From: Guillermo Calvo Date: Sun, 28 Jul 2024 14:24:42 +0200 Subject: [PATCH 01/15] Implement Markdown output generator --- .../japicmp/output/markdown/Markdown.java | 55 ++ .../output/markdown/MarkdownBadge.java | 53 ++ .../output/markdown/MarkdownImage.java | 13 + .../japicmp/output/markdown/MarkdownLink.java | 16 + .../japicmp/output/markdown/MarkdownList.java | 33 + .../markdown/MarkdownOutputGenerator.java | 605 ++++++++++++++++++ .../output/markdown/MarkdownRefImage.java | 13 + .../output/markdown/MarkdownRefLink.java | 17 + .../output/markdown/MarkdownReference.java | 40 ++ .../output/markdown/MarkdownReferences.java | 48 ++ .../output/markdown/MarkdownSection.java | 54 ++ .../markdown/MarkdownStoredReference.java | 41 ++ .../output/markdown/MarkdownTable.java | 97 +++ .../config/MarkdownHeaderOptions.java | 26 + .../config/MarkdownMessageOptions.java | 186 ++++++ .../markdown/config/MarkdownOptions.java | 37 ++ .../markdown/config/MarkdownSortOptions.java | 23 + .../markdown/config/MarkdownTitleOptions.java | 15 + .../JApiClassFileFormatVersionHelper.java | 71 ++ .../java/japicmp/util/MemberValueHelper.java | 59 ++ .../java/japicmp/util/ModifierHelper.java | 32 + .../java/japicmp/util/TypeNameHelper.java | 183 ++++++ 22 files changed, 1717 insertions(+) create mode 100644 japicmp/src/main/java/japicmp/output/markdown/Markdown.java create mode 100644 japicmp/src/main/java/japicmp/output/markdown/MarkdownBadge.java create mode 100644 japicmp/src/main/java/japicmp/output/markdown/MarkdownImage.java create mode 100644 japicmp/src/main/java/japicmp/output/markdown/MarkdownLink.java create mode 100644 japicmp/src/main/java/japicmp/output/markdown/MarkdownList.java create mode 100644 japicmp/src/main/java/japicmp/output/markdown/MarkdownOutputGenerator.java create mode 100644 japicmp/src/main/java/japicmp/output/markdown/MarkdownRefImage.java create mode 100644 japicmp/src/main/java/japicmp/output/markdown/MarkdownRefLink.java create mode 100644 japicmp/src/main/java/japicmp/output/markdown/MarkdownReference.java create mode 100644 japicmp/src/main/java/japicmp/output/markdown/MarkdownReferences.java create mode 100644 japicmp/src/main/java/japicmp/output/markdown/MarkdownSection.java create mode 100644 japicmp/src/main/java/japicmp/output/markdown/MarkdownStoredReference.java create mode 100644 japicmp/src/main/java/japicmp/output/markdown/MarkdownTable.java create mode 100644 japicmp/src/main/java/japicmp/output/markdown/config/MarkdownHeaderOptions.java create mode 100644 japicmp/src/main/java/japicmp/output/markdown/config/MarkdownMessageOptions.java create mode 100644 japicmp/src/main/java/japicmp/output/markdown/config/MarkdownOptions.java create mode 100644 japicmp/src/main/java/japicmp/output/markdown/config/MarkdownSortOptions.java create mode 100644 japicmp/src/main/java/japicmp/output/markdown/config/MarkdownTitleOptions.java create mode 100644 japicmp/src/main/java/japicmp/util/JApiClassFileFormatVersionHelper.java create mode 100644 japicmp/src/main/java/japicmp/util/MemberValueHelper.java create mode 100644 japicmp/src/main/java/japicmp/util/TypeNameHelper.java diff --git a/japicmp/src/main/java/japicmp/output/markdown/Markdown.java b/japicmp/src/main/java/japicmp/output/markdown/Markdown.java new file mode 100644 index 000000000..eba4769ad --- /dev/null +++ b/japicmp/src/main/java/japicmp/output/markdown/Markdown.java @@ -0,0 +1,55 @@ +package japicmp.output.markdown; + +import static java.util.stream.Collectors.joining; + +import java.util.stream.Collector; + +public abstract class Markdown { + + public static final String EOL = "\n"; + public static final String PARAGRAPH = "\n\n"; + public static final String SPACE = " "; + public static final String EMPTY = ""; + public static final String DASH = "-"; + public static final String UNDERSCORE = "_"; + public static final String QUOTE = "\""; + public static final String BACKSLASH = "\\"; + public static final String PARENTHESIS_OPEN = "("; + public static final String PARENTHESIS_CLOSE = ")"; + public static final String ANGLE_OPEN = "<"; + public static final String ANGLE_CLOSE = ">"; + public static final String BRACKET_OPEN = "["; + public static final String BRACKET_CLOSE = "]"; + public static final String BANG = "!"; + public static final String HASH = "#"; + public static final String COLON = ":"; + public static final String EQUAL = "="; + public static final String DOT = "."; + public static final char PIPE = '|'; + public static final String BACKTICK = "`"; + public static final String MARKDOWN_HORIZONTAL_RULE = "___"; + public static final Collector LINES = joining(EOL); + public static final Collector SPACES = joining(SPACE); + public static final Collector CSV = joining(", "); + public static final Collector BR = joining("
"); + + public static String quotes(String text) { + return QUOTE + text + QUOTE; + } + + public static String backticks(String text) { + return BACKTICK + text + BACKTICK; + } + + public static String angles(String text) { + return ANGLE_OPEN + text + ANGLE_CLOSE; + } + + public static String brackets(String text) { + return BRACKET_OPEN + text + BRACKET_CLOSE; + } + + public static String parenthesis(String text) { + return PARENTHESIS_OPEN + text + PARENTHESIS_CLOSE; + } +} diff --git a/japicmp/src/main/java/japicmp/output/markdown/MarkdownBadge.java b/japicmp/src/main/java/japicmp/output/markdown/MarkdownBadge.java new file mode 100644 index 000000000..5df2345d1 --- /dev/null +++ b/japicmp/src/main/java/japicmp/output/markdown/MarkdownBadge.java @@ -0,0 +1,53 @@ +package japicmp.output.markdown; + +public class MarkdownBadge extends Markdown { + + static final String BASE_URL = "https://img.shields.io/badge/"; + + final String label; + final String message; + final String color; + final String logo; + + public MarkdownBadge(String label, String message, String color, String logo) { + this.label = label; + this.message = message; + this.color = color; + this.logo = logo; + } + + public MarkdownBadge(String label, String message, String color) { + this(label, message, color, null); + } + + @Override + public String toString() { + final String alt = label != null ? label + SPACE + message : message; + return new MarkdownImage(alt, getHref(), alt).toString(); + } + + public MarkdownRefImage toRefImage(MarkdownReferences references, String alt, String title) { + return references.make(getHref(), alt, title).toImage(alt); + } + + public MarkdownRefImage toRefImage(MarkdownReferences references, String title) { + return toRefImage(references, title, title); + } + + public MarkdownRefImage toRefImage(MarkdownReferences references) { + return toRefImage(references, message); + } + + private String getHref() { + final String pre = label == null ? EMPTY : label + .replace(DASH, UNDERSCORE) + .replace(SPACE, UNDERSCORE) + .replace(HASH, COLON) + DASH; + final String msg = message + .replace(DASH, UNDERSCORE) + .replace(SPACE, UNDERSCORE) + .replace(HASH, COLON); + final String arg = logo == null ? EMPTY : "?logo" + EQUAL + logo; + return BASE_URL + pre + msg + DASH + color + arg; + } +} diff --git a/japicmp/src/main/java/japicmp/output/markdown/MarkdownImage.java b/japicmp/src/main/java/japicmp/output/markdown/MarkdownImage.java new file mode 100644 index 000000000..cae245db4 --- /dev/null +++ b/japicmp/src/main/java/japicmp/output/markdown/MarkdownImage.java @@ -0,0 +1,13 @@ +package japicmp.output.markdown; + +final class MarkdownImage extends MarkdownLink { + + MarkdownImage(String alt, String href, String title) { + super(alt, href, title); + } + + @Override + public String toString() { + return BANG + super.toString(); + } +} diff --git a/japicmp/src/main/java/japicmp/output/markdown/MarkdownLink.java b/japicmp/src/main/java/japicmp/output/markdown/MarkdownLink.java new file mode 100644 index 000000000..eedb0a194 --- /dev/null +++ b/japicmp/src/main/java/japicmp/output/markdown/MarkdownLink.java @@ -0,0 +1,16 @@ +package japicmp.output.markdown; + +class MarkdownLink extends MarkdownReference { + + final String text; + + MarkdownLink(String text, String href, String title) { + super(href, title); + this.text = text == null ? EMPTY : text; + } + + @Override + public String toString() { + return brackets(text) + parenthesis(super.toString()); + } +} diff --git a/japicmp/src/main/java/japicmp/output/markdown/MarkdownList.java b/japicmp/src/main/java/japicmp/output/markdown/MarkdownList.java new file mode 100644 index 000000000..369033d88 --- /dev/null +++ b/japicmp/src/main/java/japicmp/output/markdown/MarkdownList.java @@ -0,0 +1,33 @@ +package japicmp.output.markdown; + +import static java.util.Arrays.*; +import static java.util.stream.Collectors.toList; + +import java.util.List; +import java.util.stream.Stream; + +class MarkdownList extends Markdown { + + private final String pad; + private final List elements; + + MarkdownList(String... elements) { + this.pad = EMPTY; + this.elements = asList(elements); + } + + MarkdownList(int level, Stream elements) { + final String format = "%-" + (level * 2) + "s"; + this.pad = String.format(format, EMPTY); + this.elements = elements.collect(toList()); + } + + MarkdownList(int level, String... elements) { + this(level, stream(elements)); + } + + @Override + public String toString() { + return (pad.isEmpty() || elements.isEmpty() ? EMPTY : EOL) + elements.stream().filter(x -> x != null && !x.isEmpty()).map(e -> pad + "- " + e).collect(LINES); + } +} diff --git a/japicmp/src/main/java/japicmp/output/markdown/MarkdownOutputGenerator.java b/japicmp/src/main/java/japicmp/output/markdown/MarkdownOutputGenerator.java new file mode 100644 index 000000000..0608411d7 --- /dev/null +++ b/japicmp/src/main/java/japicmp/output/markdown/MarkdownOutputGenerator.java @@ -0,0 +1,605 @@ +package japicmp.output.markdown; + +import static japicmp.model.JApiChangeStatus.*; +import static japicmp.output.markdown.Markdown.*; +import static japicmp.util.JApiClassFileFormatVersionHelper.*; +import static japicmp.util.MemberValueHelper.formatMemberValue; +import static japicmp.util.ModifierHelper.*; +import static japicmp.util.OptionalHelper.N_A; +import static japicmp.util.TypeNameHelper.*; +import static java.lang.String.format; +import static java.util.Collections.*; +import static java.util.stream.Collectors.*; + +import japicmp.cmp.JApiCmpArchive; +import japicmp.config.*; +import japicmp.filter.Filter; +import japicmp.model.*; +import japicmp.model.JApiJavaObjectSerializationCompatibility.JApiJavaObjectSerializationChangeStatus; +import japicmp.output.*; +import japicmp.output.markdown.config.MarkdownOptions; +import japicmp.output.semver.SemverOut; +import japicmp.util.Optional; +import java.util.*; +import java.util.regex.Pattern; +import java.util.stream.Stream; +import javassist.bytecode.annotation.MemberValue; + +public class MarkdownOutputGenerator extends OutputGenerator { + + final MarkdownOptions md; + final MarkdownReferences references = new MarkdownReferences(); + + public MarkdownOutputGenerator(MarkdownOptions mdOptions, List jApiClasses) { + super(mdOptions.options, jApiClasses); + md = mdOptions; + } + + public MarkdownOutputGenerator(Options options, List jApiClasses) { + this(MarkdownOptions.newDefault(options), jApiClasses); + } + + @Override + public String generate() { + return toString(); + } + + @Override + public String toString() { + final String semver = new SemverOut(options, jApiClasses).generate(); + return renderHeading(0, md.title.report) + + md.message.getSemverBadge(semver) + EOL + + renderHeading(1, md.title.summary) + + renderReportSummary(md.message.getSummaryMessage(semver), options) + PARAGRAPH + + renderHtmlDetails(md.message.expandOptions, renderReportOptions(options)) + + renderReportResults(options) + EOL + + renderMissingClassesWarning(options.getIgnoreMissingClasses()) + + MARKDOWN_HORIZONTAL_RULE + PARAGRAPH + + format(md.message.generatedOn, md.message.getCurrentTimestamp()) + PARAGRAPH + + references + EOL; + } + + private String renderHeading(int level, String text) { + final StringBuilder tmp = new StringBuilder(); + tmp.append(EOL); + for (int repeat = 0; repeat < md.title.topHeadingLevel + level && repeat < 6; repeat++) { + tmp.append(HASH); + } + tmp.append(" "); + tmp.append(text); + tmp.append(PARAGRAPH); + return tmp.toString(); + } + + private String renderReportSummary(String summary, Options options) { + final String newVersion = renderArchivesVersion(md.targetNewVersion, options.getNewArchives(), md.message.oneNewVersion, md.message.manyNewArchives); + final String oldVersion = renderArchivesVersion(md.targetOldVersion, options.getOldArchives(), md.message.oneOldVersion, md.message.manyOldArchives); + return format(summary, newVersion, oldVersion); + } + + private String renderReportOptions(Options options) { + final List patterns = options.getIgnoreMissingClasses().getIgnoreMissingClassRegularExpression(); + return new MarkdownList( + format(md.message.reportOnlyChanges, md.message.yesNo(options.isOutputOnlyModifications())), + format(md.message.reportOnlyBinaryIncompatibleChanges, md.message.yesNo(options.isOutputOnlyBinaryIncompatibleModifications())), + format(md.message.accessModifierFilter, options.getAccessModifier()), + format(md.message.oldArchives, new MarkdownList(1, options.getOldArchives().stream().map(this::renderArchive))), + format(md.message.newArchives, new MarkdownList(1, options.getNewArchives().stream().map(this::renderArchive))), + format(md.message.evaluateAnnotations, md.message.yesNo(!options.isNoAnnotations())), + format(md.message.includeSynthetic, md.message.yesNo(options.isIncludeSynthetic())), + format(md.message.includeSpecificElements, md.message.yesNo(!options.getIncludes().isEmpty()) + new MarkdownList(1, options.getIncludes().stream().filter(Objects::nonNull).map(Filter::toString).distinct().map(this::renderCode))), + format(md.message.excludeSpecificElements, md.message.yesNo(!options.getExcludes().isEmpty()) + new MarkdownList(1, options.getExcludes().stream().filter(Objects::nonNull).map(Filter::toString).distinct().map(this::renderCode))), + format(md.message.ignoreAllMissingClasses, md.message.yesNo(options.getIgnoreMissingClasses().isIgnoreAllMissingClasses())), + format(md.message.ignoreSpecificMissingClasses, md.message.yesNo(!patterns.isEmpty()) + new MarkdownList(1, patterns.stream().map(Pattern::pattern).map(this::renderCode))), + format(md.message.treatChangesAsErrors, new MarkdownList(1, + format(md.message.anyChanges, md.message.yesNo(options.isErrorOnModifications())), + format(md.message.binaryIncompatibleChanges, md.message.yesNo(options.isErrorOnBinaryIncompatibility())), + format(md.message.sourceIncompatibleChanges, md.message.yesNo(options.isErrorOnSourceIncompatibility())), + format(md.message.incompatibleChangesCausedByExcludedClasses, md.message.yesNo(options.isErrorOnExclusionIncompatibility())), + format(md.message.semanticallyIncompatibleChanges, md.message.yesNo(options.isErrorOnSemanticIncompatibility())), + format(md.message.semanticallyIncompatibleChangesIncludingDevelopmentVersions, md.message.yesNo(options.isErrorOnSemanticIncompatibilityForMajorVersionZero()))) + ), + format(md.message.classpathMode, options.getClassPathMode()), + format(md.message.oldClasspath, options.getOldClassPath().or(EMPTY)), + format(md.message.newClasspath, options.getNewClassPath().or(EMPTY)) + ) + EOL; + } + + private String renderArchivesVersion(Optional version, List archives, String one, String many) { + if (version.isPresent()) { + return format(one, version.get()); + } + if (archives.isEmpty()) { + return format(one, md.message.unknownVersion); + } + if (archives.size() == 1) { + final JApiCmpArchive archive = archives.get(0); + final String archiveVersion = archive.getVersion().getStringVersion(); + if (archiveVersion != null && !archiveVersion.equals(N_A)) { + return format(one, archiveVersion); + } + return format(one, renderSimpleArchiveName(archive)); + } + return many; + } + + private String renderReportResults(Options options) { + new OutputFilter(options).filter(jApiClasses); + if (jApiClasses.isEmpty()) { + return EMPTY; + } + return new MarkdownSection<>(renderHeading(1, md.title.results), jApiClasses, md.sort.classes) + .column(md.header.status, this::renderStatus) + .column(md.header.type, this::renderClassLink) + .column(md.header.serialization, this::renderSerializationChange) + .column(md.header.compatibilityChanges, this::renderAllCompatibilityChanges) + + (md.options.isReportOnlySummary() ? "" : renderHtmlDetails(md.message.expandResults, jApiClasses.stream().sorted(md.sort.classes).map(this::renderClass).collect(joining()))); + } + + private String renderMissingClassesWarning(IgnoreMissingClasses missing) { + if (missing.isIgnoreAllMissingClasses()) { + return md.message.warningAllMissingClassesIgnored; + } else if (!missing.getIgnoreMissingClassRegularExpression().isEmpty()) { + return md.message.warningSomeMissingClassesIgnored; + } + return EMPTY; + } + + private String renderClass(JApiClass clazz) { + final String name = clazz.getFullyQualifiedName(); + return MARKDOWN_HORIZONTAL_RULE + PARAGRAPH + + renderHtmlAnchor(name) + + renderHeading(2, renderCode(name)) + + renderCompatibilityList(clazz) + PARAGRAPH + + renderClassInfo(clazz) + + renderGenericTemplates(clazz) + + renderImplementedInterfaces(clazz) + + renderAnnotations(clazz) + + renderConstructors(clazz) + + renderMethods(clazz) + + renderFields(clazz); + } + + private String renderHtmlAnchor(String id) { + return angles("a" + SPACE + "id" + EQUAL + quotes(renderSlug(id))) + angles("/a"); + } + + private String renderHtmlDetails(String summary, String details) { + return angles("details" + SPACE + "markdown" + EQUAL + quotes("1")) + EOL + + angles("summary") + summary + angles("/summary") + PARAGRAPH + + details + EOL + + angles("/details") + PARAGRAPH; + } + + private String renderSlug(String id) { + return "user-content-" + id.toLowerCase(); + } + + private Markdown renderCompatibilityList(JApiClass clazz) { + return new MarkdownList( + format(md.message.compatibilityBinary, md.message.checkbox(clazz.isBinaryCompatible())), + format(md.message.compatibilitySource, md.message.checkbox(clazz.isSourceCompatible())), + format(md.message.compatibilitySerialization, md.message.checkbox( + !clazz.getJavaObjectSerializationCompatible().isIncompatible()))); + } + + private Markdown renderClassInfo(JApiClass clazz) { + return new MarkdownSection<>(EMPTY, clazz) + .column(md.header.status, this::renderStatus) + .column(md.header.modifiers, this::renderModifiers) + .column(md.header.classType, this::renderClassType) + .column(md.header.className, this::renderClassSimpleName) + .column(md.header.superclass, this::renderClassSuperclass) + .column(md.header.classJdk, this::renderClassJdk) + .column(md.header.serialization, this::renderSerializationChange) + .column(md.header.compatibilityChanges, this::renderClassLevelCompatibilityChanges); + } + + private Markdown renderGenericTemplates(JApiClass clazz) { + return new MarkdownSection<>(renderHeading(3, md.title.generics), clazz.getGenericTemplates(), md.sort.generics) + .column(md.header.status, this::renderStatus) + .column(md.header.genericTemplateName, this::renderGenericTemplateName) + .column(md.header.genericTemplateType, this::renderGenericTemplateType) + .column(md.header.compatibilityChanges, this::renderCompatibilityChanges); + } + + private Markdown renderImplementedInterfaces(JApiClass clazz) { + return new MarkdownSection<>(renderHeading(3, md.title.interfaces), clazz.getInterfaces(), md.sort.interfaces) + .column(md.header.status, this::renderStatus) + .column(md.header.interfaceName, this::renderImplementedInterfaceName) + .column(md.header.compatibilityChanges, this::renderCompatibilityChanges); + } + + private Markdown renderAnnotations(JApiClass clazz) { + return new MarkdownSection<>(renderHeading(3, md.title.annotations), clazz.getAnnotations(), md.sort.annotations) + .column(md.header.status, this::renderStatus) + .column(md.header.annotationName, this::renderAnnotation) + .column(md.header.compatibilityChanges, this::renderAllCompatibilityChanges); + } + + private Markdown renderConstructors(JApiClass clazz) { + return new MarkdownSection<>(renderHeading(3, md.title.constructors), clazz.getConstructors(), md.sort.constructors) + .column(md.header.status, this::renderStatus) + .column(md.header.modifiers, this::renderModifiers) + .column(md.header.generics, this::renderGenericTemplates) + .column(md.header.constructorNameAndParameters, this::renderNameAndParameters) + .column(md.header.annotations, this::renderInlineAnnotations) + .column(md.header.exceptions, this::renderExceptions) + .column(md.header.compatibilityChanges, this::renderAllCompatibilityChanges); + } + + private Markdown renderMethods(JApiClass clazz) { + return new MarkdownSection<>(renderHeading(3, md.title.methods), clazz.getMethods(), md.sort.methods) + .column(md.header.status, this::renderStatus) + .column(md.header.modifiers, this::renderModifiers) + .column(md.header.generics, this::renderGenericTemplates) + .column(md.header.methodReturnType, this::renderReturnType) + .column(md.header.methodNameAndParameters, this::renderNameAndParameters) + .column(md.header.annotations, this::renderInlineAnnotations) + .column(md.header.exceptions, this::renderExceptions) + .column(md.header.compatibilityChanges, this::renderAllCompatibilityChanges); + } + + private Markdown renderFields(JApiClass clazz) { + return new MarkdownSection<>(renderHeading(3, md.title.fields), clazz.getFields(), md.sort.fields) + .column(md.header.status, this::renderStatus) + .column(md.header.modifiers, this::renderModifiers) + .column(md.header.fieldType, this::renderFieldType) + .column(md.header.fieldName, this::renderFieldName) + .column(md.header.annotations, this::renderInlineAnnotations) + .column(md.header.compatibilityChanges, this::renderCompatibilityChanges); + } + + private String renderStatus(JApiHasChangeStatus element) { + final boolean isBinaryCompatible = ((JApiCompatibility) element).isBinaryCompatible(); + final boolean isSourceCompatible = ((JApiCompatibility) element).isSourceCompatible(); + final boolean isSerializationCompatible = !(element instanceof JApiJavaObjectSerializationCompatibility) + || !((JApiJavaObjectSerializationCompatibility) element).getJavaObjectSerializationCompatible().isIncompatible(); + final boolean isFullyCompatible = isBinaryCompatible && isSourceCompatible && isSerializationCompatible; + if (element.getChangeStatus() != UNCHANGED || isFullyCompatible) { + return renderLiteralStatus(element); + } else if (!isBinaryCompatible && !isSourceCompatible) { + return md.message.statusIncompatible; + } else if (!isBinaryCompatible) { + return md.message.statusBinaryIncompatible; + } else if (!isSourceCompatible) { + return md.message.statusSourceIncompatible; + } + return md.message.statusSerializationIncompatible; + } + + private String renderLiteralStatus(JApiHasChangeStatus element) { + switch (element.getChangeStatus()) { + case NEW: + return md.message.statusNew; + case REMOVED: + return md.message.statusRemoved; + case UNCHANGED: + return md.message.statusUnchanged; + default: + case MODIFIED: + return md.message.statusModified; + } + } + + private String renderClassLink(JApiClass clazz) { + final String name = clazz.getFullyQualifiedName(); + return md.options.isReportOnlySummary() ? name : references.link(HASH + renderSlug(name), name, null).toString(); + } + + private String renderClassSimpleName(JApiClass clazz) { + final String simpleName = formatTypeName(clazz.getFullyQualifiedName(), emptyList(), true); + return renderChange(clazz, renderCode(simpleName)); + } + + private String renderClassType(JApiClass clazz) { + final JApiClassType classType = clazz.getClassType(); + return renderChange(classType, md.message.getClassType(classType.getOldTypeOptional()), md.message.getClassType(classType.getNewTypeOptional())); + } + + private String renderClassSuperclass(JApiClass clazz) { + final JApiSuperclass superclass = clazz.getSuperclass(); + final JApiClass correspondingClass = superclass.getCorrespondingJApiClass().or((JApiClass) null); + return renderChange(superclass, + renderTypeWithGenericTemplates(superclass.getOldSuperclassName().or((String) null), superclass, correspondingClass), + renderTypeWithGenericTemplates(superclass.getNewSuperclassName().or((String) null), superclass, correspondingClass)); + } + + private String renderClassJdk(JApiClass clazz) { + final JApiClassFileFormatVersion version = clazz.getClassFileFormatVersion(); + return renderChange(version, getOldJdkVersion(version), getNewJdkVersion(version)); + } + + private String renderGenericTemplateName(JApiGenericTemplate genericTemplate) { + return renderChange(genericTemplate, renderCode(genericTemplate.getName())); + } + + private String renderGenericTemplateType(JApiGenericTemplate genericTemplate) { + return renderChange(genericTemplate, + renderTypeWithGenericTypes(genericTemplate.getOldType(), genericTemplate.getOldGenericTypes()), + renderTypeWithGenericTypes(genericTemplate.getNewType(), genericTemplate.getNewGenericTypes())); + } + + private String renderImplementedInterfaceName(JApiImplementedInterface implInterface) { + return renderChange(implInterface, renderTypeWithGenericTemplates( + implInterface.getFullyQualifiedName(), implInterface, implInterface.getCorrespondingJApiClass().or((JApiClass) null))); + } + + private String renderNameAndParameters(JApiBehavior behavior) { + final String name = behavior.getName(); + final int pos = name != null ? name.lastIndexOf('$') : -1; + final String simpleName = pos > 0 ? name.substring(pos + 1) : name; + return renderChange(behavior, renderCode(simpleName)) + renderParameters(behavior); + } + + private String renderParameters(JApiBehavior behavior) { + return parenthesis(behavior.getParameters().stream().map(x -> renderParameter(behavior, x)).collect(CSV)); + } + + private String renderParameter(JApiBehavior method, JApiParameter parameter) { + if (parameter.getTemplateNameOptional().isPresent()) { + return renderChange(parameter, renderCode(parameter.getTemplateName())); + } + final JApiChangeStatus status = method.getChangeStatus(); + final JApiModifier varargs = method.getVarargsModifier(); + final String oldType = (status == NEW) ? null : renderParameterType(method, parameter, varargs.getOldModifier(), parameter.getOldGenericTypes()); + final String newType = (status == REMOVED) ? null : renderParameterType(method, parameter, varargs.getNewModifier(), parameter.getNewGenericTypes()); + return renderChange(parameter, oldType, newType); + } + + private String renderGenericTemplates(JApiBehavior behavior) { + final List genericTemplates = behavior.getGenericTemplates(); + if (genericTemplates.isEmpty()) { + return EMPTY; + } + return BACKSLASH + ANGLE_OPEN + + genericTemplates.stream().map(this::renderGenericTemplate).collect(CSV) + + BACKSLASH + ANGLE_CLOSE; + } + + private String renderGenericTemplate(JApiGenericTemplate genericTemplate) { + final String name = genericTemplate.getName(); + final String oldTemplate = renderGenericTemplate(name, genericTemplate.getOldTypeOptional().or((String) null), genericTemplate.getOldGenericTypes()); + final String newTemplate = renderGenericTemplate(name, genericTemplate.getNewTypeOptional().or((String) null), genericTemplate.getNewGenericTypes()); + return renderChange(genericTemplate, oldTemplate, newTemplate); + } + + private String renderGenericTemplate(String name, String type, List genericTypes) { + final String fullType = formatGenericTemplate(name, type, genericTypes, false); + final String simpleType = formatGenericTemplate(name, type, genericTypes, true); + return renderCodeWithTooltip(fullType, simpleType); + } + + private String renderCompatibilityChanges(List changes) { + if (changes.isEmpty()) { + return renderNoChangesBadge(); + } + return changes.stream().map(this::renderChangeBadge).collect(SPACES); + } + + private String renderCompatibilityChanges(JApiCompatibility hasCompatibilityChanges) { + return renderCompatibilityChanges(hasCompatibilityChanges.getCompatibilityChanges()); + } + + @SafeVarargs + private final String renderCompatibilityChanges(List... haveCompatibilityChanges) { + return renderCompatibilityChanges(Stream.of(haveCompatibilityChanges).flatMap(List::stream) + .map(JApiCompatibility::getCompatibilityChanges).flatMap(List::stream).distinct().collect(toList())); + } + + private String renderAllCompatibilityChanges(JApiClass clazz) { + return renderCompatibilityChanges(Stream.of( + singletonList(clazz), + singletonList(clazz.getClassFileFormatVersion()), + singletonList(clazz.getSuperclass()), + clazz.getGenericTemplates(), + clazz.getInterfaces(), + clazz.getAnnotations(), + clazz.getAnnotations().stream().map(JApiAnnotation::getElements).flatMap(List::stream).collect(toList()), + clazz.getConstructors(), + clazz.getConstructors().stream().map(JApiConstructor::getParameters).flatMap(List::stream).collect(toList()), + clazz.getMethods(), + clazz.getMethods().stream().map(JApiMethod::getReturnType).collect(toList()), + clazz.getMethods().stream().map(JApiMethod::getParameters).flatMap(List::stream).collect(toList()), + clazz.getFields()) + .flatMap(List::stream) + .map(JApiCompatibility::getCompatibilityChanges) + .flatMap(List::stream) + .distinct().sorted(Comparator.comparing(JApiCompatibilityChange::getType)) + .collect(toList())); + } + + private String renderClassLevelCompatibilityChanges(JApiClass clazz) { + return renderCompatibilityChanges(Arrays.asList(clazz, clazz.getClassFileFormatVersion(), clazz.getSuperclass())); + } + + private String renderAllCompatibilityChanges(JApiAnnotation annotation) { + return renderCompatibilityChanges(singletonList(annotation), annotation.getElements()); + } + + private String renderAllCompatibilityChanges(JApiConstructor constructor) { + return renderCompatibilityChanges(singletonList(constructor), constructor.getParameters()); + } + + private String renderAllCompatibilityChanges(JApiMethod method) { + return renderCompatibilityChanges(singletonList(method), singletonList(method.getReturnType()), method.getParameters()); + } + + private String renderNoChangesBadge() { + return new MarkdownBadge(null, md.message.noCompatibilityChanges, md.message.colorNoChanges) + .toRefImage(references).toString(); + } + + private String renderChangeBadge(JApiCompatibilityChange change) { + final JApiCompatibilityChangeType type = change.getType(); + return new MarkdownBadge(null, md.message.compatibilityChangeType.getOrDefault(type, type.name()), md.message.getSemanticColor(change.getSemanticVersionLevel())) + .toRefImage(references).toString(); + } + + private String renderSerializationChange(JApiClass clazz) { + final JApiJavaObjectSerializationChangeStatus change = clazz.getJavaObjectSerializationCompatible(); + final String text = md.message.serializationCompatibility.getOrDefault(change, change.getDescription()); + final String color = change.isIncompatible() ? md.message.colorMajorChanges : md.message.colorNoChanges; + final String msg = change.isIncompatible() ? md.message.statusIncompatible : text; + return new MarkdownBadge(null, msg, color).toRefImage(references, text).toString(); + } + + private String renderChange(JApiHasChangeStatus hasStatus, String oldValue, String newValue) { + if (oldValue == null && newValue == null) { + return null; + } + switch (hasStatus.getChangeStatus()) { + case NEW: + return newValue == null ? null : format(md.message.added, newValue); + case REMOVED: + return oldValue == null ? null : format(md.message.removed, oldValue); + case UNCHANGED: + if (newValue == null) { + return format(md.message.unchanged, oldValue); + } else if (oldValue == null || newValue.equals(oldValue)) { + return format(md.message.unchanged, newValue); + } + return format(md.message.modified, oldValue, newValue); + default: + case MODIFIED: + if (oldValue == null) { + return format(md.message.added, newValue); + } else if (newValue == null) { + return format(md.message.removed, oldValue); + } else if (newValue.equals(oldValue)) { + return format(md.message.unchanged, newValue); + } + return format(md.message.modified, oldValue, newValue); + } + } + + private String renderChange(JApiHasChangeStatus status, String value) { + return renderChange(status, value, value); + } + + private String renderModifiers(JApiHasModifiers clazz) { + return clazz.getModifiers().stream().map(this::renderModifier) + .filter(Objects::nonNull).collect(SPACES); + } + + private String renderModifier(JApiModifier>> modifier) { + final String oldName = getOldModifierName(modifier).or((String) null); + final String newName = getNewModifierName(modifier).or((String) null); + return renderChange(modifier, renderCode(oldName), renderCode(newName)); + } + + private String renderTypeWithGenericTypes(String type, List genericTypes) { + if (type == null) { + return null; + } + final String fullType = formatTypeName(type, genericTypes, false); + final String simpleType = formatTypeName(type, genericTypes, true); + return renderCodeWithTooltip(fullType, simpleType); + } + + private String renderTypeWithGenericTemplates(String type, JApiHasChangeStatus hasChangeStatus, JApiHasGenericTemplates hasGenericTemplates) { + if (type == null) { + return null; + } + final String fullType = formatTypeName(type, hasChangeStatus, hasGenericTemplates, false); + final String simpleType = formatTypeName(type, hasChangeStatus, hasGenericTemplates, true); + return renderCodeWithTooltip(fullType, simpleType); + } + + private String renderParameterType(JApiBehavior method, JApiParameter parameter, Optional varargs, List genericTypes) { + if (parameter.getType() == null) { + return null; + } + final String fullType = formatParameterTypeName(method, parameter, varargs, genericTypes, false); + final String simpleType = formatParameterTypeName(method, parameter, varargs, genericTypes, true); + return renderCodeWithTooltip(fullType, simpleType); + } + + private String renderMemberValue(Optional optionalValue) { + if (!optionalValue.isPresent()) { + return EMPTY; + } + final String fullValue = formatMemberValue(optionalValue.get(), false); + final String simpleValue = formatMemberValue(optionalValue.get(), true); + return renderCodeWithTooltip(fullValue, simpleValue); + } + + private String renderReturnType(JApiMethod method) { + final JApiReturnType returnType = method.getReturnType(); + return renderChange(returnType, + renderTypeWithGenericTypes(returnType.getOldReturnType(), returnType.getOldGenericTypes()), + renderTypeWithGenericTypes(returnType.getNewReturnType(), returnType.getNewGenericTypes())); + } + + private String renderFieldType(JApiField field) { + final JApiType fieldType = field.getType(); + return renderChange(fieldType, + renderTypeWithGenericTypes(fieldType.getOldValue(), field.getOldGenericTypes()), + renderTypeWithGenericTypes(fieldType.getNewValue(), field.getNewGenericTypes())); + } + + private String renderFieldName(JApiField field) { + return renderCode(field.getName()); + } + + private String renderExceptions(JApiBehavior behavior) { + return behavior.getExceptions().stream().map(this::renderException).collect(CSV); + } + + private String renderException(JApiException exception) { + return renderChange(exception, renderTypeWithGenericTypes(exception.getName(), emptyList())); + } + + private String renderInlineAnnotations(JApiHasAnnotations hasAnnotations) { + return hasAnnotations.getAnnotations().stream().map(this::renderAnnotation).collect(BR); + } + + private String renderAnnotation(JApiAnnotation annotation) { + final String typeName = renderTypeWithGenericTemplates(annotation.getFullyQualifiedName(), annotation, annotation.getCorrespondingJApiClass().or((JApiClass) null)); + return renderChange(annotation, typeName) + + (annotation.getElements().isEmpty() ? EMPTY : COLON + SPACE) + + annotation.getElements().stream().map(this::renderAnnotationElement).collect(CSV); + } + + private String renderAnnotationElement(JApiAnnotationElement element) { + return renderChange(element, renderCode(element.getName())) + EQUAL + + renderChange(element, renderMemberValue(element.getOldValue()), renderMemberValue(element.getNewValue())); + } + + private String renderCode(String text) { + return text == null || text.isEmpty() ? text : backticks(text); + } + + private String renderCodeWithTooltip(String fullType, String simpleType) { + if (fullType.equals(simpleType)) { + return renderCode(simpleType); + } + return references.link(null, renderCode(simpleType), fullType).toString(); + } + + String renderArchive(JApiCmpArchive archive) { + final String label = renderSimpleArchiveName(archive); + final String version = archive.getVersion().getStringVersion(); + final String message = version != null && !version.equals(N_A) ? version : md.message.unknownVersion; + return new MarkdownBadge(label, message, md.message.colorVersionNumber).toString(); + } + + String renderSimpleArchiveName(JApiCmpArchive archive) { + final String version = archive.getVersion().getStringVersion(); + String name = archive.getFile().getName(); + // Drop version from archive name + if (version != null && name.contains(version)) { + name = name.replace(version, EMPTY); + } + // Drop extension from archive name + final int dot = name.lastIndexOf(DOT); + if (dot > 0) { + name = name.substring(0, dot); + } + // Drop trailing dashes or underscores + if (name.endsWith(DASH) || name.endsWith(UNDERSCORE)) { + name = name.substring(0, name.length() - 1); + } + return name; + } +} diff --git a/japicmp/src/main/java/japicmp/output/markdown/MarkdownRefImage.java b/japicmp/src/main/java/japicmp/output/markdown/MarkdownRefImage.java new file mode 100644 index 000000000..aa7a5297a --- /dev/null +++ b/japicmp/src/main/java/japicmp/output/markdown/MarkdownRefImage.java @@ -0,0 +1,13 @@ +package japicmp.output.markdown; + +final class MarkdownRefImage extends MarkdownRefLink { + + MarkdownRefImage(String alt, MarkdownStoredReference reference) { + super(alt, reference); + } + + @Override + public String toString() { + return BANG + super.toString(); + } +} diff --git a/japicmp/src/main/java/japicmp/output/markdown/MarkdownRefLink.java b/japicmp/src/main/java/japicmp/output/markdown/MarkdownRefLink.java new file mode 100644 index 000000000..50119f923 --- /dev/null +++ b/japicmp/src/main/java/japicmp/output/markdown/MarkdownRefLink.java @@ -0,0 +1,17 @@ +package japicmp.output.markdown; + +class MarkdownRefLink extends Markdown { + private final String text; + private final MarkdownStoredReference reference; + + MarkdownRefLink(String text, MarkdownStoredReference reference) { + this.text = text != null ? text : EMPTY; + this.reference = reference; + } + + @Override + public String toString() { + return brackets(text) + + (text.equals(reference.id) ? EMPTY : brackets(reference.id)); + } +} diff --git a/japicmp/src/main/java/japicmp/output/markdown/MarkdownReference.java b/japicmp/src/main/java/japicmp/output/markdown/MarkdownReference.java new file mode 100644 index 000000000..ce2a09d47 --- /dev/null +++ b/japicmp/src/main/java/japicmp/output/markdown/MarkdownReference.java @@ -0,0 +1,40 @@ +package japicmp.output.markdown; + +import japicmp.util.Optional; +import java.util.Objects; + +class MarkdownReference extends Markdown { + + final String href; + final String title; + + MarkdownReference(String href, String title) { + this.href = Optional.fromNullable(href).or(HASH); + this.title = title; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } else if (obj instanceof MarkdownReference) { + final MarkdownReference that = (MarkdownReference) obj; + return Objects.equals(href, that.href) && Objects.equals(title, that.title); + } + return false; + } + + @Override + public int hashCode() { + return Objects.hash(href, title); + } + + @Override + public String toString() { + if (title == null || title.isEmpty()) { + return href; + } + final String sanitizedTitle = title.replace(QUOTE, BACKSLASH + QUOTE); + return href + SPACE + quotes(sanitizedTitle); + } +} diff --git a/japicmp/src/main/java/japicmp/output/markdown/MarkdownReferences.java b/japicmp/src/main/java/japicmp/output/markdown/MarkdownReferences.java new file mode 100644 index 000000000..8e2c4a2d3 --- /dev/null +++ b/japicmp/src/main/java/japicmp/output/markdown/MarkdownReferences.java @@ -0,0 +1,48 @@ +package japicmp.output.markdown; + +import static java.util.Comparator.comparing; + +import java.util.ArrayList; +import java.util.List; + +final class MarkdownReferences extends Markdown { + + private final List references = new ArrayList<>(); + private int referenceId; + + MarkdownStoredReference make(String href, String id, String title) { + final MarkdownReference reference = new MarkdownReference(href, title); + return references.stream().filter(reference::equals).findAny() + .orElseGet(() -> storeReference(id, reference)); + } + + MarkdownRefLink link(String href, String text, String title) { + return make(href, text, title).toLink(text); + } + + private MarkdownStoredReference storeReference(String id, MarkdownReference reference) { + final MarkdownStoredReference stored; + if (isIllegalReferenceId(id) || alreadyUsedReferenceId(id)) { + stored = new MarkdownStoredReference(++referenceId, reference); + } else { + stored = new MarkdownStoredReference(id, reference); + } + references.add(stored); + return stored; + } + + private boolean isIllegalReferenceId(String text) { + return text == null || text.isEmpty() || text.contains(BRACKET_OPEN) || text.contains(BRACKET_CLOSE); + } + + private boolean alreadyUsedReferenceId(String id) { + return references.stream().map(MarkdownStoredReference::getId).anyMatch(id::equals); + } + + @Override + public String toString() { + return references.stream() + .sorted(comparing(MarkdownStoredReference::getIndex).thenComparing(MarkdownStoredReference::getId)) + .map(MarkdownStoredReference::toString).collect(LINES); + } +} diff --git a/japicmp/src/main/java/japicmp/output/markdown/MarkdownSection.java b/japicmp/src/main/java/japicmp/output/markdown/MarkdownSection.java new file mode 100644 index 000000000..4b42b5db0 --- /dev/null +++ b/japicmp/src/main/java/japicmp/output/markdown/MarkdownSection.java @@ -0,0 +1,54 @@ +package japicmp.output.markdown; + +import static java.util.Collections.singletonList; +import static java.util.stream.Collectors.toList; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.function.Function; +import java.util.stream.Stream; + +final class MarkdownSection extends Markdown { + + private final String title; + private final List list; + private final Comparator comparator; + private final List> columns = new ArrayList<>(); + + MarkdownSection(String title, List list, Comparator comparator) { + this.title = title; + this.list = list; + this.comparator = comparator; + } + + MarkdownSection(String title, T one) { + this(title, singletonList(one), null); + } + + MarkdownSection column(String header, Function mapper) { + this.columns.add(new Column<>(header, mapper)); + return this; + } + + @Override + public String toString() { + if (list.isEmpty()) { + return EMPTY; + } + final Stream stream = comparator == null ? list.stream() : list.stream().sorted(comparator); + final MarkdownTable table = new MarkdownTable(columns.stream().map(column -> column.header).collect(toList())); + stream.forEach(x -> table.addRow(columns.stream().map(column -> column.mapper.apply(x)).collect(toList()))); + return title + table; + } + + private static final class Column { + final String header; + final Function mapper; + + Column(String header, Function mapper) { + this.header = header; + this.mapper = mapper; + } + } +} diff --git a/japicmp/src/main/java/japicmp/output/markdown/MarkdownStoredReference.java b/japicmp/src/main/java/japicmp/output/markdown/MarkdownStoredReference.java new file mode 100644 index 000000000..da41bb672 --- /dev/null +++ b/japicmp/src/main/java/japicmp/output/markdown/MarkdownStoredReference.java @@ -0,0 +1,41 @@ +package japicmp.output.markdown; + +final class MarkdownStoredReference extends MarkdownReference { + final int index; + final String id; + + MarkdownStoredReference(int index, String id, MarkdownReference reference) { + super(reference.href, reference.title); + this.index = index; + this.id = id; + } + + MarkdownStoredReference(String id, MarkdownReference reference) { + this(Integer.MAX_VALUE, id, reference); + } + + MarkdownStoredReference(int index, MarkdownReference reference) { + this(index, String.valueOf(index), reference); + } + + int getIndex() { + return index; + } + + String getId() { + return id; + } + + MarkdownRefImage toImage(String alt) { + return new MarkdownRefImage(alt, this); + } + + MarkdownRefLink toLink(String text) { + return new MarkdownRefLink(text, this); + } + + @Override + public String toString() { + return brackets(id) + COLON + SPACE + super.toString(); + } +} diff --git a/japicmp/src/main/java/japicmp/output/markdown/MarkdownTable.java b/japicmp/src/main/java/japicmp/output/markdown/MarkdownTable.java new file mode 100644 index 000000000..66af1154e --- /dev/null +++ b/japicmp/src/main/java/japicmp/output/markdown/MarkdownTable.java @@ -0,0 +1,97 @@ +package japicmp.output.markdown; + +import static java.util.stream.Collectors.joining; + +import java.util.*; +import java.util.function.Function; +import java.util.stream.*; + +final class MarkdownTable extends Markdown { + + final int columns; + final List> rows = new ArrayList<>(); + + MarkdownTable(List headers) { + columns = headers.size(); + rows.add(headers); + } + + static String getColumnFormat(int width) { + return width < 1 ? "%s" : "%-" + width + "s"; + } + + void addRow(List row) { + rows.add(row); + } + + @Override + public String toString() { + if (rows.size() == 1) { + return EMPTY; + } + final Map colWidths = calculateColumnWidths(); + return IntStream.range(0, rows.size()).mapToObj(r -> { + final List row = rows.get(r); + final StringBuilder tmp = new StringBuilder(); + tmp.append(new Row(row, colWidths)); + if (r == 0) { + tmp.append(PIPE); + IntStream.range(0, columns).forEach(index -> tmp + .append(DASH) + .append(String.format(getColumnFormat(colWidths.get(index)), EMPTY).replace(SPACE, DASH)) + .append(DASH) + .append(PIPE)); + tmp.append(EOL); + } + return tmp.toString(); + }).collect(joining()) + EOL; + } + + private Map calculateColumnWidths() { + return IntStream.range(0, columns).mapToObj(Integer.class::cast) + .collect(Collectors.toMap(Function.identity(), this::calculateMaxWidth)); + } + + private int calculateMaxWidth(int index) { + if (index + 1 < columns) { + // Columns adjust dynamically up to a fixed limit + return rows.stream().map(x -> x.get(index)).mapToInt(String::length).filter(x -> x <= 64).max().orElse(0); + } + // Last column adjusts to heading size + return rows.get(0).get(index).length(); + } + + private class Row { + + final List data; + final Map widths; + int offset = 0; + + Row(List data, Map widths) { + this.data = data; + this.widths = widths; + } + + String formatColumn(int index) { + final int width = widths.get(index); + final int maxWidth = Math.max(0, width - offset); + final String formatted = String.format(getColumnFormat(maxWidth), data.get(index)); + final int length = formatted.length(); + if (length <= width) { + offset -= width - length; + } else if (length > maxWidth) { + offset += length - maxWidth; + } + offset = Math.max(0, offset); + return formatted; + } + + @Override + public String toString() { + return PIPE + IntStream.range(0, columns) + .mapToObj(index -> SPACE + formatColumn(index) + SPACE + PIPE) + .collect(joining()) + + EOL; + } + } +} diff --git a/japicmp/src/main/java/japicmp/output/markdown/config/MarkdownHeaderOptions.java b/japicmp/src/main/java/japicmp/output/markdown/config/MarkdownHeaderOptions.java new file mode 100644 index 000000000..487ed83da --- /dev/null +++ b/japicmp/src/main/java/japicmp/output/markdown/config/MarkdownHeaderOptions.java @@ -0,0 +1,26 @@ +package japicmp.output.markdown.config; + +public class MarkdownHeaderOptions { + + public String annotationName = "Annotation"; + public String annotations = "Annotations"; + public String className = "Name"; + public String classType = "Type"; + public String compatibilityChanges = "Compatibility Changes"; + public String constructorNameAndParameters = "Constructor"; + public String exceptions = "Throws"; + public String fieldName = "Name"; + public String fieldType = "Type"; + public String genericTemplateName = "Name"; + public String genericTemplateType = "Extends"; + public String generics = "Generics"; + public String interfaceName = "Interface"; + public String classJdk = "JDK"; + public String methodNameAndParameters = "Method"; + public String methodReturnType = "Type"; + public String modifiers = "Modifiers"; + public String serialization = "Serialization"; + public String status = "Status"; + public String superclass = "Extends"; + public String type = "Type"; +} diff --git a/japicmp/src/main/java/japicmp/output/markdown/config/MarkdownMessageOptions.java b/japicmp/src/main/java/japicmp/output/markdown/config/MarkdownMessageOptions.java new file mode 100644 index 000000000..a8e1c8842 --- /dev/null +++ b/japicmp/src/main/java/japicmp/output/markdown/config/MarkdownMessageOptions.java @@ -0,0 +1,186 @@ +package japicmp.output.markdown.config; + +import static japicmp.output.markdown.Markdown.*; +import static japicmp.output.semver.SemverOut.*; +import static java.util.Arrays.stream; +import static java.util.function.Function.identity; +import static java.util.stream.Collectors.toMap; + +import japicmp.model.*; +import japicmp.model.JApiJavaObjectSerializationCompatibility.JApiJavaObjectSerializationChangeStatus; +import japicmp.output.markdown.MarkdownBadge; +import japicmp.util.Optional; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Map; + +public class MarkdownMessageOptions { + + public String summaryMajorChanges = "> [!CAUTION]\n>\n> Incompatible changes found while checking backward compatibility of %s with %s."; + public String summaryMinorChanges = "> [!WARNING]\n>\n> Compatible changes found while checking backward compatibility of %s with %s."; + public String summaryPatchChanges = "> [!IMPORTANT]\n>\n> Compatible bug fixes found while checking backward compatibility of %s with %s."; + public String summaryNoChanges = "> [!NOTE]\n>\n> No incompatible changes found while checking backward compatibility of %s with %s."; + + public String oneNewVersion = "version `%s`"; + public String oneOldVersion = "the previous version `%s`"; + public String manyNewArchives = "several archives"; + public String manyOldArchives = "their previous versions"; + public String unknownVersion = "unknown"; + public String expandResults = "Expand for details."; + public String expandOptions = "Expand to see options used."; + + public String warningAllMissingClassesIgnored = "> [!WARNING]\n>\n> All missing classes, i.e. superclasses and interfaces that could not be found on the classpath were ignored.\n>\n> Hence changes caused by these superclasses and interfaces are not reflected in the output.\n\n"; + public String warningSomeMissingClassesIgnored = "> [!WARNING]\n>\n> Certain classes, i.e. superclasses and interfaces that could not be found on the classpath were ignored.\n>\n> Hence changes caused by these superclasses and interfaces are not reflected in the output.\n\n"; + + public String generatedOn = "*Generated on: %s*."; + public String dateTimeFormat = "yyyy-MM-dd HH:mm:ss.SSSZ"; + + public String classpathMode = "**Classpath mode**: `%s`"; + public String oldArchives = "**Old archives**:%s"; + public String newArchives = "**New archives**:%s"; + public String oldClasspath = "**Old classpath**:\n```\n%s\n```"; + public String newClasspath = "**New classpath**:\n```\n%s\n```"; + public String accessModifierFilter = "**Access modifier filter**: `%s`"; + public String evaluateAnnotations = "**Evaluate annotations**: %s"; + public String reportOnlyChanges = "**Report only changes**: %s"; + public String reportOnlyBinaryIncompatibleChanges = "**Report only binary-incompatible changes**: %s"; + public String includeSpecificElements = "**Include specific elements**: %s"; + public String includeSynthetic = "**Include synthetic classes and class members**: %s"; + public String excludeSpecificElements = "**Exclude specific elements**: %s"; + public String ignoreAllMissingClasses = "**Ignore all missing classes**: %s"; + public String ignoreSpecificMissingClasses = "**Ignore specific missing classes**: %s"; + public String treatChangesAsErrors = "**Treat changes as errors**:%s"; + + public String anyChanges = "Any changes: %s"; + public String binaryIncompatibleChanges = "Binary incompatible changes: %s"; + public String sourceIncompatibleChanges = "Source incompatible changes: %s"; + public String incompatibleChangesCausedByExcludedClasses = "Incompatible changes caused by excluded classes: %s"; + public String semanticallyIncompatibleChanges = "Semantically incompatible changes: %s"; + public String semanticallyIncompatibleChangesIncludingDevelopmentVersions = "Semantically incompatible changes, including development versions: %s"; + + public String added = "**%s**"; + public String removed = "~~%s~~"; + public String modified = "~~%s~~ → **%s**"; + public String unchanged = "%s"; + + public String yes = "Yes"; + public String no = "No"; + + public String checked = "[X]"; + public String unchecked = "[ ]"; + + public String compatibilityBinary = "%s Binary-compatible"; + public String compatibilitySource = "%s Source-compatible"; + public String compatibilitySerialization = "%s Serialization-compatible"; + + public String noCompatibilityChanges = "No changes"; + + public String colorMajorChanges = "red"; + public String colorMinorChanges = "orange"; + public String colorPatchChanges = "yellow"; + public String colorNoChanges = "green"; + public String colorVersionNumber = "blue"; + + public String badgeMajorChanges = new MarkdownBadge("semver", "MAJOR", colorMajorChanges, "semver").toString(); + public String badgeMinorChanges = new MarkdownBadge("semver", "MINOR", colorMinorChanges, "semver").toString(); + public String badgePatchChanges = new MarkdownBadge("semver", "PATCH", colorPatchChanges, "semver").toString(); + public String badgeNoChanges = new MarkdownBadge("semver", "OK", colorNoChanges, "semver").toString(); + + public String typeAnnotation = "Annotation"; + public String typeInterface = "Interface"; + public String typeClass = "Class"; + public String typeEnum = "Enum"; + + public String statusNew = "Added"; + public String statusRemoved = "Removed"; + public String statusModified = "Modified"; + public String statusUnchanged = "Unchanged"; + public String statusIncompatible = "Incompatible"; + public String statusSourceIncompatible = "Source-incompatible"; + public String statusBinaryIncompatible = "Binary-incompatible"; + public String statusSerializationIncompatible = "Serialization-incompatible"; + + public Map serializationCompatibility = + stream(JApiJavaObjectSerializationChangeStatus.values()).collect(toMap(identity(), e -> capitalize(e.getDescription()))); + + public Map compatibilityChangeType = + stream(JApiCompatibilityChangeType.values()).collect(toMap(identity(), e -> capitalize(e.name()))); + + private static String capitalize(String text) { + return text.substring(0, 1).toUpperCase() + text.substring(1).toLowerCase().replace(UNDERSCORE, SPACE); + } + + public String getSemanticColor(JApiSemanticVersionLevel level) { + switch (level) { + default: + case MAJOR: + return colorMajorChanges; + case MINOR: + return colorMinorChanges; + case PATCH: + return colorPatchChanges; + } + } + + public String getSemverBadge(String semver) { + switch (semver) { + case SEMVER_MAJOR: + return badgeMajorChanges; + case SEMVER_MINOR: + return badgeMinorChanges; + case SEMVER_PATCH: + return badgePatchChanges; + case SEMVER_COMPATIBLE: + default: + return badgeNoChanges; + } + } + + public String getSummaryMessage(String semver) { + switch (semver) { + case SEMVER_MAJOR: + return summaryMajorChanges; + case SEMVER_MINOR: + return summaryMinorChanges; + case SEMVER_PATCH: + return summaryPatchChanges; + case SEMVER_COMPATIBLE: + default: + return summaryNoChanges; + } + } + + public String getClassType(Optional classType) { + if (!classType.isPresent()) { + return EMPTY; + } + switch (classType.get()) { + case ANNOTATION: + return typeAnnotation; + case INTERFACE: + return typeInterface; + default: + case CLASS: + return typeClass; + case ENUM: + return typeEnum; + } + } + + public String getCurrentTimestamp() { + final ZonedDateTime now = ZonedDateTime.now(); + try { + return DateTimeFormatter.ofPattern(dateTimeFormat).format(now); + } catch (Exception e) { + return now.toString(); + } + } + + public String yesNo(boolean value) { + return value ? yes : no; + } + + public String checkbox(boolean value) { + return value ? checked : unchecked; + } +} diff --git a/japicmp/src/main/java/japicmp/output/markdown/config/MarkdownOptions.java b/japicmp/src/main/java/japicmp/output/markdown/config/MarkdownOptions.java new file mode 100644 index 000000000..2898620ee --- /dev/null +++ b/japicmp/src/main/java/japicmp/output/markdown/config/MarkdownOptions.java @@ -0,0 +1,37 @@ +package japicmp.output.markdown.config; + +import japicmp.config.Options; +import japicmp.util.Optional; + +public class MarkdownOptions { + + public Options options; + + public Optional targetOldVersion = Optional.absent(); + public Optional targetNewVersion = Optional.absent(); + + public MarkdownTitleOptions title = new MarkdownTitleOptions(); + public MarkdownHeaderOptions header = new MarkdownHeaderOptions(); + public MarkdownSortOptions sort = new MarkdownSortOptions(); + public MarkdownMessageOptions message = new MarkdownMessageOptions(); + + MarkdownOptions(Options options) { + this.options = options != null ? options : Options.newDefault(); + } + + public static MarkdownOptions newDefault() { + return new MarkdownOptions(null); + } + + public static MarkdownOptions newDefault(Options options) { + return new MarkdownOptions(options); + } + + public void setTargetOldVersion(String targetOldVersion) { + this.targetOldVersion = Optional.fromNullable(targetOldVersion); + } + + public void setTargetNewVersion(String targetNewVersion) { + this.targetNewVersion = Optional.fromNullable(targetNewVersion); + } +} diff --git a/japicmp/src/main/java/japicmp/output/markdown/config/MarkdownSortOptions.java b/japicmp/src/main/java/japicmp/output/markdown/config/MarkdownSortOptions.java new file mode 100644 index 000000000..3aeb2567b --- /dev/null +++ b/japicmp/src/main/java/japicmp/output/markdown/config/MarkdownSortOptions.java @@ -0,0 +1,23 @@ +package japicmp.output.markdown.config; + +import static java.util.Comparator.comparing; + +import japicmp.model.JApiAnnotation; +import japicmp.model.JApiClass; +import japicmp.model.JApiConstructor; +import japicmp.model.JApiField; +import japicmp.model.JApiGenericTemplate; +import japicmp.model.JApiImplementedInterface; +import japicmp.model.JApiMethod; +import java.util.Comparator; + +public class MarkdownSortOptions { + + public Comparator classes = comparing(JApiClass::getFullyQualifiedName); + public Comparator generics = null; + public Comparator interfaces = comparing(JApiImplementedInterface::getFullyQualifiedName); + public Comparator annotations = comparing(JApiAnnotation::getFullyQualifiedName); + public Comparator constructors = null; + public Comparator methods = comparing(JApiMethod::getName); + public Comparator fields = comparing(JApiField::getName); +} diff --git a/japicmp/src/main/java/japicmp/output/markdown/config/MarkdownTitleOptions.java b/japicmp/src/main/java/japicmp/output/markdown/config/MarkdownTitleOptions.java new file mode 100644 index 000000000..4356093ce --- /dev/null +++ b/japicmp/src/main/java/japicmp/output/markdown/config/MarkdownTitleOptions.java @@ -0,0 +1,15 @@ +package japicmp.output.markdown.config; + +public class MarkdownTitleOptions { + + public int topHeadingLevel = 1; + public String report = "Compatibility Report"; + public String summary = "Summary"; + public String results = "Results"; + public String generics = "Generics"; + public String interfaces = "Implemented Interfaces"; + public String annotations = "Annotations"; + public String constructors = "Constructors"; + public String methods = "Methods"; + public String fields = "Fields"; +} diff --git a/japicmp/src/main/java/japicmp/util/JApiClassFileFormatVersionHelper.java b/japicmp/src/main/java/japicmp/util/JApiClassFileFormatVersionHelper.java new file mode 100644 index 000000000..545f928c4 --- /dev/null +++ b/japicmp/src/main/java/japicmp/util/JApiClassFileFormatVersionHelper.java @@ -0,0 +1,71 @@ +package japicmp.util; + +import japicmp.model.JApiClassFileFormatVersion; + +public class JApiClassFileFormatVersionHelper { + + private JApiClassFileFormatVersionHelper() { + } + + public static String getOldJdkVersion(JApiClassFileFormatVersion x) { + return getJdkVersion(x.getMajorVersionOld(), x.getMinorVersionOld()); + } + + public static String getNewJdkVersion(JApiClassFileFormatVersion x) { + return getJdkVersion(x.getMajorVersionNew(), x.getMinorVersionNew()); + } + + private static String getJdkVersion(int major, int minor) { + if (major == -1 || minor == -1) { + return ""; + } + if (major == 45) { + return minor < 3 ? "JDK 1.0" : "JDK 1.1"; + } else if (major == 46) { + return "JDK 1.2"; + } else if (major == 47) { + return "JDK 1.3"; + } else if (major == 48) { + return "JDK 1.4"; + } else if (major == 49) { + return "JDK 5.0"; + } else if (major == 50) { + return "JDK 6"; + } else if (major == 51) { + return "JDK 7"; + } else if (major == 52) { + return "JDK 8"; + } else if (major == 53) { + return "JDK 9"; + } else if (major == 54) { + return "JDK 10"; + } else if (major == 55) { + return "JDK 11"; + } else if (major == 56) { + return "JDK 12"; + } else if (major == 57) { + return "JDK 13"; + } else if (major == 58) { + return "JDK 14"; + } else if (major == 59) { + return "JDK 15"; + } else if (major == 60) { + return "JDK 16"; + } else if (major == 61) { + return "JDK 17"; + } else if (major == 62) { + return "JDK 18"; + } else if (major == 63) { + return "JDK 19"; + } else if (major == 64) { + return "JDK 20"; + } else if (major == 65) { + return "JDK 21"; + } else if (major == 66) { + return "JDK 22"; + } else if (major == 67) { + return "JDK 23"; + } + return "Version " + major + "." + minor; + } +} diff --git a/japicmp/src/main/java/japicmp/util/MemberValueHelper.java b/japicmp/src/main/java/japicmp/util/MemberValueHelper.java new file mode 100644 index 000000000..72814411b --- /dev/null +++ b/japicmp/src/main/java/japicmp/util/MemberValueHelper.java @@ -0,0 +1,59 @@ +package japicmp.util; + +import static japicmp.util.TypeNameHelper.formatTypeName; +import static java.util.Collections.emptyList; +import static java.util.stream.Collectors.joining; +import static java.util.Arrays.stream; + +import java.util.Set; +import javassist.bytecode.annotation.*; + +public class MemberValueHelper { + + private MemberValueHelper() { + } + + /** + * Formats an annotation's member value. + * + * @param value The member value. + * @param shorten Whether to truncate types to 32 characters or not. + * @return The formatted member value. + */ + public static String formatMemberValue(MemberValue value, boolean shorten) { + if (value instanceof AnnotationMemberValue) { + final Annotation annotation = ((AnnotationMemberValue) value).getValue(); + final Set names = annotation.getMemberNames(); + final String typeName = formatTypeName(annotation.getTypeName(), emptyList(), shorten); + if (names.isEmpty()) { + return typeName; + } + return typeName + "(" + names.stream().map(annotation::getMemberValue).map(MemberValue::toString).collect(joining(", ")) + ")"; + } else if (value instanceof ArrayMemberValue) { + return "{" + stream(((ArrayMemberValue) value).getValue()).map(x -> formatMemberValue(x, shorten)).collect(joining(", ")) + "}"; + } else if (value instanceof BooleanMemberValue) { + return Boolean.toString(((BooleanMemberValue) value).getValue()); + } else if (value instanceof ByteMemberValue) { + return Byte.toString(((ByteMemberValue) value).getValue()); + } else if (value instanceof CharMemberValue) { + return Character.toString(((CharMemberValue) value).getValue()); + } else if (value instanceof FloatMemberValue) { + return Float.toString(((FloatMemberValue) value).getValue()); + } else if (value instanceof DoubleMemberValue) { + return Double.toString(((DoubleMemberValue) value).getValue()); + } else if (value instanceof ShortMemberValue) { + return Short.toString(((ShortMemberValue) value).getValue()); + } else if (value instanceof IntegerMemberValue) { + return Integer.toString(((IntegerMemberValue) value).getValue()); + } else if (value instanceof LongMemberValue) { + return Long.toString(((LongMemberValue) value).getValue()); + } else if (value instanceof EnumMemberValue) { + return shorten ? ((EnumMemberValue) value).getValue() : value.toString(); + } else if (value instanceof StringMemberValue) { + return "\"" + ((StringMemberValue) value).getValue() + "\""; + } else if (value instanceof ClassMemberValue) { + return TypeNameHelper.formatTypeName(((ClassMemberValue) value).getValue(), emptyList(), shorten); + } + return value.toString(); + } +} diff --git a/japicmp/src/main/java/japicmp/util/ModifierHelper.java b/japicmp/src/main/java/japicmp/util/ModifierHelper.java index 98a6e2387..5f5ece8dc 100644 --- a/japicmp/src/main/java/japicmp/util/ModifierHelper.java +++ b/japicmp/src/main/java/japicmp/util/ModifierHelper.java @@ -2,15 +2,23 @@ import japicmp.cmp.JarArchiveComparatorOptions; import japicmp.config.Options; +import japicmp.model.AbstractModifier; import japicmp.model.AccessModifier; +import japicmp.model.BridgeModifier; +import japicmp.model.FinalModifier; import japicmp.model.JApiAttribute; import japicmp.model.JApiCanBeSynthetic; import japicmp.model.JApiChangeStatus; import japicmp.model.JApiHasAccessModifier; import japicmp.model.JApiModifier; import japicmp.model.JApiModifierBase; +import japicmp.model.StaticModifier; import japicmp.model.SyntheticAttribute; import japicmp.model.SyntheticModifier; +import japicmp.model.TransientModifier; +import japicmp.model.VolatileModifier; +import java.util.Arrays; +import java.util.List; import javassist.CtBehavior; import javassist.CtClass; import javassist.CtField; @@ -21,6 +29,17 @@ public class ModifierHelper { public static final int ACC_BRIDGE = 0x00000040; public static final int ACC_SYNTHETIC = 0x00001000; + private static final List IGNORED_MODIFIERS = Arrays.asList( + AbstractModifier.NON_ABSTRACT, + AccessModifier.PACKAGE_PROTECTED, + BridgeModifier.NON_BRIDGE, + FinalModifier.NON_FINAL, + StaticModifier.NON_STATIC, + SyntheticModifier.NON_SYNTHETIC, + TransientModifier.NON_TRANSIENT, + VolatileModifier.NON_VOLATILE + ); + private ModifierHelper() { } @@ -217,6 +236,19 @@ public static boolean isSynthetic(JApiCanBeSynthetic jApiClass) { return isSynthetic; } + public static Optional getOldModifierName(JApiModifier>> modifier) { + return getModifierName(modifier.getOldModifier()); + } + + public static Optional getNewModifierName(JApiModifier>> modifier) { + return getModifierName(modifier.getNewModifier()); + } + + private static Optional getModifierName(Optional> modifier) { + return !modifier.isPresent() || IGNORED_MODIFIERS.contains(modifier.get()) ? Optional.absent() : + Optional.of(modifier.get().name().toLowerCase()); + } + private static boolean hasSyntheticAttribute(JApiAttribute syntheticAttribute) { boolean hasSyntheticAttribute = false; if (syntheticAttribute.getOldAttribute().isPresent() && syntheticAttribute.getNewAttribute().isPresent()) { diff --git a/japicmp/src/main/java/japicmp/util/TypeNameHelper.java b/japicmp/src/main/java/japicmp/util/TypeNameHelper.java new file mode 100644 index 000000000..72800e46b --- /dev/null +++ b/japicmp/src/main/java/japicmp/util/TypeNameHelper.java @@ -0,0 +1,183 @@ +package japicmp.util; + +import static japicmp.model.VarargsModifier.*; +import static java.util.stream.Collectors.joining; + +import japicmp.model.*; +import java.util.List; + +public class TypeNameHelper { + + private static final String STR_ARRAY = "[]"; + private static final String STR_VARARGS = "..."; + + private TypeNameHelper() { + } + + /** + * Formats a generic template. + * + * @param name The generic template name. + * @param type The type extended by the generic template. + * @param genericTypes The generic types of the generic template. + * @param shorten Whether to truncate types to 32 characters or not. + * @return A string with the format {@code "NAME extends TYPE"}. + */ + public static String formatGenericTemplate(String name, String type, List genericTypes, boolean shorten) { + return type == null ? name : name + " extends " + formatTypeName(type, genericTypes, shorten); + } + + /** + * Formats a Java type in FQN form plus generic types. + * + * @param typeName The fully qualified type name to format. + * @param genericTypes The possibly empty list of generic types. + * @param maxLength The maximum number of characters that will be produced. + * If greater or equal to 3, the FQN will be truncated to its simple name, + * and surplus characters will be replaced with the ellipsis character. + * @return The formatted type. + */ + public static String formatTypeName(String typeName, List genericTypes, int maxLength) { + if (typeName == null || typeName.isEmpty() || typeName.equals(OptionalHelper.N_A)) { + return typeName; + } + return truncateTypeName(typeName, maxLength) + formatGenericTypes(genericTypes, maxLength); + } + + /** + * Formats a Java type in FQN form plus generic templates. + * + * @param typeName The fully qualified type name to format. + * @param hasChangeStatus The element that has a change status. + * @param hasGenericTemplates The element that has generic templates. + * @param maxLength The maximum number of characters that will be produced. + * If greater or equal to 3, the FQN will be truncated to its simple name, + * and surplus characters will be replaced with the ellipsis character. + * @return The formatted type. + */ + public static String formatTypeName(String typeName, JApiHasChangeStatus hasChangeStatus, JApiHasGenericTemplates hasGenericTemplates, int maxLength) { + if (typeName == null || typeName.isEmpty() || typeName.equals(OptionalHelper.N_A)) { + return typeName; + } + return truncateTypeName(typeName, maxLength) + (hasGenericTemplates == null ? "" + : formatGenericTemplates(hasChangeStatus, hasGenericTemplates.getGenericTemplates(), maxLength)); + } + + /** + * Formats a Java type in FQN form plus generic types. + * + * @param type The fully qualified name to format. + * @param genericTypes The possibly empty list of generic types. + * @param shorten Whether to truncate the type to 32 characters or not. + * @return The formatted type. + */ + public static String formatTypeName(String type, List genericTypes, boolean shorten) { + return formatTypeName(type, genericTypes, shorten ? 32 : -1); + } + + /** + * Formats a Java type in FQN form plus generic templates. + * + * @param typeName The fully qualified type name to format. + * @param hasChangeStatus The element that has a change status. + * @param hasGenericTemplates The element that has generic templates. + * @param shorten Whether to truncate the type to 32 characters or not. + * @return The formatted type. + */ + public static String formatTypeName(String typeName, JApiHasChangeStatus hasChangeStatus, JApiHasGenericTemplates hasGenericTemplates, boolean shorten) { + return formatTypeName(typeName, hasChangeStatus, hasGenericTemplates, shorten ? 32 : -1); + } + + /** + * Formats a parameter type plus generic types. + * + * @param method The method this parameter belongs to. + * @param parameter The parameter whose type will be formatted. + * @param varargs The varargs modifier of the method. + * @param genericTypes The possibly empty list of generic types. + * @param shorten Whether to truncate the type to 32 characters or not. + * @return The formatted type. + */ + public static String formatParameterTypeName(JApiBehavior method, JApiParameter parameter, Optional varargs, List genericTypes, boolean shorten) { + final String type = parameter.getType(); + final List params = method.getParameters(); + if (type.endsWith(STR_ARRAY) && parameter == params.get(params.size() - 1) && varargs.or(NON_VARARGS) == VARARGS) { + return formatTypeName(type.substring(0, type.length() - 2) + STR_VARARGS, genericTypes, shorten); + } + return formatTypeName(type, genericTypes, shorten); + } + + private static String formatGenericTypes(List genericTypes, int maxLength) { + if (genericTypes == null || genericTypes.isEmpty()) { + return ""; + } + return "<" + genericTypes.stream().map(x -> formatGenericType(x, maxLength)).collect(joining(", ")) + ">"; + } + + private static String formatGenericTemplates(JApiHasChangeStatus hasChangeStatus, List genericTemplates, int maxLength) { + if (genericTemplates == null || genericTemplates.isEmpty()) { + return ""; + } + return "<" + genericTemplates.stream().map(x -> formatGenericTemplate(hasChangeStatus, x, maxLength)).collect(joining(", ")) + ">"; + } + + private static String formatGenericType(JApiGenericType genericType, int maxLength) { + switch (genericType.getGenericWildCard()) { + case NONE: + return formatTypeName(genericType.getType(), genericType.getGenericTypes(), maxLength); + default: + case UNBOUNDED: + return "?"; + case EXTENDS: + return "? extends " + formatTypeName(genericType.getType(), genericType.getGenericTypes(), maxLength); + case SUPER: + return "? super " + formatTypeName(genericType.getType(), genericType.getGenericTypes(), maxLength); + } + } + + private static String formatGenericTemplate(JApiHasChangeStatus hasChangeStatus, JApiGenericTemplate genericTemplate, int maxLength) { + final String name = genericTemplate.getName(); + String type = null; + List genericTypes = null; + if (maxLength <= 0) { + switch (hasChangeStatus.getChangeStatus()) { + default: + case MODIFIED: + case NEW: + if (genericTemplate.getNewTypeOptional().isPresent()) { + type = genericTemplate.getNewType(); + genericTypes = genericTemplate.getNewGenericTypes(); + break; + } + case UNCHANGED: + case REMOVED: + if (genericTemplate.getOldTypeOptional().isPresent()) { + type = genericTemplate.getOldType(); + genericTypes = genericTemplate.getOldGenericTypes(); + } + } + } + if (type == null) { + return name; + } + return name + " extends " + formatTypeName(type, genericTypes, maxLength); + } + + private static String truncateTypeName(String typeName, int maxLength) { + if (maxLength < 3) { + return typeName; + } + // Enforcing max length implies sticking to simple name only + final int dollar = typeName.lastIndexOf('$'); + final int dot = (typeName.endsWith(STR_VARARGS) ? typeName.substring(0, typeName.length() - 3) : typeName).lastIndexOf('.'); + final int pos = Integer.max(dollar, dot); + final String name = pos > 0 ? typeName.substring(pos + 1) : typeName; + final int length = name.length(); + if (length > maxLength) { + // Cut in half and replace surplus characters with ellipsis + final int half = maxLength / 2; + return name.substring(0, maxLength - half - 1) + '\u2026' + name.substring(length - half); + } + return name; + } +} From 68b5870684e502cf4948f7f85be2ce58648b0b67 Mon Sep 17 00:00:00 2001 From: Guillermo Calvo Date: Sun, 28 Jul 2024 14:24:52 +0200 Subject: [PATCH 02/15] Add new CLI option `--markdown` to generate Markdown reports --- japicmp/src/main/java/japicmp/cli/CliParser.java | 6 ++++++ japicmp/src/main/java/japicmp/cli/JApiCli.java | 7 +++++++ japicmp/src/main/java/japicmp/config/Options.java | 9 +++++++++ 3 files changed, 22 insertions(+) diff --git a/japicmp/src/main/java/japicmp/cli/CliParser.java b/japicmp/src/main/java/japicmp/cli/CliParser.java index b0c05216b..7afcfde0e 100644 --- a/japicmp/src/main/java/japicmp/cli/CliParser.java +++ b/japicmp/src/main/java/japicmp/cli/CliParser.java @@ -64,6 +64,8 @@ public Options parse(String[] args) throws IllegalArgumentException { options.setHtmlOutputFile(Optional.fromNullable(pathToHtmlOutputFile)); } else if ("-s".equals(arg) || "--semantic-versioning".equals(arg)) { options.setSemanticVersioning(true); + } else if ("--markdown".equals(arg)) { + options.setMarkdown(true); } else if ("--include-synthetic".equals(arg)) { options.setIncludeSynthetic(true); } else if (IGNORE_MISSING_CLASSES.equals(arg)) { @@ -128,6 +130,7 @@ public static void printHelp() { " [--old-classpath ]\n" + " [--report-only-filename] [--report-only-summary]\n" + " [(-s | --semantic-versioning)]\n" + + " [--markdown]\n" + " [(-x | --xml-file )]\n" + " [--error-on-binary-incompatibility]\n" + " [--error-on-source-incompatibility]\n" + @@ -215,6 +218,9 @@ public static void printHelp() { " -s, --semantic-versioning\n" + " Tells you which part of the version to increment.\n" + "\n" + + " --markdown\n" + + " Generates output in Markdown format.\n" + + "\n" + " -x , --xml-file \n" + " Provides the path to the xml output file.\n" + "\n" + diff --git a/japicmp/src/main/java/japicmp/cli/JApiCli.java b/japicmp/src/main/java/japicmp/cli/JApiCli.java index 9ebf17816..f2ecd96e7 100644 --- a/japicmp/src/main/java/japicmp/cli/JApiCli.java +++ b/japicmp/src/main/java/japicmp/cli/JApiCli.java @@ -9,6 +9,7 @@ import japicmp.output.html.HtmlOutputGenerator; import japicmp.output.html.HtmlOutputGeneratorOptions; import japicmp.output.incompatible.IncompatibleErrorOutput; +import japicmp.output.markdown.MarkdownOutputGenerator; import japicmp.output.semver.SemverOut; import japicmp.output.stdout.StdoutOutputGenerator; import japicmp.output.xml.XmlOutput; @@ -46,6 +47,12 @@ private void generateOutput(Options options, List jApiClasses, JarArc System.out.println(output); return; } + if (options.isMarkdown()) { + MarkdownOutputGenerator markdownOutputGenerator = new MarkdownOutputGenerator(options, jApiClasses); + String output = markdownOutputGenerator.generate(); + System.out.println(output); + return; + } SemverOut semverOut = new SemverOut(options, jApiClasses); if (options.getXmlOutputFile().isPresent()) { XmlOutputGeneratorOptions xmlOutputGeneratorOptions = new XmlOutputGeneratorOptions(); diff --git a/japicmp/src/main/java/japicmp/config/Options.java b/japicmp/src/main/java/japicmp/config/Options.java index f0e132740..c9a696068 100644 --- a/japicmp/src/main/java/japicmp/config/Options.java +++ b/japicmp/src/main/java/japicmp/config/Options.java @@ -42,6 +42,7 @@ public class Options { private boolean reportOnlyFilename; private boolean reportOnlySummary; private boolean semanticVersioning; + private boolean markdown; private boolean errorOnBinaryIncompatibility; private boolean errorOnSourceIncompatibility; private boolean errorOnExclusionIncompatibility = true; @@ -398,6 +399,14 @@ public boolean isSemanticVersioning() { return semanticVersioning; } + public void setMarkdown(boolean markdown) { + this.markdown = markdown; + } + + public boolean isMarkdown() { + return markdown; + } + public boolean isErrorOnBinaryIncompatibility() { return errorOnBinaryIncompatibility; } From 6a80bdc9486f7a40145ae063432f41b73e4b7785 Mon Sep 17 00:00:00 2001 From: Guillermo Calvo Date: Sun, 28 Jul 2024 14:25:03 +0200 Subject: [PATCH 03/15] Update the Ant task to generate Markdown reports --- .../main/java/japicmp/ant/JApiCmpTask.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/japicmp-ant-task/src/main/java/japicmp/ant/JApiCmpTask.java b/japicmp-ant-task/src/main/java/japicmp/ant/JApiCmpTask.java index b44f40076..8672c99d3 100644 --- a/japicmp-ant-task/src/main/java/japicmp/ant/JApiCmpTask.java +++ b/japicmp-ant-task/src/main/java/japicmp/ant/JApiCmpTask.java @@ -9,6 +9,7 @@ import japicmp.output.html.HtmlOutputGenerator; import japicmp.output.html.HtmlOutputGeneratorOptions; import japicmp.output.incompatible.IncompatibleErrorOutput; +import japicmp.output.markdown.MarkdownOutputGenerator; import japicmp.output.semver.SemverOut; import japicmp.output.stdout.StdoutOutputGenerator; import japicmp.output.xml.XmlOutput; @@ -38,6 +39,7 @@ public class JApiCmpTask extends Task { private boolean includeSynthetic = false; private boolean noAnnotations = false; private boolean semanticVersioning = false; + private boolean markdown = false; private boolean reportOnlyFilename = false; private boolean reportOnlySummary = false; private boolean ignoreMissingClasses = false; @@ -46,6 +48,7 @@ public class JApiCmpTask extends Task { private final List ignoreMissingClassesByRegularExpressions = new ArrayList<>(); private String accessModifier = "protected"; private String semanticVersionProperty; + private String markdownProperty; private String oldJar; private String newJar; private Path oldClassPath; @@ -88,6 +91,15 @@ public void setSemVerProperty(String semverProperty) { semanticVersionProperty = semverProperty; } + public void setMarkdown(String markdown) { + this.markdown = Project.toBoolean(markdown); + } + + public void setMarkdownProperty(String mdProperty) { + markdown = Boolean.TRUE; + markdownProperty = mdProperty; + } + public void setReportOnlyFilename(String reportOnlyFilename) { this.reportOnlyFilename = Project.toBoolean(reportOnlyFilename); } @@ -284,6 +296,14 @@ private void generateOutput(Options options, List jApiClasses, JarArc } log(semver); return; + } else if (markdown) { + MarkdownOutputGenerator markdownOutputGenerator = new MarkdownOutputGenerator(options, jApiClasses); + String md = markdownOutputGenerator.generate(); + if (markdownProperty != null) { + getProject().setProperty(markdownProperty, md); + } + log(md); + return; } if (!options.getXmlOutputFile().isPresent() && !options.getHtmlOutputFile().isPresent()) { From d4bb5a4dc9c2ada908e5d9c767bb396182fae188 Mon Sep 17 00:00:00 2001 From: Guillermo Calvo Date: Sun, 28 Jul 2024 14:25:11 +0200 Subject: [PATCH 04/15] Update the Maven plugin to generate Markdown reports --- .../main/java/japicmp/maven/JApiCmpMojo.java | 27 +++++++++++++++++++ .../main/java/japicmp/maven/Parameter.java | 20 ++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/japicmp-maven-plugin/src/main/java/japicmp/maven/JApiCmpMojo.java b/japicmp-maven-plugin/src/main/java/japicmp/maven/JApiCmpMojo.java index 6b892fc43..1396962f8 100644 --- a/japicmp-maven-plugin/src/main/java/japicmp/maven/JApiCmpMojo.java +++ b/japicmp-maven-plugin/src/main/java/japicmp/maven/JApiCmpMojo.java @@ -15,6 +15,8 @@ import japicmp.output.html.HtmlOutputGenerator; import japicmp.output.html.HtmlOutputGeneratorOptions; import japicmp.output.incompatible.IncompatibleErrorOutput; +import japicmp.output.markdown.MarkdownOutputGenerator; +import japicmp.output.markdown.config.MarkdownOptions; import japicmp.output.semver.SemverOut; import japicmp.output.stdout.StdoutOutputGenerator; import japicmp.output.xml.XmlOutput; @@ -77,6 +79,8 @@ public class JApiCmpMojo extends AbstractMojo { private boolean skip; @org.apache.maven.plugins.annotations.Parameter(property = "japicmp.skip", defaultValue = "false") private boolean skipExec; + @org.apache.maven.plugins.annotations.Parameter(property = "japicmp.skipMarkdownReport", required = false) + private boolean skipMarkdownReport; @org.apache.maven.plugins.annotations.Parameter(property = "japicmp.skipXmlReport", required = false) private boolean skipXmlReport; @org.apache.maven.plugins.annotations.Parameter(property = "japicmp.skipHtmlReport", required = false) @@ -148,6 +152,9 @@ Optional executeWithParameters(PluginParameters pluginParameters, Ma SemverOut semverOut = new SemverOut(options, jApiClasses); String semanticVersioningInformation = semverOut.generate(); generateDiffOutput(mavenParameters, pluginParameters, options, jApiClasses, jApiCmpBuildDir, semanticVersioningInformation); + if (!skipMarkdownReport(pluginParameters)) { + generateMarkdownOutput(mavenParameters, pluginParameters, options, jApiClasses, jApiCmpBuildDir); + } if (!skipXmlReport(pluginParameters)) { XmlOutput xmlOutput = generateXmlOutput(jApiClasses, jApiCmpBuildDir, options, mavenParameters, pluginParameters, semanticVersioningInformation); if (pluginParameters.isWriteToFiles()) { @@ -576,6 +583,18 @@ private void generateDiffOutput(MavenParameters mavenParameters, PluginParameter } } + private void generateMarkdownOutput(MavenParameters mavenParameters, PluginParameters pluginParameters, Options options, + List jApiClasses, File jApiCmpBuildDir) throws IOException, MojoFailureException { + MarkdownOptions mdOptions = MarkdownOptions.newDefault(options); + if (pluginParameters.getParameterParam() != null && pluginParameters.getParameterParam().getMarkdownTitle() != null) { + mdOptions.title.report = pluginParameters.getParameterParam().getMarkdownTitle(); + } + MarkdownOutputGenerator mdOut = new MarkdownOutputGenerator(mdOptions, jApiClasses); + String markdown = mdOut.generate(); + File output = new File(jApiCmpBuildDir.getCanonicalPath() + File.separator + createFilename(mavenParameters) + ".md"); + writeToFile(markdown, output); + } + private XmlOutput generateXmlOutput(List jApiClasses, File jApiCmpBuildDir, Options options, MavenParameters mavenParameters, PluginParameters pluginParameters, String semanticVersioningInformation) throws IOException { String filename = createFilename(mavenParameters); @@ -621,6 +640,14 @@ private boolean skipXmlReport(PluginParameters pluginParameters) { return skipReport || this.skipXmlReport; } + private boolean skipMarkdownReport(PluginParameters pluginParameters) { + boolean skipReport = false; + if (pluginParameters.getParameterParam() != null) { + skipReport = pluginParameters.getParameterParam().getSkipMarkdownReport(); + } + return skipReport || this.skipMarkdownReport; + } + private String createFilename(MavenParameters mavenParameters) { String filename = "japicmp"; String executionId = mavenParameters.getMojoExecution().getExecutionId(); diff --git a/japicmp-maven-plugin/src/main/java/japicmp/maven/Parameter.java b/japicmp-maven-plugin/src/main/java/japicmp/maven/Parameter.java index 8aa3f0f19..51bb6b1ec 100644 --- a/japicmp-maven-plugin/src/main/java/japicmp/maven/Parameter.java +++ b/japicmp-maven-plugin/src/main/java/japicmp/maven/Parameter.java @@ -23,6 +23,8 @@ public class Parameter { @org.apache.maven.plugins.annotations.Parameter(required = false) private String htmlTitle; @org.apache.maven.plugins.annotations.Parameter(required = false) + private String markdownTitle; + @org.apache.maven.plugins.annotations.Parameter(required = false) private boolean noAnnotations; @org.apache.maven.plugins.annotations.Parameter(required = false) private String ignoreNonResolvableArtifacts; @@ -35,6 +37,8 @@ public class Parameter { @org.apache.maven.plugins.annotations.Parameter(required = false) private boolean skipXmlReport; @org.apache.maven.plugins.annotations.Parameter(required = false) + private boolean skipMarkdownReport; + @org.apache.maven.plugins.annotations.Parameter(required = false) private boolean skipDiffReport; @org.apache.maven.plugins.annotations.Parameter(required = false) private boolean ignoreMissingOldVersion; @@ -221,6 +225,14 @@ public void setHtmlTitle(String htmlTitle) { this.htmlTitle = htmlTitle; } + public String getMarkdownTitle() { + return markdownTitle; + } + + public void setMarkdownTitle(String markdownTitle) { + this.markdownTitle = markdownTitle; + } + public String getIgnoreNonResolvableArtifacts() { return ignoreNonResolvableArtifacts; } @@ -277,6 +289,14 @@ public void setSkipXmlReport(boolean skipXmlReport) { this.skipXmlReport = skipXmlReport; } + public boolean getSkipMarkdownReport() { + return skipMarkdownReport; + } + + public void setSkipMarkdownReport(boolean skipMarkdownReport) { + this.skipMarkdownReport = skipMarkdownReport; + } + public boolean isSkipDiffReport() { return skipDiffReport; } From 188b0ad0b3b605cd27f8085c2d4dccbedc5c0154 Mon Sep 17 00:00:00 2001 From: Guillermo Calvo Date: Sun, 28 Jul 2024 14:25:21 +0200 Subject: [PATCH 05/15] Add tests for the new Markdown output generator --- .../markdown/MarkdownOutputGeneratorTest.java | 296 ++++++++++++++++++ 1 file changed, 296 insertions(+) create mode 100644 japicmp/src/test/java/japicmp/output/markdown/MarkdownOutputGeneratorTest.java diff --git a/japicmp/src/test/java/japicmp/output/markdown/MarkdownOutputGeneratorTest.java b/japicmp/src/test/java/japicmp/output/markdown/MarkdownOutputGeneratorTest.java new file mode 100644 index 000000000..07e2af4e8 --- /dev/null +++ b/japicmp/src/test/java/japicmp/output/markdown/MarkdownOutputGeneratorTest.java @@ -0,0 +1,296 @@ +package japicmp.output.markdown; + +import static japicmp.model.AccessModifier.PRIVATE; +import static japicmp.model.JApiCompatibilityChangeType.FIELD_GENERICS_CHANGED; +import static japicmp.model.JApiCompatibilityChangeType.METHOD_PARAMETER_GENERICS_CHANGED; +import static japicmp.model.JApiCompatibilityChangeType.METHOD_REMOVED; +import static japicmp.model.JApiCompatibilityChangeType.METHOD_RETURN_TYPE_GENERICS_CHANGED; +import static japicmp.model.JApiJavaObjectSerializationCompatibility.JApiJavaObjectSerializationChangeStatus.NOT_SERIALIZABLE; +import static java.lang.String.format; +import static java.util.Collections.emptyList; +import static java.util.Collections.singletonList; +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.not; +import static org.hamcrest.MatcherAssert.assertThat; + +import japicmp.cmp.ClassesHelper; +import japicmp.cmp.JApiCmpArchive; +import japicmp.cmp.JarArchiveComparatorOptions; +import japicmp.config.Options; +import japicmp.model.JApiClass; +import japicmp.output.markdown.config.MarkdownMessageOptions; +import japicmp.output.markdown.config.MarkdownOptions; +import japicmp.util.CtClassBuilder; +import japicmp.util.CtFieldBuilder; +import japicmp.util.CtInterfaceBuilder; +import japicmp.util.CtMethodBuilder; +import java.io.File; +import java.util.Arrays; +import java.util.List; +import javassist.ClassPool; +import javassist.CtClass; +import javassist.CtField; +import javassist.CtMethod; +import org.junit.Assert; +import org.junit.Test; + +public class MarkdownOutputGeneratorTest { + + static final String TEST_CLASS_FQN = "japicmp.Test"; + static final String TEST_INTERFACE_NAME = "MyInterface"; + static final String TEST_METHOD_NAME = "method"; + static final String TEST_METHOD_BODY = "return;"; + static final String TEST_FIELD_NAME = "list"; + static final String TEST_TYPE = "java.util.List"; + static final String OLD_VERSION = "1.2.3"; + static final String NEW_VERSION = "1.3.0"; + static final JApiCmpArchive OLD_ARCHIVE = new JApiCmpArchive(new File("my-old-archive.jar"), OLD_VERSION); + static final JApiCmpArchive NEW_ARCHIVE = new JApiCmpArchive(new File("my-new-archive.jar"), NEW_VERSION); + static final MarkdownMessageOptions MSG = MarkdownOptions.newDefault().message; + + @Test + public void testNoChanges() { + Options options = Options.newDefault(); + options.setOldArchives(singletonList(OLD_ARCHIVE)); + options.setNewArchives(singletonList(NEW_ARCHIVE)); + MarkdownOutputGenerator generator = new MarkdownOutputGenerator(options, emptyList()); + String generated = generator.generate(); + assertThat(generated, containsString(MSG.badgeNoChanges)); + assertThat(generated, containsString( + format(MSG.summaryNoChanges, format(MSG.oneNewVersion, NEW_VERSION), format(MSG.oneOldVersion, OLD_VERSION)))); + } + + @Test + public void testWarningWhenIgnoreMissingClasses() { + Options options = Options.newDefault(); + options.setOldArchives(Arrays.asList(OLD_ARCHIVE, OLD_ARCHIVE)); + options.setNewArchives(Arrays.asList(NEW_ARCHIVE, NEW_ARCHIVE)); + options.setIgnoreMissingClasses(true); + MarkdownOutputGenerator generator = new MarkdownOutputGenerator(options, emptyList()); + String generated = generator.generate(); + assertThat(generated, containsString(MSG.warningAllMissingClassesIgnored)); + assertThat(generated, containsString( + format(MSG.summaryNoChanges, MSG.manyNewArchives, MSG.manyOldArchives))); + } + + @Test + public void testNoClassFileFormatVersionIfInterfaceRemoved() throws Exception { + JarArchiveComparatorOptions jarArchiveComparatorOptions = new JarArchiveComparatorOptions(); + jarArchiveComparatorOptions.setAccessModifier(PRIVATE); + List jApiClasses = ClassesHelper.compareClasses(jarArchiveComparatorOptions, new ClassesHelper.ClassesGenerator() { + @Override + public List createOldClasses(ClassPool classPool) throws Exception { + CtClass myInterface = CtInterfaceBuilder.create() + .name(TEST_INTERFACE_NAME) + .addToClassPool(classPool); + return singletonList(myInterface); + } + + @Override + public List createNewClasses(ClassPool classPool) { + return emptyList(); + } + }); + MarkdownOptions mdOptions = MarkdownOptions.newDefault(); + mdOptions.setTargetOldVersion(OLD_VERSION); + mdOptions.setTargetNewVersion(NEW_VERSION); + mdOptions.options.setOldArchives(Arrays.asList(OLD_ARCHIVE, OLD_ARCHIVE)); + mdOptions.options.setNewArchives(Arrays.asList(NEW_ARCHIVE, NEW_ARCHIVE)); + MarkdownOutputGenerator generator = new MarkdownOutputGenerator(mdOptions, jApiClasses); + String generated = generator.generate(); + assertThat(generated, containsString( + format(MSG.summaryMajorChanges, format(MSG.oneNewVersion, NEW_VERSION), format(MSG.oneOldVersion, OLD_VERSION)))); + Assert.assertFalse(generated.contains("-1.-1")); + } + + @Test + public void testMethodWithGenericTypes() throws Exception { + JarArchiveComparatorOptions jarArchiveComparatorOptions = new JarArchiveComparatorOptions(); + jarArchiveComparatorOptions.setAccessModifier(PRIVATE); + List jApiClasses = ClassesHelper.compareClasses(jarArchiveComparatorOptions, new ClassesHelper.ClassesGenerator() { + @Override + public List createOldClasses(ClassPool classPool) throws Exception { + CtClass ctClass = CtClassBuilder.create() + .name(TEST_CLASS_FQN) + .addToClassPool(classPool); + CtMethod method = CtMethodBuilder.create() + .publicAccess() + .returnType(classPool.get(TEST_TYPE)) + .name(TEST_METHOD_NAME) + .parameter(classPool.get(TEST_TYPE)) + .body(TEST_METHOD_BODY) + .addToClass(ctClass); + method.setGenericSignature("(Ljava/util/List;)Ljava/util/List;"); + return singletonList(ctClass); + } + + @Override + public List createNewClasses(ClassPool classPool) throws Exception { + CtClass ctClass = CtClassBuilder.create() + .name(TEST_CLASS_FQN) + .addToClassPool(classPool); + CtMethod method = CtMethodBuilder.create() + .publicAccess() + .returnType(classPool.get(TEST_TYPE)) + .name(TEST_METHOD_NAME) + .parameter(classPool.get(TEST_TYPE)) + .body(TEST_METHOD_BODY) + .addToClass(ctClass); + method.setGenericSignature("(Ljava/util/List;)Ljava/util/List;"); + return singletonList(ctClass); + } + }); + Options options = Options.newDefault(); + MarkdownOutputGenerator generator = new MarkdownOutputGenerator(options, jApiClasses); + String generated = generator.generate(); + assertThat(generated, containsString(format("\n| %s | [%s] | ![%s] | ![%s] ![%s] |\n", + MSG.statusSourceIncompatible, + TEST_CLASS_FQN, + MSG.serializationCompatibility.get(NOT_SERIALIZABLE), + MSG.compatibilityChangeType.get(METHOD_RETURN_TYPE_GENERICS_CHANGED), + MSG.compatibilityChangeType.get(METHOD_PARAMETER_GENERICS_CHANGED)))); + assertThat(generated, containsString(MSG.expandResults)); + assertThat(generated, containsString(format(MSG.compatibilityBinary, MSG.checked))); + assertThat(generated, containsString(format(MSG.compatibilitySource, MSG.unchecked))); + assertThat(generated, containsString(format(MSG.compatibilitySerialization, MSG.checked))); + } + + @Test + public void testMethodWithGenericTypesReportOnlySummary() throws Exception { + JarArchiveComparatorOptions jarArchiveComparatorOptions = new JarArchiveComparatorOptions(); + jarArchiveComparatorOptions.setAccessModifier(PRIVATE); + List jApiClasses = ClassesHelper.compareClasses(jarArchiveComparatorOptions, new ClassesHelper.ClassesGenerator() { + @Override + public List createOldClasses(ClassPool classPool) throws Exception { + CtClass ctClass = CtClassBuilder.create() + .name(TEST_CLASS_FQN) + .addToClassPool(classPool); + CtMethod method = CtMethodBuilder.create() + .publicAccess() + .returnType(classPool.get(TEST_TYPE)) + .name(TEST_METHOD_NAME) + .parameter(classPool.get(TEST_TYPE)) + .body(TEST_METHOD_BODY) + .addToClass(ctClass); + method.setGenericSignature("(Ljava/util/List;)Ljava/util/List;"); + return singletonList(ctClass); + } + + @Override + public List createNewClasses(ClassPool classPool) throws Exception { + CtClass ctClass = CtClassBuilder.create() + .name(TEST_CLASS_FQN) + .addToClassPool(classPool); + CtMethod method = CtMethodBuilder.create() + .publicAccess() + .returnType(classPool.get(TEST_TYPE)) + .name(TEST_METHOD_NAME) + .parameter(classPool.get(TEST_TYPE)) + .body(TEST_METHOD_BODY) + .addToClass(ctClass); + method.setGenericSignature("(Ljava/util/List;)Ljava/util/List;"); + return singletonList(ctClass); + } + }); + Options options = Options.newDefault(); + options.setReportOnlySummary(true); + MarkdownOutputGenerator generator = new MarkdownOutputGenerator(options, jApiClasses); + String generated = generator.generate(); + assertThat(generated, containsString(format("\n| %s | %s | ![%s] | ![%s] ![%s] |\n", + MSG.statusSourceIncompatible, + TEST_CLASS_FQN, + MSG.serializationCompatibility.get(NOT_SERIALIZABLE), + MSG.compatibilityChangeType.get(METHOD_RETURN_TYPE_GENERICS_CHANGED), + MSG.compatibilityChangeType.get(METHOD_PARAMETER_GENERICS_CHANGED)))); + assertThat(generated, not(containsString(MSG.expandResults))); + assertThat(generated, not(containsString(format(MSG.compatibilityBinary, MSG.checked)))); + assertThat(generated, not(containsString(format(MSG.compatibilitySource, MSG.unchecked)))); + assertThat(generated, not(containsString(format(MSG.compatibilitySerialization, MSG.checked)))); + } + + @Test + public void testMethodWithGenericTypesRemoved() throws Exception { + JarArchiveComparatorOptions jarArchiveComparatorOptions = new JarArchiveComparatorOptions(); + jarArchiveComparatorOptions.setAccessModifier(PRIVATE); + List jApiClasses = ClassesHelper.compareClasses(jarArchiveComparatorOptions, new ClassesHelper.ClassesGenerator() { + @Override + public List createOldClasses(ClassPool classPool) throws Exception { + CtClass ctClass = CtClassBuilder.create() + .name(TEST_CLASS_FQN) + .addToClassPool(classPool); + CtMethod method = CtMethodBuilder.create() + .publicAccess() + .returnType(classPool.get(TEST_TYPE)) + .name(TEST_METHOD_NAME) + .parameter(classPool.get(TEST_TYPE)) + .body(TEST_METHOD_BODY) + .addToClass(ctClass); + method.setGenericSignature("(Ljava/util/List;)Ljava/util/List;"); + return singletonList(ctClass); + } + + @Override + public List createNewClasses(ClassPool classPool) { + CtClass ctClass = CtClassBuilder.create() + .name(TEST_CLASS_FQN) + .addToClassPool(classPool); + return singletonList(ctClass); + } + }); + Options options = Options.newDefault(); + MarkdownOutputGenerator generator = new MarkdownOutputGenerator(options, jApiClasses); + String generated = generator.generate(); + assertThat(generated, containsString(format("\n| %s | [%s] | ![%s] | ![%s] |\n", + MSG.statusModified, + TEST_CLASS_FQN, + MSG.serializationCompatibility.get(NOT_SERIALIZABLE), + MSG.compatibilityChangeType.get(METHOD_REMOVED)))); + assertThat(generated, containsString(format(MSG.compatibilityBinary, MSG.unchecked))); + assertThat(generated, containsString(format(MSG.compatibilitySource, MSG.unchecked))); + assertThat(generated, containsString(format(MSG.compatibilitySerialization, MSG.checked))); + } + + @Test + public void testFieldWithGenericTypes() throws Exception { + JarArchiveComparatorOptions jarArchiveComparatorOptions = new JarArchiveComparatorOptions(); + jarArchiveComparatorOptions.setAccessModifier(PRIVATE); + List jApiClasses = ClassesHelper.compareClasses(jarArchiveComparatorOptions, new ClassesHelper.ClassesGenerator() { + @Override + public List createOldClasses(ClassPool classPool) throws Exception { + CtClass ctClass = CtClassBuilder.create() + .name(TEST_CLASS_FQN) + .addToClassPool(classPool); + CtField ctField = CtFieldBuilder.create() + .type(classPool.get(TEST_TYPE)) + .name(TEST_FIELD_NAME) + .addToClass(ctClass); + ctField.setGenericSignature("Ljava/util/List;"); + return singletonList(ctClass); + } + + @Override + public List createNewClasses(ClassPool classPool) throws Exception { + CtClass ctClass = CtClassBuilder.create() + .name(TEST_CLASS_FQN) + .addToClassPool(classPool); + CtField ctField = CtFieldBuilder.create() + .type(classPool.get(TEST_TYPE)) + .name(TEST_FIELD_NAME) + .addToClass(ctClass); + ctField.setGenericSignature("Ljava/util/List;"); + return singletonList(ctClass); + } + }); + Options options = Options.newDefault(); + MarkdownOutputGenerator generator = new MarkdownOutputGenerator(options, jApiClasses); + String generated = generator.generate(); + assertThat(generated, containsString(format("\n| %s | [%s] | ![%s] | ![%s] |\n", + MSG.statusSourceIncompatible, + TEST_CLASS_FQN, + MSG.serializationCompatibility.get(NOT_SERIALIZABLE), + MSG.compatibilityChangeType.get(FIELD_GENERICS_CHANGED)))); + assertThat(generated, containsString(format(MSG.compatibilityBinary, MSG.checked))); + assertThat(generated, containsString(format(MSG.compatibilitySource, MSG.unchecked))); + assertThat(generated, containsString(format(MSG.compatibilitySerialization, MSG.checked))); + } +} From a653c596146090a4ce3bb13a950d388cedb577e3 Mon Sep 17 00:00:00 2001 From: Guillermo Calvo Date: Sun, 28 Jul 2024 14:25:29 +0200 Subject: [PATCH 06/15] Add tests for the Maven plugin --- .../japicmp-test-maven-plugin/pom.xml | 2 ++ .../test/ITClassFileFormatVersion.java | 18 +++++++++++ .../java/japicmp/test/ITMarkdownTitle.java | 30 +++++++++++++++++++ .../java/japicmp/test/ITModuleExcluded.java | 5 ++++ .../japicmp/test/ITMultipleExecutions.java | 2 ++ .../test/java/japicmp/test/ITNoReports.java | 5 ++++ .../src/test/java/japicmp/test/ITSkip.java | 5 ++++ 7 files changed, 67 insertions(+) create mode 100644 japicmp-testbase/japicmp-test-maven-plugin/src/test/java/japicmp/test/ITMarkdownTitle.java diff --git a/japicmp-testbase/japicmp-test-maven-plugin/pom.xml b/japicmp-testbase/japicmp-test-maven-plugin/pom.xml index 0df80b09c..16dc67134 100644 --- a/japicmp-testbase/japicmp-test-maven-plugin/pom.xml +++ b/japicmp-testbase/japicmp-test-maven-plugin/pom.xml @@ -108,6 +108,7 @@ true ${project.basedir}/src/main/resources/css/stylesheet.css Test-Title + Test-Markdown-Title @@ -190,6 +191,7 @@ true true true + true diff --git a/japicmp-testbase/japicmp-test-maven-plugin/src/test/java/japicmp/test/ITClassFileFormatVersion.java b/japicmp-testbase/japicmp-test-maven-plugin/src/test/java/japicmp/test/ITClassFileFormatVersion.java index 4da3a7335..4ff700387 100644 --- a/japicmp-testbase/japicmp-test-maven-plugin/src/test/java/japicmp/test/ITClassFileFormatVersion.java +++ b/japicmp-testbase/japicmp-test-maven-plugin/src/test/java/japicmp/test/ITClassFileFormatVersion.java @@ -38,6 +38,24 @@ public void testClassFileFormatVersionIsPresent() throws IOException { } } + @Test + public void testMarkdownReportDiffClassFileFormatVersionIsPresent() throws IOException { + Path path = Paths.get(System.getProperty("user.dir"), "target", "japicmp", "class-file-format-version.md"); + if (!Files.exists(path)) { + return; //in JDK 1.7 case + } + assertThat(Files.exists(path), is(true)); + List lines = Files.readAllLines(path, StandardCharsets.UTF_8); + boolean found = false; + for (String line : lines) { + if (line.contains("~~JDK 6~~ → **JDK 8**")) { + found = true; + break; + } + } + assertThat(found, is(true)); + } + @Test public void testStoutDiffClassFileFormatVersionIsPresent() throws IOException { Path path = Paths.get(System.getProperty("user.dir"), "target", "japicmp", "class-file-format-version.diff"); diff --git a/japicmp-testbase/japicmp-test-maven-plugin/src/test/java/japicmp/test/ITMarkdownTitle.java b/japicmp-testbase/japicmp-test-maven-plugin/src/test/java/japicmp/test/ITMarkdownTitle.java new file mode 100644 index 000000000..c3af25cef --- /dev/null +++ b/japicmp-testbase/japicmp-test-maven-plugin/src/test/java/japicmp/test/ITMarkdownTitle.java @@ -0,0 +1,30 @@ +package japicmp.test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.Is.is; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; +import org.junit.Test; + +public class ITMarkdownTitle { + + @Test + public void testMarkdownTitle() throws IOException { + Path markdownPath = Paths.get(System.getProperty("user.dir"), "target", "japicmp", "single-version.md"); + assertThat(Files.exists(markdownPath), is(true)); + List lines = Files.readAllLines(markdownPath, StandardCharsets.UTF_8); + boolean found = false; + for (String line : lines) { + if (line.equals("# Test-Markdown-Title")) { + found = true; + break; + } + } + assertThat(found, is(true)); + } +} diff --git a/japicmp-testbase/japicmp-test-maven-plugin/src/test/java/japicmp/test/ITModuleExcluded.java b/japicmp-testbase/japicmp-test-maven-plugin/src/test/java/japicmp/test/ITModuleExcluded.java index d565dc30a..194f340fb 100644 --- a/japicmp-testbase/japicmp-test-maven-plugin/src/test/java/japicmp/test/ITModuleExcluded.java +++ b/japicmp-testbase/japicmp-test-maven-plugin/src/test/java/japicmp/test/ITModuleExcluded.java @@ -21,6 +21,11 @@ public void testHtmlReportNotGenerated() throws IOException { assertThat(Files.exists(Paths.get(System.getProperty("user.dir"), "target", "japicmp", "ignore-module.xml")), is(false)); } + @Test + public void testMarkdownReportGenerated() throws IOException { + assertThat(Files.exists(Paths.get(System.getProperty("user.dir"), "target", "japicmp", "ignore-module.md")), is(false)); + } + @Test public void testDiffReportGenerated() throws IOException { assertThat(Files.exists(Paths.get(System.getProperty("user.dir"), "target", "japicmp", "ignore-module.diff")), is(false)); diff --git a/japicmp-testbase/japicmp-test-maven-plugin/src/test/java/japicmp/test/ITMultipleExecutions.java b/japicmp-testbase/japicmp-test-maven-plugin/src/test/java/japicmp/test/ITMultipleExecutions.java index a54441f6a..d829ff46b 100644 --- a/japicmp-testbase/japicmp-test-maven-plugin/src/test/java/japicmp/test/ITMultipleExecutions.java +++ b/japicmp-testbase/japicmp-test-maven-plugin/src/test/java/japicmp/test/ITMultipleExecutions.java @@ -14,9 +14,11 @@ public class ITMultipleExecutions { public void testThatXmlAndHtmlFilesAreWritten() { assertThat(Files.exists(Paths.get(System.getProperty("user.dir"), "target", "japicmp", "multiple-versions.html")), is(true)); assertThat(Files.exists(Paths.get(System.getProperty("user.dir"), "target", "japicmp", "multiple-versions.xml")), is(true)); + assertThat(Files.exists(Paths.get(System.getProperty("user.dir"), "target", "japicmp", "multiple-versions.md")), is(true)); assertThat(Files.exists(Paths.get(System.getProperty("user.dir"), "target", "japicmp", "multiple-versions.diff")), is(true)); assertThat(Files.exists(Paths.get(System.getProperty("user.dir"), "target", "japicmp", "single-version.html")), is(true)); assertThat(Files.exists(Paths.get(System.getProperty("user.dir"), "target", "japicmp", "single-version.xml")), is(true)); + assertThat(Files.exists(Paths.get(System.getProperty("user.dir"), "target", "japicmp", "single-version.md")), is(true)); assertThat(Files.exists(Paths.get(System.getProperty("user.dir"), "target", "japicmp", "single-version.diff")), is(true)); } } diff --git a/japicmp-testbase/japicmp-test-maven-plugin/src/test/java/japicmp/test/ITNoReports.java b/japicmp-testbase/japicmp-test-maven-plugin/src/test/java/japicmp/test/ITNoReports.java index 6cc8ebc8b..5504fecc6 100644 --- a/japicmp-testbase/japicmp-test-maven-plugin/src/test/java/japicmp/test/ITNoReports.java +++ b/japicmp-testbase/japicmp-test-maven-plugin/src/test/java/japicmp/test/ITNoReports.java @@ -21,6 +21,11 @@ public void testHtmlReportNotGenerated() throws IOException { assertThat(Files.exists(Paths.get(System.getProperty("user.dir"), "target", "japicmp", "no-reports.xml")), is(false)); } + @Test + public void testMarkdownReportNotGenerated() throws IOException { + assertThat(Files.exists(Paths.get(System.getProperty("user.dir"), "target", "japicmp", "no-reports.md")), is(false)); + } + @Test public void testDiffReportGenerated() throws IOException { assertThat(Files.exists(Paths.get(System.getProperty("user.dir"), "target", "japicmp", "no-reports.diff")), is(true)); diff --git a/japicmp-testbase/japicmp-test-maven-plugin/src/test/java/japicmp/test/ITSkip.java b/japicmp-testbase/japicmp-test-maven-plugin/src/test/java/japicmp/test/ITSkip.java index bb44c3a09..007337f0b 100644 --- a/japicmp-testbase/japicmp-test-maven-plugin/src/test/java/japicmp/test/ITSkip.java +++ b/japicmp-testbase/japicmp-test-maven-plugin/src/test/java/japicmp/test/ITSkip.java @@ -21,6 +21,11 @@ public void testHtmlReportNotGenerated() throws IOException { assertThat(Files.exists(Paths.get(System.getProperty("user.dir"), "target", "japicmp", "skip.xml")), is(false)); } + @Test + public void testMarkdownReportGenerated() throws IOException { + assertThat(Files.exists(Paths.get(System.getProperty("user.dir"), "target", "japicmp", "skip.md")), is(false)); + } + @Test public void testDiffReportGenerated() throws IOException { assertThat(Files.exists(Paths.get(System.getProperty("user.dir"), "target", "japicmp", "skip.diff")), is(false)); From 6feb875d89d0204330171e5c9b31b387c097fc23 Mon Sep 17 00:00:00 2001 From: Guillermo Calvo Date: Sun, 28 Jul 2024 14:25:41 +0200 Subject: [PATCH 07/15] Update documentation --- src/site/markdown/AntTask.md | 1 + src/site/markdown/CliTool.md | 4 ++++ src/site/markdown/MavenPlugin.md | 5 +++++ src/site/markdown/index.md | 1 + 4 files changed, 11 insertions(+) diff --git a/src/site/markdown/AntTask.md b/src/site/markdown/AntTask.md index 3e99b7bd1..02962e2d1 100644 --- a/src/site/markdown/AntTask.md +++ b/src/site/markdown/AntTask.md @@ -49,6 +49,7 @@ The following table gives an overview of all available parameters of the Ant tas | classpath | true | n.a. | Classpath for the dependencies used to compare old and new versions. | | classpathref | true | n.a. | Classpath reference for the dependencies used to compare old and new versions. | | semanticVersioning | true | false | Indicate which part of the version to increment according to semantic versioning rules. | +| markdown | true | false | Generates output in Markdown format. | | onlyBinaryIncompatible | true | false | If true, output only binary incompatible changes. | | onlyModified | true | false | If true, output only modified classes/methods, else print all classes and methods.| | includeSynthetic | true | false | If true, track changes for synthetic classes and class members.| diff --git a/src/site/markdown/CliTool.md b/src/site/markdown/CliTool.md index 411111b84..f1808ff5c 100644 --- a/src/site/markdown/CliTool.md +++ b/src/site/markdown/CliTool.md @@ -18,6 +18,7 @@ SYNOPSIS [--old-classpath ] [--report-only-filename] [--report-only-summary] [(-s | --semantic-versioning)] + [--markdown] [(-x | --xml-file )] [--error-on-binary-incompatibility] [--error-on-source-incompatibility] @@ -105,6 +106,9 @@ OPTIONS -s, --semantic-versioning Tells you which part of the version to increment. + --markdown + Generates output in Markdown format. + -x , --xml-file Provides the path to the xml output file. diff --git a/src/site/markdown/MavenPlugin.md b/src/site/markdown/MavenPlugin.md index 79e61b739..beb737626 100644 --- a/src/site/markdown/MavenPlugin.md +++ b/src/site/markdown/MavenPlugin.md @@ -97,6 +97,7 @@ The following properties can be set: | japicmp.skip | Skip the execution of this plugin. | | japicmp.skipXmlReport | Skip the generation of the XML report. | | japicmp.skipHtmlReport | Skip the generation of the HTML report. | +| japicmp.skipMarkdownReport | Skip the generation of the Markdown report. | | japicmp.breakBuildOnModifications | Break the build in case of any modifications. | | japicmp.breakBuildOnBinaryIncompatibleModifications | Break the build in case of any binary incompatible modifications. | | japicmp.breakBuildOnSourceIncompatibleModifications | Break the build in case of any source incompatible modifications. | @@ -172,6 +173,7 @@ An advanced configuration can utilize the following parameters: true path/to/stylesheet.css Title of report + Title of report false false false @@ -182,6 +184,7 @@ An advanced configuration can utilize the following parameters: false false false + false false .*incl.* @@ -241,6 +244,7 @@ the <dependency> element. Through the <parameter> element you can pr | excludeExclusively | true | false | Exclude only packages specified in the "excludes" parameter, include their sub-packages. | | htmlStylesheet | true | n.a. | Path to an individual CSS stylesheet for the HTML report. | | htmlTitle | true | n.a. | A title for the HTML report (optional). | +| markdownTitle | true | n.a. | A title for the Markdown report (optional). | | skipPomModules | true | true | Setting this parameter to false (default: true) will not skip execution in modules with packaging type pom. | | skip | true | false | Setting this parameter to true will skip execution of the plugin. | | ignoreNonResolvableArtifacts | true | false | Set this to true in order to ignore artifacts that cannot be resolved, i.e. the build does not break in case a dependency cannot be resolved to a file. | @@ -251,6 +255,7 @@ the <dependency> element. Through the <parameter> element you can pr | postAnalysisScript | true | n.a. | A [Groovy](https://www.groovy-lang.org/) script that gets invoked after analysis is completed and before the output is written. This way it can be used to filter the output or break the build on specific conditions. It can be an absolute path or a relative path of a file within the classpath.| | skipXmlReport | true | false | If set to true, no XML report will be generated. | | skipHtmlReport | true | false | If set to true, no HTML report will be generated. | +| skipMarkdownReport | true | false | If set to true, no Markdown report will be generated. | | skipDiffReport | true | false | If set to true, no diff report will be generated. | | oldVersionPattern | true | n.a. | If <oldVersion> is not used, the old version compared against must match this regular expression. | | includeModules | true | n.a. | List of regular expression that specify if an artifact should be excluded based on its artifact id. | diff --git a/src/site/markdown/index.md b/src/site/markdown/index.md index 9cc11a52b..9b646a168 100644 --- a/src/site/markdown/index.md +++ b/src/site/markdown/index.md @@ -115,6 +115,7 @@ Features * All changes between annotations are compared, hence japicmp can be used to track annotation-based APIs like JAXB, JPA, JAX-RS, etc. * A maven plugin is available that allows you to compare the current artifact version with some older version from the repository. * The option `--semantic-versioning` tells you which part of the version you have to increment in order to follow [semantic versioning](http://semver.org/). +* The option `--markdown` generates output in [Markdown](https://www.markdownguide.org/) format. * If a class is serializable, changes are evaluated regarding the [Java Object Serialization Specification](http://docs.oracle.com/javase/7/docs/platform/serialization/spec/serialTOC.html). * Per default synthetic classes and class members (e.g. [bridge methods](https://docs.oracle.com/javase/tutorial/java/generics/bridgeMethods.html)) are hidden. They can be listed by using the option `--include-synthetic`. * The maven plugin allows project-specific filtering and reports using a custom [Groovy](groovy-lang.org) script. From 809bc494f80e2f720e3bc8a76cc81b01ab7a4ed3 Mon Sep 17 00:00:00 2001 From: Guillermo Calvo Date: Tue, 30 Jul 2024 18:57:33 +0200 Subject: [PATCH 08/15] Display usage of option `--report-only-summary` --- .../java/japicmp/output/markdown/MarkdownOutputGenerator.java | 1 + .../japicmp/output/markdown/config/MarkdownMessageOptions.java | 1 + 2 files changed, 2 insertions(+) diff --git a/japicmp/src/main/java/japicmp/output/markdown/MarkdownOutputGenerator.java b/japicmp/src/main/java/japicmp/output/markdown/MarkdownOutputGenerator.java index 0608411d7..10eafa765 100644 --- a/japicmp/src/main/java/japicmp/output/markdown/MarkdownOutputGenerator.java +++ b/japicmp/src/main/java/japicmp/output/markdown/MarkdownOutputGenerator.java @@ -80,6 +80,7 @@ private String renderReportSummary(String summary, Options options) { private String renderReportOptions(Options options) { final List patterns = options.getIgnoreMissingClasses().getIgnoreMissingClassRegularExpression(); return new MarkdownList( + format(md.message.reportOnlySummary, md.message.yesNo(options.isReportOnlySummary())), format(md.message.reportOnlyChanges, md.message.yesNo(options.isOutputOnlyModifications())), format(md.message.reportOnlyBinaryIncompatibleChanges, md.message.yesNo(options.isOutputOnlyBinaryIncompatibleModifications())), format(md.message.accessModifierFilter, options.getAccessModifier()), diff --git a/japicmp/src/main/java/japicmp/output/markdown/config/MarkdownMessageOptions.java b/japicmp/src/main/java/japicmp/output/markdown/config/MarkdownMessageOptions.java index a8e1c8842..3acb77331 100644 --- a/japicmp/src/main/java/japicmp/output/markdown/config/MarkdownMessageOptions.java +++ b/japicmp/src/main/java/japicmp/output/markdown/config/MarkdownMessageOptions.java @@ -42,6 +42,7 @@ public class MarkdownMessageOptions { public String newClasspath = "**New classpath**:\n```\n%s\n```"; public String accessModifierFilter = "**Access modifier filter**: `%s`"; public String evaluateAnnotations = "**Evaluate annotations**: %s"; + public String reportOnlySummary = "**Report only summary**: %s"; public String reportOnlyChanges = "**Report only changes**: %s"; public String reportOnlyBinaryIncompatibleChanges = "**Report only binary-incompatible changes**: %s"; public String includeSpecificElements = "**Include specific elements**: %s"; From d7eac02e9d9c5981999859cf182180c91572be99 Mon Sep 17 00:00:00 2001 From: Guillermo Calvo Date: Sun, 4 Aug 2024 12:54:00 +0200 Subject: [PATCH 09/15] Update contributor list --- pom.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pom.xml b/pom.xml index db8b1dcc4..66b14df86 100644 --- a/pom.xml +++ b/pom.xml @@ -128,6 +128,11 @@ Stefano Cordio https://github.com/scordio + + Guillermo Calvo + https://github.com/guillermocalvo + guillermo@guillermo.dev + From 4307e005fe99f22d4d1b276387343c1b80f459d1 Mon Sep 17 00:00:00 2001 From: Guillermo Calvo Date: Sun, 4 Aug 2024 13:03:04 +0200 Subject: [PATCH 10/15] Update documentation --- README.md | 2 +- doc/japicmp_guava.md | 3177 ++++++++++++++++++++++++++++++++ doc/japicmp_guava_markdown.png | Bin 0 -> 219594 bytes src/site/markdown/Examples.md | 5 + src/site/markdown/index.md | 2 +- 5 files changed, 3184 insertions(+), 2 deletions(-) create mode 100644 doc/japicmp_guava.md create mode 100644 doc/japicmp_guava_markdown.png diff --git a/README.md b/README.md index 7a64aae8d..6a2094450 100644 --- a/README.md +++ b/README.md @@ -105,7 +105,7 @@ in less than one second and therewith can be easily integrated in each build. * Comparison of two jar archives without the need to add all of their dependencies to the classpath. * Differences are printed on the command line in a simple diff format. -* Differences can optionally be printed as XML or HTML file. +* Differences can optionally be printed as [Markdown](https://www.markdownguide.org/), XML or HTML file. * Per default private and package protected classes and class members are not compared. If necessary, the access modifier of the classes and class members to be compared can be set to public, protected, package or private. * Per default all classes are tracked. If necessary, certain packages, classes, methods or fields can be excluded or explicitly included. Inclusion and exclusion is also possible based on annotations. diff --git a/doc/japicmp_guava.md b/doc/japicmp_guava.md new file mode 100644 index 000000000..ec876f46d --- /dev/null +++ b/doc/japicmp_guava.md @@ -0,0 +1,3177 @@ + +# Compatibility Report + +![semver MAJOR](https://img.shields.io/badge/semver-MAJOR-red?logo=semver "semver MAJOR") + +## Summary + +> [!CAUTION] +> +> Incompatible changes found while checking backward compatibility of version `19.0` with the previous version `18.0`. + +
+Expand to see options used. + +- **Report only summary**: No +- **Report only changes**: Yes +- **Report only binary-incompatible changes**: No +- **Access modifier filter**: `PROTECTED` +- **Old archives**: + - ![guava 18.0](https://img.shields.io/badge/guava-18.0-blue "guava 18.0") +- **New archives**: + - ![guava 19.0](https://img.shields.io/badge/guava-19.0-blue "guava 19.0") +- **Evaluate annotations**: Yes +- **Include synthetic classes and class members**: No +- **Include specific elements**: No +- **Exclude specific elements**: No +- **Ignore all missing classes**: No +- **Ignore specific missing classes**: No +- **Treat changes as errors**: + - Any changes: No + - Binary incompatible changes: No + - Source incompatible changes: No + - Incompatible changes caused by excluded classes: Yes + - Semantically incompatible changes: No + - Semantically incompatible changes, including development versions: No +- **Classpath mode**: `ONE_COMMON_CLASSPATH` +- **Old classpath**: +``` + +``` +- **New classpath**: +``` + +``` + +
+ + +## Results + +| Status | Type | Serialization | Compatibility Changes | +|----------------------------|-----------------------------------------------------------|-------------------------------------|-----------------------| +| Unchanged | [com.google.common.base.Ascii] | ![Not serializable] | ![Annotation added] ![Annotation removed] | +| Unchanged | [com.google.common.base.CaseFormat] | ![Compatible] | ![Annotation added] | +| Modified | [com.google.common.base.CharMatcher] | ![Not serializable] | ![Method added to public class] | +| Unchanged | [com.google.common.base.Defaults] | ![Not serializable] | ![Annotation added] | +| Unchanged | [com.google.common.base.Enums] | ![Not serializable] | ![Annotation added] | +| Unchanged | [com.google.common.base.Equivalence] | ![Not serializable] | ![Annotation added] | +| Unchanged | [com.google.common.base.Functions] | ![Not serializable] | ![Annotation added] | +| Unchanged | [com.google.common.base.Joiner] | ![Not serializable] | ![Annotation added] | +| Unchanged | [com.google.common.base.Joiner$MapJoiner] | ![Not serializable] | ![Annotation added] | +| Unchanged | [com.google.common.base.MoreObjects] | ![Not serializable] | ![Annotation added] | +| Unchanged | [com.google.common.base.MoreObjects$ToStringHelper] | ![Not serializable] | ![Annotation added] | +| Unchanged | [com.google.common.base.Objects] | ![Not serializable] | ![Annotation added] | +| Unchanged | [com.google.common.base.Optional] | ![Compatible] | ![Annotation added] | +| Unchanged | [com.google.common.base.Predicates] | ![Not serializable] | ![Annotation added] | +| Unchanged | [com.google.common.base.Splitter] | ![Not serializable] | ![Annotation added] | +| Unchanged | [com.google.common.base.Splitter$MapSplitter] | ![Not serializable] | ![Annotation added] | +| Unchanged | [com.google.common.base.StandardSystemProperty] | ![Compatible] | ![Annotation added] | +| Unchanged | [com.google.common.base.Stopwatch] | ![Not serializable] | ![Annotation added] | +| Unchanged | [com.google.common.base.Strings] | ![Not serializable] | ![Annotation added] | +| Unchanged | [com.google.common.base.Suppliers] | ![Not serializable] | ![Annotation added] | +| Modified | [com.google.common.base.Throwables] | ![Not serializable] | ![Annotation added] ![Method added to public class] | +| Unchanged | [com.google.common.base.Ticker] | ![Not serializable] | ![Annotation added] | +| Unchanged | [com.google.common.base.Utf8] | ![Not serializable] | ![Annotation added] | +| Modified | [com.google.common.base.VerifyException] | ![Default serialversionuid changed] | ![No changes] | +| Modified | [com.google.common.cache.CacheLoader$UnsupportedLoadingOperationException] | ![Default serialversionuid changed] | ![No changes] | +| Modified | [com.google.common.cache.RemovalNotification] | ![Not serializable] | ![Method added to public class] | +| Unchanged | [com.google.common.collect.BiMap] | ![Not serializable] | ![Annotation added] | +| Unchanged | [com.google.common.collect.Collections2] | ![Not serializable] | ![Annotation added] | +| Modified | [com.google.common.collect.ComparisonChain] | ![Not serializable] | ![Annotation added] ![Annotation deprecated added] ![Method added to public class] | +| Modified | [com.google.common.collect.FluentIterable] | ![Not serializable] | ![Annotation added] ![Method added to public class] | +| Modified | [com.google.common.collect.HashBiMap] | ![Superclass modified] | ![Superclass added] ![Method return type generics changed] | +| Modified | [com.google.common.collect.ImmutableBiMap] | ![Default serialversionuid changed] | ![Method added to public class] | +| Modified | [com.google.common.collect.ImmutableBiMap$Builder] | ![Not serializable] | ![Method added to public class] | +| Modified | [com.google.common.collect.ImmutableClassToInstanceMap] | ![Default serialversionuid changed] | ![Method added to public class] | +| Modified | [com.google.common.collect.ImmutableCollection] | ![Default serialversionuid changed] | ![Method now abstract] | +| Serialization-incompatible | [com.google.common.collect.ImmutableList] | ![Default serialversionuid changed] | ![No changes] | +| Modified | [com.google.common.collect.ImmutableListMultimap] | ![Compatible] | ![Method added to public class] | +| Modified | [com.google.common.collect.ImmutableListMultimap$Builder] | ![Not serializable] | ![Method added to public class] | +| Modified | [com.google.common.collect.ImmutableMap] | ![Default serialversionuid changed] | ![Method added to public class] | +| Modified | [com.google.common.collect.ImmutableMap$Builder] | ![Not serializable] | ![Method added to public class] | +| Modified | [com.google.common.collect.ImmutableMultimap] | ![Compatible] | ![Method added to public class] | +| Modified | [com.google.common.collect.ImmutableMultimap$Builder] | ![Not serializable] | ![Method added to public class] | +| Modified | [com.google.common.collect.ImmutableMultiset] | ![Default serialversionuid changed] | ![No changes] | +| Modified | [com.google.common.collect.ImmutableRangeMap] | ![Compatible] | ![Interface added] ![Method added to public class] | +| Modified | [com.google.common.collect.ImmutableRangeSet] | ![Default serialversionuid changed] | ![Method added to public class] | +| Modified | [com.google.common.collect.ImmutableSetMultimap] | ![Compatible] | ![Method added to public class] | +| Modified | [com.google.common.collect.ImmutableSetMultimap$Builder] | ![Not serializable] | ![Method added to public class] | +| Modified | [com.google.common.collect.ImmutableSortedMap] | ![Compatible] | ![Class now final] ![Method added to public class] | +| Modified | [com.google.common.collect.ImmutableSortedMap$Builder] | ![Not serializable] | ![Annotation deprecated added] ![Method added to public class] | +| Source-incompatible | [com.google.common.collect.ImmutableSortedMultiset] | ![Compatible] | ![Class generic template generics changed] | +| Serialization-incompatible | [com.google.common.collect.ImmutableSortedSet] | ![Default serialversionuid changed] | ![No changes] | +| Unchanged | [com.google.common.collect.Iterables] | ![Not serializable] | ![Annotation added] | +| Unchanged | [com.google.common.collect.Iterators] | ![Not serializable] | ![Annotation added] | +| Modified | [com.google.common.collect.Lists] | ![Not serializable] | ![Annotation added] | +| Unchanged | [com.google.common.collect.MapConstraint] | ![Not serializable] | ![Annotation deprecated added] | +| Unchanged | [com.google.common.collect.MapConstraints] | ![Not serializable] | ![Annotation deprecated added] | +| Modified | [com.google.common.collect.MapMaker] | ![Not serializable] | ![Method less accessible] | +| Modified | [com.google.common.collect.Maps] | ![Not serializable] | ![Annotation added] ![Method added to public class] | +| Unchanged | [com.google.common.collect.MultimapBuilder] | ![Not serializable] | ![Annotation added] | +| Unchanged | [com.google.common.collect.Multimaps] | ![Not serializable] | ![Annotation added] | +| Modified | [com.google.common.collect.Multisets] | ![Not serializable] | ![Annotation added] ![Method added to public class] | +| Modified | [com.google.common.collect.RangeMap] | ![Not serializable] | ![Method added to interface] | +| Modified | [com.google.common.collect.RangeSet] | ![Not serializable] | ![Method added to interface] | +| Unchanged | [com.google.common.collect.Sets] | ![Not serializable] | ![Annotation added] ![Annotation deprecated added] | +| Unchanged | [com.google.common.collect.Table] | ![Not serializable] | ![Annotation added] | +| Unchanged | [com.google.common.collect.Table$Cell] | ![Not serializable] | ![Annotation added] | +| Modified | [com.google.common.collect.TreeRangeMap] | ![Not serializable] | ![Method added to public class] | +| Modified | [com.google.common.collect.TreeRangeSet] | ![Not serializable] | ![Method added to public class] | +| Modified | [com.google.common.eventbus.AsyncEventBus] | ![Not serializable] | ![Method removed] | +| Modified | [com.google.common.eventbus.DeadEvent] | ![Not serializable] | ![Method added to public class] | +| Modified | [com.google.common.eventbus.EventBus] | ![Not serializable] | ![Method added to public class] | +| Modified | [com.google.common.hash.BloomFilter] | ![Default serialversionuid changed] | ![Annotation added] ![Method added to public class] | +| Unchanged | [com.google.common.hash.Funnels] | ![Not serializable] | ![Annotation added] | +| Unchanged | [com.google.common.hash.HashCode] | ![Not serializable] | ![Annotation added] | +| Modified | [com.google.common.hash.Hasher] | ![Not serializable] | ![Annotation added] ![Annotation deprecated added] ![Method added to interface] | +| Modified | [com.google.common.hash.Hashing] | ![Not serializable] | ![Annotation added] ![Method added to public class] | +| Unchanged | [com.google.common.hash.HashingInputStream] | ![Not serializable] | ![Annotation added] | +| Unchanged | [com.google.common.hash.HashingOutputStream] | ![Not serializable] | ![Annotation added] | +| Modified | [com.google.common.io.BaseEncoding] | ![Not serializable] | ![Method now abstract] | +| Modified | [com.google.common.io.ByteSource] | ![Not serializable] | ![Method added to public class] | +| Modified | [com.google.common.io.CharSource] | ![Not serializable] | ![Method added to public class] | +| Modified | [com.google.common.net.HttpHeaders] | ![Not serializable] | ![No changes] | +| Modified | [com.google.common.net.MediaType] | ![Not serializable] | ![No changes] | +| Unchanged | [com.google.common.primitives.Booleans] | ![Not serializable] | ![Annotation added] | +| Unchanged | [com.google.common.primitives.Bytes] | ![Not serializable] | ![Annotation added] | +| Unchanged | [com.google.common.primitives.Chars] | ![Not serializable] | ![Annotation added] | +| Unchanged | [com.google.common.primitives.Doubles] | ![Not serializable] | ![Annotation added] | +| Unchanged | [com.google.common.primitives.Floats] | ![Not serializable] | ![Annotation added] | +| Modified | [com.google.common.primitives.Ints] | ![Not serializable] | ![Annotation added] | +| Modified | [com.google.common.primitives.Longs] | ![Not serializable] | ![Annotation added] ![Method added to public class] | +| Unchanged | [com.google.common.primitives.Primitives] | ![Not serializable] | ![Annotation added] | +| Unchanged | [com.google.common.primitives.Shorts] | ![Not serializable] | ![Annotation added] | +| Unchanged | [com.google.common.primitives.SignedBytes] | ![Not serializable] | ![Annotation added] | +| Unchanged | [com.google.common.primitives.UnsignedBytes] | ![Not serializable] | ![Annotation added] | +| Unchanged | [com.google.common.primitives.UnsignedInteger] | ![Compatible] | ![Annotation added] ![Annotation removed] | +| Unchanged | [com.google.common.primitives.UnsignedInts] | ![Not serializable] | ![Annotation added] | +| Unchanged | [com.google.common.primitives.UnsignedLong] | ![Compatible] | ![Annotation added] | +| Unchanged | [com.google.common.primitives.UnsignedLongs] | ![Not serializable] | ![Annotation added] | +| Modified | [com.google.common.reflect.ClassPath$ResourceInfo] | ![Not serializable] | ![No changes] | +| Modified | [com.google.common.reflect.TypeToken] | ![Default serialversionuid changed] | ![Annotation deprecated added] ![Method added to public class] | +| Modified | [com.google.common.util.concurrent.AbstractFuture] | ![Not serializable] | ![No changes] | +| Modified | [com.google.common.util.concurrent.AbstractListeningExecutorService] | ![Not serializable] | ![Method return type changed] | +| Unchanged | [com.google.common.util.concurrent.FutureFallback] | ![Not serializable] | ![Annotation deprecated added] | +| Modified | [com.google.common.util.concurrent.Futures] | ![Not serializable] | ![Annotation added] ![Annotation deprecated added] ![Superclass added] ![Method added to public class] | +| Modified | [com.google.common.util.concurrent.SettableFuture] | ![Not serializable] | ![Superclass added] ![Method added to public class] | + +
+Expand for details. + +___ + + +### `com.google.common.base.Ascii` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|-----------|------------------|-------|---------|------------|-------|---------------------|-----------------------| +| Unchanged | `final` `public` | Class | `Ascii` | [`Object`] | JDK 6 | ![Not serializable] | ![Annotation added] | + + +#### Annotations + +| Status | Annotation | Compatibility Changes | +|--------|--------------------------|-----------------------| +| Added | **[`CheckReturnValue`]** | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|-----------|-------------------|----------|------------|-------------------------------------------------|--------------------------|--------|-----------------------| +| Unchanged | `static` `public` | | [`String`] | `truncate`([`CharSequence`], `int`, [`String`]) | ~~[`CheckReturnValue`]~~ | | ![Annotation removed] | + +___ + + +### `com.google.common.base.CaseFormat` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|-----------|---------------------|------|--------------|-------------|-------|---------------|-----------------------| +| Unchanged | `public` `abstract` | Enum | `CaseFormat` | [`Enum`] | JDK 6 | ![Compatible] | ![Annotation added] | + + +#### Annotations + +| Status | Annotation | Compatibility Changes | +|--------|--------------------------|-----------------------| +| Added | **[`CheckReturnValue`]** | ![No changes] | + +___ + + +### `com.google.common.base.CharMatcher` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------|---------------------|-------|---------------|------------|-------|---------------------|-----------------------| +| Modified | `public` `abstract` | Class | `CharMatcher` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|--------|---------------------------|----------|---------------------|----------------------------|-------------|--------|-----------------------| +| Added | **`static`** **`public`** | | **[`CharMatcher`]** | **`any`**() | | | ![Method added to public class] | +| Added | **`static`** **`public`** | | **[`CharMatcher`]** | **`ascii`**() | | | ![Method added to public class] | +| Added | **`static`** **`public`** | | **[`CharMatcher`]** | **`breakingWhitespace`**() | | | ![Method added to public class] | +| Added | **`static`** **`public`** | | **[`CharMatcher`]** | **`digit`**() | | | ![Method added to public class] | +| Added | **`static`** **`public`** | | **[`CharMatcher`]** | **`invisible`**() | | | ![Method added to public class] | +| Added | **`static`** **`public`** | | **[`CharMatcher`]** | **`javaDigit`**() | | | ![Method added to public class] | +| Added | **`static`** **`public`** | | **[`CharMatcher`]** | **`javaIsoControl`**() | | | ![Method added to public class] | +| Added | **`static`** **`public`** | | **[`CharMatcher`]** | **`javaLetter`**() | | | ![Method added to public class] | +| Added | **`static`** **`public`** | | **[`CharMatcher`]** | **`javaLetterOrDigit`**() | | | ![Method added to public class] | +| Added | **`static`** **`public`** | | **[`CharMatcher`]** | **`javaLowerCase`**() | | | ![Method added to public class] | +| Added | **`static`** **`public`** | | **[`CharMatcher`]** | **`javaUpperCase`**() | | | ![Method added to public class] | +| Added | **`static`** **`public`** | | **[`CharMatcher`]** | **`none`**() | | | ![Method added to public class] | +| Added | **`static`** **`public`** | | **[`CharMatcher`]** | **`singleWidth`**() | | | ![Method added to public class] | +| Added | **`static`** **`public`** | | **[`CharMatcher`]** | **`whitespace`**() | | | ![Method added to public class] | + +___ + + +### `com.google.common.base.Defaults` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|-----------|------------------|-------|------------|------------|-------|---------------------|-----------------------| +| Unchanged | `final` `public` | Class | `Defaults` | [`Object`] | JDK 6 | ![Not serializable] | ![Annotation added] | + + +#### Annotations + +| Status | Annotation | Compatibility Changes | +|--------|--------------------------|-----------------------| +| Added | **[`CheckReturnValue`]** | ![No changes] | + +___ + + +### `com.google.common.base.Enums` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|-----------|------------------|-------|---------|------------|-------|---------------------|-----------------------| +| Unchanged | `final` `public` | Class | `Enums` | [`Object`] | JDK 6 | ![Not serializable] | ![Annotation added] | + + +#### Annotations + +| Status | Annotation | Compatibility Changes | +|--------|--------------------------|-----------------------| +| Added | **[`CheckReturnValue`]** | ![No changes] | + +___ + + +### `com.google.common.base.Equivalence` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|-----------|---------------------|-------|---------------|------------|-------|---------------------|-----------------------| +| Unchanged | `public` `abstract` | Class | `Equivalence` | [`Object`] | JDK 6 | ![Not serializable] | ![Annotation added] | + + +#### Generics + +| Status | Name | Extends | Compatibility Changes | +|-----------|------|------------|-----------------------| +| Unchanged | `T` | [`Object`] | ![No changes] | + + +#### Annotations + +| Status | Annotation | Compatibility Changes | +|--------|--------------------------|-----------------------| +| Added | **[`CheckReturnValue`]** | ![No changes] | + +___ + + +### `com.google.common.base.Functions` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|-----------|------------------|-------|-------------|------------|-------|---------------------|-----------------------| +| Unchanged | `final` `public` | Class | `Functions` | [`Object`] | JDK 6 | ![Not serializable] | ![Annotation added] | + + +#### Annotations + +| Status | Annotation | Compatibility Changes | +|--------|--------------------------|-----------------------| +| Added | **[`CheckReturnValue`]** | ![No changes] | + +___ + + +### `com.google.common.base.Joiner` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|-----------|-----------|-------|----------|------------|-------|---------------------|-----------------------| +| Unchanged | `public` | Class | `Joiner` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|-----------|-------------------|----------|------------|-----------------------------------------------|--------------------------|--------|-----------------------| +| Unchanged | `final` `public` | | [`String`] | `join`([`Iterable`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `final` `public` | | [`String`] | `join`([`Iterator`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `final` `public` | | [`String`] | `join`([`Object[]`][1]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `final` `public` | | [`String`] | `join`([`Object`], [`Object`], [`Object...`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | | [`Joiner`] | `on`([`String`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | | [`Joiner`] | `on`(`char`) | **[`CheckReturnValue`]** | | ![Annotation added] | + +___ + + +### `com.google.common.base.Joiner$MapJoiner` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|-----------|---------------------------|-------|-------------|------------|-------|---------------------|-----------------------| +| Unchanged | `final` `static` `public` | Class | `MapJoiner` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|-----------|-----------|----------|------------|-----------------------------------------------------------------|--------------------------|--------|-----------------------| +| Unchanged | `public` | | [`String`] | `join`([`Map`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `public` | | [`String`] | `join`([`Iterable>`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `public` | | [`String`] | `join`([`Iterator>`]) | **[`CheckReturnValue`]** | | ![Annotation added] | + +___ + + +### `com.google.common.base.MoreObjects` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|-----------|------------------|-------|---------------|------------|-------|---------------------|-----------------------| +| Unchanged | `final` `public` | Class | `MoreObjects` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|-----------|-------------------|--------------------------|--------------------|--------------------------------|--------------------------|--------|-----------------------| +| Unchanged | `static` `public` | \<[`T extends Object`]\> | [`Object`] | `firstNonNull`(`T`, `T`) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | | [`ToStringHelper`] | `toStringHelper`([`Object`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | | [`ToStringHelper`] | `toStringHelper`([`Class`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | | [`ToStringHelper`] | `toStringHelper`([`String`]) | **[`CheckReturnValue`]** | | ![Annotation added] | + +___ + + +### `com.google.common.base.MoreObjects$ToStringHelper` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|-----------|---------------------------|-------|------------------|------------|-------|---------------------|-----------------------| +| Unchanged | `final` `static` `public` | Class | `ToStringHelper` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|-----------|-----------|----------|------------|--------------|--------------------------|--------|-----------------------| +| Unchanged | `public` | | [`String`] | `toString`() | **[`CheckReturnValue`]** | | ![Annotation added] | + +___ + + +### `com.google.common.base.Objects` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|-----------|------------------|-------|-----------|------------|-------|---------------------|-----------------------| +| Unchanged | `final` `public` | Class | `Objects` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|-----------|-------------------|--------------------------|-----------------------|--------------------------------|--------------------------|--------|-----------------------| +| Unchanged | `static` `public` | \<[`T extends Object`]\> | [`Object`] | `firstNonNull`(`T`, `T`) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | | `int` | `hashCode`([`Object...`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | | [`ToStringHelper`][2] | `toStringHelper`([`Object`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | | [`ToStringHelper`][2] | `toStringHelper`([`Class`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | | [`ToStringHelper`][2] | `toStringHelper`([`String`]) | **[`CheckReturnValue`]** | | ![Annotation added] | + +___ + + +### `com.google.common.base.Optional` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|-----------|---------------------|-------|------------|------------|-------|---------------|-----------------------| +| Unchanged | `public` `abstract` | Class | `Optional` | [`Object`] | JDK 6 | ![Compatible] | ![Annotation added] | + + +#### Generics + +| Status | Name | Extends | Compatibility Changes | +|-----------|------|------------|-----------------------| +| Unchanged | `T` | [`Object`] | ![No changes] | + + +#### Annotations + +| Status | Annotation | Compatibility Changes | +|--------|--------------------------|-----------------------| +| Added | **[`CheckReturnValue`]** | ![No changes] | + +___ + + +### `com.google.common.base.Predicates` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|-----------|------------------|-------|--------------|------------|-------|---------------------|-----------------------| +| Unchanged | `final` `public` | Class | `Predicates` | [`Object`] | JDK 6 | ![Not serializable] | ![Annotation added] | + + +#### Annotations + +| Status | Annotation | Compatibility Changes | +|--------|--------------------------|-----------------------| +| Added | **[`CheckReturnValue`]** | ![No changes] | + +___ + + +### `com.google.common.base.Splitter` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|-----------|------------------|-------|------------|------------|-------|---------------------|-----------------------| +| Unchanged | `final` `public` | Class | `Splitter` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|-----------|-------------------|----------|----------------------|---------------------------------|--------------------------|--------|-----------------------| +| Unchanged | `static` `public` | | [`Splitter`] | `fixedLength`(`int`) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | | [`Splitter`] | `on`(`char`) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | | [`Splitter`] | `on`([`CharMatcher`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | | [`Splitter`] | `on`([`String`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | | [`Splitter`] | `on`([`Pattern`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | | [`Splitter`] | `onPattern`([`String`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `public` | | [`Iterable`] | `split`([`CharSequence`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `public` | | [`List`] | `splitToList`([`CharSequence`]) | **[`CheckReturnValue`]** | | ![Annotation added] | + +___ + + +### `com.google.common.base.Splitter$MapSplitter` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|-----------|---------------------------|-------|---------------|------------|-------|---------------------|-----------------------| +| Unchanged | `final` `static` `public` | Class | `MapSplitter` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|-----------|-----------|----------|-------------------------|---------------------------|--------------------------|--------|-----------------------| +| Unchanged | `public` | | [`Map`] | `split`([`CharSequence`]) | **[`CheckReturnValue`]** | | ![Annotation added] | + +___ + + +### `com.google.common.base.StandardSystemProperty` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|-----------|------------------|------|--------------------------|-------------|-------|---------------|-----------------------| +| Unchanged | `final` `public` | Enum | `StandardSystemProperty` | [`Enum`] | JDK 6 | ![Compatible] | ![Annotation added] | + + +#### Annotations + +| Status | Annotation | Compatibility Changes | +|--------|--------------------------|-----------------------| +| Added | **[`CheckReturnValue`]** | ![No changes] | + +___ + + +### `com.google.common.base.Stopwatch` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|-----------|------------------|-------|-------------|------------|-------|---------------------|-----------------------| +| Unchanged | `final` `public` | Class | `Stopwatch` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|-----------|-------------------|----------|---------------|-------------------------------|--------------------------|--------|-----------------------| +| Unchanged | `static` `public` | | [`Stopwatch`] | `createStarted`() | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | | [`Stopwatch`] | `createStarted`([`Ticker`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | | [`Stopwatch`] | `createUnstarted`() | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | | [`Stopwatch`] | `createUnstarted`([`Ticker`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `public` | | `long` | `elapsed`([`TimeUnit`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `public` | | `boolean` | `isRunning`() | **[`CheckReturnValue`]** | | ![Annotation added] | + +___ + + +### `com.google.common.base.Strings` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|-----------|------------------|-------|-----------|------------|-------|---------------------|-----------------------| +| Unchanged | `final` `public` | Class | `Strings` | [`Object`] | JDK 6 | ![Not serializable] | ![Annotation added] | + + +#### Annotations + +| Status | Annotation | Compatibility Changes | +|--------|--------------------------|-----------------------| +| Added | **[`CheckReturnValue`]** | ![No changes] | + +___ + + +### `com.google.common.base.Suppliers` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|-----------|------------------|-------|-------------|------------|-------|---------------------|-----------------------| +| Unchanged | `final` `public` | Class | `Suppliers` | [`Object`] | JDK 6 | ![Not serializable] | ![Annotation added] | + + +#### Annotations + +| Status | Annotation | Compatibility Changes | +|--------|--------------------------|-----------------------| +| Added | **[`CheckReturnValue`]** | ![No changes] | + +___ + + +### `com.google.common.base.Throwables` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------|------------------|-------|--------------|------------|-------|---------------------|-----------------------| +| Modified | `final` `public` | Class | `Throwables` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|-----------|---------------------------|----------|---------------------------------|----------------------------------------|--------------------------|--------|-----------------------| +| Unchanged | `static` `public` | | [`List`] | `getCausalChain`([`Throwable`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | | [`Throwable`] | `getRootCause`([`Throwable`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | | [`String`] | `getStackTraceAsString`([`Throwable`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Added | **`static`** **`public`** | | **[`List`]** | **`lazyStackTrace`**([`Throwable`]) | **[`CheckReturnValue`]** | | ![Method added to public class] ![Annotation added] | +| Added | **`static`** **`public`** | | **`boolean`** | **`lazyStackTraceIsLazy`**() | **[`CheckReturnValue`]** | | ![Method added to public class] ![Annotation added] | + +___ + + +### `com.google.common.base.Ticker` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|-----------|---------------------|-------|----------|------------|-------|---------------------|-----------------------| +| Unchanged | `public` `abstract` | Class | `Ticker` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|-----------|-------------------|----------|------------|------------------|--------------------------|--------|-----------------------| +| Unchanged | `static` `public` | | [`Ticker`] | `systemTicker`() | **[`CheckReturnValue`]** | | ![Annotation added] | + +___ + + +### `com.google.common.base.Utf8` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|-----------|------------------|-------|--------|------------|-------|---------------------|-----------------------| +| Unchanged | `final` `public` | Class | `Utf8` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|-----------|-------------------|----------|-----------|----------------------------------------|--------------------------|--------|-----------------------| +| Unchanged | `static` `public` | | `int` | `encodedLength`([`CharSequence`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | | `boolean` | `isWellFormed`(`byte[]`) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | | `boolean` | `isWellFormed`(`byte[]`, `int`, `int`) | **[`CheckReturnValue`]** | | ![Annotation added] | + +___ + + +### `com.google.common.base.VerifyException` + +- [X] Binary-compatible +- [X] Source-compatible +- [ ] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------|-----------|-------|-------------------|----------------------|-------|-------------------------------------|-----------------------| +| Modified | `public` | Class | `VerifyException` | [`RuntimeException`] | JDK 6 | ![Default serialversionuid changed] | ![No changes] | + + +#### Constructors + +| Status | Modifiers | Generics | Constructor | Annotations | Throws | Compatibility Changes | +|--------|--------------|----------|--------------------------------------------------|-------------|--------|-----------------------| +| Added | **`public`** | | **`VerifyException`**([`Throwable`]) | | | ![No changes] | +| Added | **`public`** | | **`VerifyException`**([`String`], [`Throwable`]) | | | ![No changes] | + +___ + + +### `com.google.common.cache.CacheLoader$UnsupportedLoadingOperationException` + +- [X] Binary-compatible +- [X] Source-compatible +- [ ] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------|-------------------------------|-------|------------------------------------|-----------------------------------|-------|-------------------------------------|-----------------------| +| Modified | `final` `static` **`public`** | Class | `UnsupportedLoad…erationException` | [`UnsupportedOperationException`] | JDK 6 | ![Default serialversionuid changed] | ![No changes] | + +___ + + +### `com.google.common.cache.RemovalNotification` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------|------------------|-------|-----------------------|------------|-------|---------------------|-----------------------| +| Modified | `final` `public` | Class | `RemovalNotification` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] | + + +#### Generics + +| Status | Name | Extends | Compatibility Changes | +|-----------|------|------------|-----------------------| +| Unchanged | `K` | [`Object`] | ![No changes] | +| Unchanged | `V` | [`Object`] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|--------|---------------------------|--------------------------------------------------------|-----------------------------------|------------------------------------------|-------------|--------|-----------------------| +| Added | **`static`** **`public`** | \<**[`K extends Object`]**, **[`V extends Object`]**\> | **[`RemovalNotification`]** | **`create`**(`K`, `V`, [`RemovalCause`]) | | | ![Method added to public class] | + +___ + + +### `com.google.common.collect.BiMap` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|-----------|---------------------|-----------|---------|------------|-------|---------------------|-----------------------| +| Unchanged | `public` `abstract` | Interface | `BiMap` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] | + + +#### Generics + +| Status | Name | Extends | Compatibility Changes | +|-----------|------|------------|-----------------------| +| Unchanged | `K` | [`Object`] | ![No changes] | +| Unchanged | `V` | [`Object`] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|-----------|---------------------|----------|------------|----------------------|------------------|--------|-----------------------| +| Unchanged | `public` `abstract` | | [`Object`] | `forcePut`(`K`, `V`) | **[`Nullable`]** | | ![Annotation added] | +| Unchanged | `public` `abstract` | | [`Object`] | `put`(`K`, `V`) | **[`Nullable`]** | | ![Annotation added] | + +___ + + +### `com.google.common.collect.Collections2` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|-----------|------------------|-------|----------------|------------|-------|---------------------|-----------------------| +| Unchanged | `final` `public` | Class | `Collections2` | [`Object`] | JDK 6 | ![Not serializable] | ![Annotation added] | + + +#### Annotations + +| Status | Annotation | Compatibility Changes | +|--------|--------------------------|-----------------------| +| Added | **[`CheckReturnValue`]** | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|-----------|-------------------|--------------------------|-------------------|-------------------------------------------------------|--------------------------|--------|-----------------------| +| Unchanged | `static` `public` | \<[`E extends Object`]\> | [`Collection`] | `filter`([`Collection`], [`Predicate`]) | **[`CheckReturnValue`]** | | ![Annotation added] | + +___ + + +### `com.google.common.collect.ComparisonChain` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------|---------------------|-------|-------------------|------------|-------|---------------------|-----------------------| +| Modified | `public` `abstract` | Class | `ComparisonChain` | [`Object`] | JDK 6 | ![Not serializable] | ![Annotation added] | + + +#### Annotations + +| Status | Annotation | Compatibility Changes | +|--------|--------------------------|-----------------------| +| Added | **[`CheckReturnValue`]** | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|--------|--------------------------|----------|-------------------------|-----------------------------------------|--------------------|--------|-----------------------| +| Added | **`final`** **`public`** | | **[`ComparisonChain`]** | **`compare`**([`Boolean`], [`Boolean`]) | **[`Deprecated`]** | | ![Method added to public class] ![Annotation deprecated added] | + +___ + + +### `com.google.common.collect.FluentIterable` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------|---------------------|-------|------------------|------------|-------|---------------------|-----------------------| +| Modified | `public` `abstract` | Class | `FluentIterable` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] | + + +#### Generics + +| Status | Name | Extends | Compatibility Changes | +|-----------|------|------------|-----------------------| +| Unchanged | `E` | [`Object`] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|-----------|--------------------------|--------------------------|---------------------------------|-------------------------------------------|--------------------------|--------|-----------------------| +| Unchanged | `final` `public` | | `boolean` | `allMatch`([`Predicate`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `final` `public` | | `boolean` | `anyMatch`([`Predicate`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `final` `public` | | `boolean` | `contains`([`Object`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `final` `public` | | [`Optional`] | `first`() | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `final` `public` | | [`Optional`] | `firstMatch`([`Predicate`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | \<[`E extends Object`]\> | [`FluentIterable`] | `from`([`Iterable`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | \<[`E extends Object`]\> | [`FluentIterable`] | `from`([`FluentIterable`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `final` `public` | | [`Object`] | `get`(`int`) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `final` `public` | \<[`K extends Object`]\> | [`ImmutableListMultimap`] | `index`([`Function`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `final` `public` | | `boolean` | `isEmpty`() | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `final` `public` | | [`String`] | `join`([`Joiner`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `final` `public` | | [`Optional`] | `last`() | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | \<[`E extends Object`]\> | [`FluentIterable`] | `of`([`Object[]`][1]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `final` `public` | | `int` | `size`() | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `final` `public` | | [`Object[]`][1] | `toArray`([`Class`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `final` `public` | | [`ImmutableList`] | `toList`() | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `final` `public` | \<[`V extends Object`]\> | [`ImmutableMap`] | `toMap`([`Function`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Added | **`final`** **`public`** | | **[`ImmutableMultiset`]** | **`toMultiset`**() | **[`CheckReturnValue`]** | | ![Method added to public class] ![Annotation added] | +| Unchanged | `final` `public` | | [`ImmutableSet`] | `toSet`() | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `final` `public` | | [`ImmutableList`] | `toSortedList`([`Comparator`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `final` `public` | | [`ImmutableSortedSet`] | `toSortedSet`([`Comparator`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `public` | | [`String`] | `toString`() | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `final` `public` | \<[`T extends Object`]\> | [`FluentIterable`] | `transform`([`Function`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `public` | \<[`T extends Object`]\> | [`FluentIterable`] | `transformAndConcat`([`Function>`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `final` `public` | \<[`K extends Object`]\> | [`ImmutableMap`] | `uniqueIndex`([`Function`]) | **[`CheckReturnValue`]** | | ![Annotation added] | + +___ + + +### `com.google.common.collect.HashBiMap` + +- [X] Binary-compatible +- [ ] Source-compatible +- [ ] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------|------------------|-------|-------------|---------|-------|------------------------|-----------------------| +| Modified | `final` `public` | Class | `HashBiMap` | ~~[`AbstractMap`]~~ → **[`IteratorBasedAbstractMap`]** | JDK 6 | ![Superclass modified] | ![Superclass added] | + + +#### Generics + +| Status | Name | Extends | Compatibility Changes | +|-----------|------|------------|-----------------------| +| Unchanged | `K` | [`Object`] | ![No changes] | +| Unchanged | `V` | [`Object`] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|---------------------|---------------------------------------|----------|---------------------------------------------|--------------|-------------|--------|-----------------------| +| Source-incompatible | `public` **`bridge`** **`synthetic`** | | ~~[`Set>`]~~ → **[`Set`]** | `entrySet`() | | | ![Method return type generics changed] | + +___ + + +### `com.google.common.collect.ImmutableBiMap` + +- [X] Binary-compatible +- [X] Source-compatible +- [ ] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------|---------------------|-------|------------------|------------------------|-------|-------------------------------------|-----------------------| +| Modified | `public` `abstract` | Class | `ImmutableBiMap` | [`ImmutableMap`] | JDK 6 | ![Default serialversionuid changed] | ![No changes] | + + +#### Generics + +| Status | Name | Extends | Compatibility Changes | +|-----------|------|------------|-----------------------| +| Unchanged | `K` | [`Object`] | ![No changes] | +| Unchanged | `V` | [`Object`] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|--------|---------------------------|--------------------------------------------------------|------------------------------|--------|-------------|--------|-----------------------| +| Added | **`static`** **`public`** | \<**[`K extends Object`]**, **[`V extends Object`]**\> | **[`ImmutableBiMap`]** | **`copyOf`**([`Iterable>`]) | | | ![Method added to public class] | + +___ + + +### `com.google.common.collect.ImmutableBiMap$Builder` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------|---------------------------|-------|-----------|-------------------|-------|---------------------|-----------------------| +| Modified | `final` `static` `public` | Class | `Builder` | [`Builder`] | JDK 6 | ![Not serializable] | ![No changes] | + + +#### Generics + +| Status | Name | Extends | Compatibility Changes | +|-----------|------|------------|-----------------------| +| Unchanged | `K` | [`Object`] | ![No changes] | +| Unchanged | `V` | [`Object`] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|--------|--------------|----------|--------------------------|------------------------------------------------------|-------------|--------|-----------------------| +| Added | **`public`** | | **[`Builder`][3]** | **`orderEntriesByValue`**([`Comparator`]) | | | ![Method added to public class] | +| Added | **`public`** | | **[`Builder`][3]** | **`put`**([`Entry`]) | | | ![Method added to public class] | +| Added | **`public`** | | **[`Builder`][3]** | **`putAll`**([`Iterable>`]) | | | ![Method added to public class] | + +___ + + +### `com.google.common.collect.ImmutableClassToInstanceMap` + +- [X] Binary-compatible +- [X] Source-compatible +- [ ] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------|------------------|-------|-------------------------------|-------------------------|-------|-------------------------------------|-----------------------| +| Modified | `final` `public` | Class | `ImmutableClassToInstanceMap` | [`ForwardingMap`] | JDK 6 | ![Default serialversionuid changed] | ![No changes] | + + +#### Generics + +| Status | Name | Extends | Compatibility Changes | +|-----------|------|------------|-----------------------| +| Unchanged | `B` | [`Object`] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|--------|---------------------------|-------------------------------------------------|----------------------------------------|-----------------------------|-------------|--------|-----------------------| +| Added | **`static`** **`public`** | \<**[`B extends Object`]**\> | **[`ImmutableClassToInstanceMap`]** | **`of`**() | | | ![Method added to public class] | +| Added | **`static`** **`public`** | \<**[`B extends Object`]**, **`T extends B`**\> | **[`ImmutableClassToInstanceMap`]** | **`of`**([`Class`], `T`) | | | ![Method added to public class] | + +___ + + +### `com.google.common.collect.ImmutableCollection` + +- [ ] Binary-compatible +- [ ] Source-compatible +- [ ] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------|---------------------|-------|-----------------------|---------------------------|-------|-------------------------------------|-----------------------| +| Modified | `public` `abstract` | Class | `ImmutableCollection` | [`AbstractCollection`] | JDK 6 | ![Default serialversionuid changed] | ![No changes] | + + +#### Generics + +| Status | Name | Extends | Compatibility Changes | +|-----------|------|------------|-----------------------| +| Unchanged | `E` | [`Object`] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|----------|-------------------------|----------|-----------|------------------------|-------------|--------|-----------------------| +| Modified | `public` **`abstract`** | | `boolean` | `contains`([`Object`]) | | | ![Method now abstract] | + +___ + + +### `com.google.common.collect.ImmutableList` + +- [X] Binary-compatible +- [X] Source-compatible +- [ ] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------------------------|---------------------|-------|-----------------|----------------------------|-------|-------------------------------------|-----------------------| +| Serialization-incompatible | `public` `abstract` | Class | `ImmutableList` | [`ImmutableCollection`] | JDK 6 | ![Default serialversionuid changed] | ![No changes] | + + +#### Generics + +| Status | Name | Extends | Compatibility Changes | +|-----------|------|------------|-----------------------| +| Unchanged | `E` | [`Object`] | ![No changes] | + +___ + + +### `com.google.common.collect.ImmutableListMultimap` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------|-----------|-------|-------------------------|-----------------------------|-------|---------------|-----------------------| +| Modified | `public` | Class | `ImmutableListMultimap` | [`ImmutableMultimap`] | JDK 6 | ![Compatible] | ![No changes] | + + +#### Generics + +| Status | Name | Extends | Compatibility Changes | +|-----------|------|------------|-----------------------| +| Unchanged | `K` | [`Object`] | ![No changes] | +| Unchanged | `V` | [`Object`] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|--------|---------------------------|--------------------------------------------------------|-------------------------------------|--------|-------------|--------|-----------------------| +| Added | **`static`** **`public`** | \<**[`K extends Object`]**, **[`V extends Object`]**\> | **[`ImmutableListMultimap`]** | **`copyOf`**([`Iterable>`]) | | | ![Method added to public class] | + +___ + + +### `com.google.common.collect.ImmutableListMultimap$Builder` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------|---------------------------|-------|-----------|----------------------|-------|---------------------|-----------------------| +| Modified | `final` `static` `public` | Class | `Builder` | [`Builder`][4] | JDK 6 | ![Not serializable] | ![No changes] | + + +#### Generics + +| Status | Name | Extends | Compatibility Changes | +|-----------|------|------------|-----------------------| +| Unchanged | `K` | [`Object`] | ![No changes] | +| Unchanged | `V` | [`Object`] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|--------|--------------|----------|--------------------------|--------|-------------|--------|-----------------------| +| Added | **`public`** | | **[`Builder`][5]** | **`putAll`**([`Iterable>`]) | | | ![Method added to public class] | + +___ + + +### `com.google.common.collect.ImmutableMap` + +- [X] Binary-compatible +- [X] Source-compatible +- [ ] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------|---------------------|-------|----------------|------------|-------|-------------------------------------|-----------------------| +| Modified | `public` `abstract` | Class | `ImmutableMap` | [`Object`] | JDK 6 | ![Default serialversionuid changed] | ![No changes] | + + +#### Generics + +| Status | Name | Extends | Compatibility Changes | +|-----------|------|------------|-----------------------| +| Unchanged | `K` | [`Object`] | ![No changes] | +| Unchanged | `V` | [`Object`] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|--------|---------------------------|--------------------------------------------------------|-------------------------------|--------|-------------|--------|-----------------------| +| Added | **`static`** **`public`** | \<**[`K extends Object`]**, **[`V extends Object`]**\> | **[`ImmutableMap`][6]** | **`copyOf`**([`Iterable>`]) | | | ![Method added to public class] | + +___ + + +### `com.google.common.collect.ImmutableMap$Builder` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------|-------------------|-------|-----------|------------|-------|---------------------|-----------------------| +| Modified | `static` `public` | Class | `Builder` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] | + + +#### Generics + +| Status | Name | Extends | Compatibility Changes | +|-----------|------|------------|-----------------------| +| Unchanged | `K` | [`Object`] | ![No changes] | +| Unchanged | `V` | [`Object`] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|--------|--------------|----------|--------------------------|------------------------------------------------------|-------------|--------|-----------------------| +| Added | **`public`** | | **[`Builder`][7]** | **`orderEntriesByValue`**([`Comparator`]) | | | ![Method added to public class] | +| Added | **`public`** | | **[`Builder`][7]** | **`putAll`**([`Iterable>`]) | | | ![Method added to public class] | + +___ + + +### `com.google.common.collect.ImmutableMultimap` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------|---------------------|-------|---------------------|----------------------------|-------|---------------|-----------------------| +| Modified | `public` `abstract` | Class | `ImmutableMultimap` | [`AbstractMultimap`] | JDK 6 | ![Compatible] | ![No changes] | + + +#### Generics + +| Status | Name | Extends | Compatibility Changes | +|-----------|------|------------|-----------------------| +| Unchanged | `K` | [`Object`] | ![No changes] | +| Unchanged | `V` | [`Object`] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|--------|---------------------------|--------------------------------------------------------|------------------------------------|--------|-------------|--------|-----------------------| +| Added | **`static`** **`public`** | \<**[`K extends Object`]**, **[`V extends Object`]**\> | **[`ImmutableMultimap`][8]** | **`copyOf`**([`Iterable>`]) | | | ![Method added to public class] | + +___ + + +### `com.google.common.collect.ImmutableMultimap$Builder` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------|-------------------|-------|-----------|------------|-------|---------------------|-----------------------| +| Modified | `static` `public` | Class | `Builder` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] | + + +#### Generics + +| Status | Name | Extends | Compatibility Changes | +|-----------|------|------------|-----------------------| +| Unchanged | `K` | [`Object`] | ![No changes] | +| Unchanged | `V` | [`Object`] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|--------|--------------|----------|--------------------------|--------|-------------|--------|-----------------------| +| Added | **`public`** | | **[`Builder`][9]** | **`putAll`**([`Iterable>`]) | | | ![Method added to public class] | + +___ + + +### `com.google.common.collect.ImmutableMultiset` + +- [X] Binary-compatible +- [X] Source-compatible +- [ ] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------|---------------------|-------|---------------------|----------------------------|-------|-------------------------------------|-----------------------| +| Modified | `public` `abstract` | Class | `ImmutableMultiset` | [`ImmutableCollection`] | JDK 6 | ![Default serialversionuid changed] | ![No changes] | + + +#### Generics + +| Status | Name | Extends | Compatibility Changes | +|-----------|------|------------|-----------------------| +| Unchanged | `E` | [`Object`] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|---------|--------------|----------|---------------|--------------------------------------|-------------|--------|-----------------------| +| Removed | ~~`public`~~ | | ~~`boolean`~~ | ~~`containsAll`~~([`Collection`]) | | | ![No changes] | + +___ + + +### `com.google.common.collect.ImmutableRangeMap` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------|-----------|-------|---------------------|------------|-------|---------------|-----------------------| +| Modified | `public` | Class | `ImmutableRangeMap` | [`Object`] | JDK 6 | ![Compatible] | ![Interface added] | + + +#### Generics + +| Status | Name | Extends | Compatibility Changes | +|-----------|------|-------------------|-----------------------| +| Unchanged | `K` | [`Comparable`] | ![No changes] | +| Unchanged | `V` | [`Object`] | ![No changes] | + + +#### Implemented Interfaces + +| Status | Interface | Compatibility Changes | +|---------------------|----------------------|-----------------------| +| Source-incompatible | [`RangeMap`] | ![No changes] | +| Added | **[`Serializable`]** | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|--------|--------------|----------|-----------------------------------|---------------------------------|-------------|--------|-----------------------| +| Added | **`public`** | | **[`ImmutableMap, V>`]** | **`asDescendingMapOfRanges`**() | | | ![Method added to public class] | + +___ + + +### `com.google.common.collect.ImmutableRangeSet` + +- [X] Binary-compatible +- [X] Source-compatible +- [ ] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------|------------------|-------|---------------------|-------------------------|-------|-------------------------------------|-----------------------| +| Modified | `final` `public` | Class | `ImmutableRangeSet` | [`AbstractRangeSet`] | JDK 6 | ![Default serialversionuid changed] | ![No changes] | + + +#### Generics + +| Status | Name | Extends | Compatibility Changes | +|-----------|------|----------------|-----------------------| +| Unchanged | `C` | [`Comparable`] | ![No changes] | + + +#### Implemented Interfaces + +| Status | Interface | Compatibility Changes | +|---------------------|-----------------|-----------------------| +| Source-incompatible | [`RangeSet`] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|--------|--------------|----------|--------------------------------|---------------------------------|-------------|--------|-----------------------| +| Added | **`public`** | | **[`ImmutableSet>`]** | **`asDescendingSetOfRanges`**() | | | ![Method added to public class] | + +___ + + +### `com.google.common.collect.ImmutableSetMultimap` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------|-----------|-------|------------------------|-----------------------------|-------|---------------|-----------------------| +| Modified | `public` | Class | `ImmutableSetMultimap` | [`ImmutableMultimap`] | JDK 6 | ![Compatible] | ![No changes] | + + +#### Generics + +| Status | Name | Extends | Compatibility Changes | +|-----------|------|------------|-----------------------| +| Unchanged | `K` | [`Object`] | ![No changes] | +| Unchanged | `V` | [`Object`] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|--------|---------------------------|--------------------------------------------------------|------------------------------------|--------|-------------|--------|-----------------------| +| Added | **`static`** **`public`** | \<**[`K extends Object`]**, **[`V extends Object`]**\> | **[`ImmutableSetMultimap`]** | **`copyOf`**([`Iterable>`]) | | | ![Method added to public class] | + +___ + + +### `com.google.common.collect.ImmutableSetMultimap$Builder` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------|---------------------------|-------|-----------|----------------------|-------|---------------------|-----------------------| +| Modified | `final` `static` `public` | Class | `Builder` | [`Builder`][4] | JDK 6 | ![Not serializable] | ![No changes] | + + +#### Generics + +| Status | Name | Extends | Compatibility Changes | +|-----------|------|------------|-----------------------| +| Unchanged | `K` | [`Object`] | ![No changes] | +| Unchanged | `V` | [`Object`] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|--------|--------------|----------|---------------------------|--------|-------------|--------|-----------------------| +| Added | **`public`** | | **[`Builder`][10]** | **`putAll`**([`Iterable>`]) | | | ![Method added to public class] | + +___ + + +### `com.google.common.collect.ImmutableSortedMap` + +- [ ] Binary-compatible +- [ ] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------|-------------------------------------|-------|----------------------|--------------------------------------------|-------|---------------|-----------------------| +| Modified | **`final`** `public` ~~`abstract`~~ | Class | `ImmutableSortedMap` | [`ImmutableSortedMapFauxverideShim`] | JDK 6 | ![Compatible] | ![Class now final] | + + +#### Generics + +| Status | Name | Extends | Compatibility Changes | +|-----------|------|------------|-----------------------| +| Unchanged | `K` | [`Object`] | ![No changes] | +| Unchanged | `V` | [`Object`] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|----------|---------------------------|--------------------------------------------------------|----------------------------------|---------------------------------|-------------|--------|-----------------------| +| Removed | ~~`public`~~ | | ~~`boolean`~~ | ~~`containsValue`~~([`Object`]) | | | ![No changes] | +| Added | **`static`** **`public`** | \<**[`K extends Object`]**, **[`V extends Object`]**\> | **[`ImmutableSortedMap`]** | **`copyOf`**([`Iterable>`]) | | | ![Method added to public class] | +| Added | **`static`** **`public`** | \<**[`K extends Object`]**, **[`V extends Object`]**\> | **[`ImmutableSortedMap`]** | **`copyOf`**([`Iterable>`], [`Comparator`]) | | | ![Method added to public class] | +| Added | **`public`** | | **[`Object`]** | **`get`**([`Object`]) | | | ![Method added to public class] | +| Modified | `public` ~~`abstract`~~ | | [`ImmutableSortedMap`] | `headMap`(`K`, `boolean`) | | | ![No changes] | +| Modified | `public` ~~`abstract`~~ | | [`ImmutableSortedSet`] | `keySet`() | | | ![No changes] | +| Modified | `public` ~~`abstract`~~ | | [`ImmutableSortedMap`] | `tailMap`(`K`, `boolean`) | | | ![No changes] | +| Modified | `public` ~~`abstract`~~ | | [`ImmutableCollection`] | `values`() | | | ![No changes] | + +___ + + +### `com.google.common.collect.ImmutableSortedMap$Builder` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------|-------------------|-------|-----------|-------------------|-------|---------------------|-----------------------| +| Modified | `static` `public` | Class | `Builder` | [`Builder`] | JDK 6 | ![Not serializable] | ![No changes] | + + +#### Generics + +| Status | Name | Extends | Compatibility Changes | +|-----------|------|------------|-----------------------| +| Unchanged | `K` | [`Object`] | ![No changes] | +| Unchanged | `V` | [`Object`] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|--------|--------------|----------|---------------------------|------------------------------------------------------|--------------------|--------|-----------------------| +| Added | **`public`** | | **[`Builder`][11]** | **`orderEntriesByValue`**([`Comparator`]) | **[`Deprecated`]** | | ![Method added to public class] ![Annotation deprecated added] | +| Added | **`public`** | | **[`Builder`][11]** | **`putAll`**([`Iterable>`]) | | | ![Method added to public class] | + +___ + + +### `com.google.common.collect.ImmutableSortedMultiset` + +- [X] Binary-compatible +- [ ] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|---------------------|---------------------|-------|---------------------------|-----------------------------------------|-------|---------------|-----------------------| +| Source-incompatible | `public` `abstract` | Class | `ImmutableSortedMultiset` | [`ImmutableSorted…etFauxverideShim`] | JDK 6 | ![Compatible] | ![No changes] | + + +#### Generics + +| Status | Name | Extends | Compatibility Changes | +|-----------|------|------------|-----------------------| +| Unchanged | `E` | [`Object`] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|---------------------|-------------------|----------|----------------|------------------|-------------|--------|-----------------------| +| Source-incompatible | `static` `public` | \<~~[`E extends Comparable`]~~ → **[`E extends Comparable`]**\> | [`Builder`] | `naturalOrder`() | | | ![Class generic template generics changed] | +| Source-incompatible | `static` `public` | \<~~[`E extends Comparable`]~~ → **[`E extends Comparable`]**\> | [`Builder`] | `reverseOrder`() | | | ![Class generic template generics changed] | + +___ + + +### `com.google.common.collect.ImmutableSortedSet` + +- [X] Binary-compatible +- [X] Source-compatible +- [ ] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------------------------|---------------------|-------|----------------------|-----------------------------------------|-------|-------------------------------------|-----------------------| +| Serialization-incompatible | `public` `abstract` | Class | `ImmutableSortedSet` | [`ImmutableSortedSetFauxverideShim`] | JDK 6 | ![Default serialversionuid changed] | ![No changes] | + + +#### Generics + +| Status | Name | Extends | Compatibility Changes | +|-----------|------|------------|-----------------------| +| Unchanged | `E` | [`Object`] | ![No changes] | + +___ + + +### `com.google.common.collect.Iterables` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|-----------|------------------|-------|-------------|------------|-------|---------------------|-----------------------| +| Unchanged | `final` `public` | Class | `Iterables` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|-----------|-------------------|------------------------------------------------|-----------------|-----------------------------------------------------|--------------------------|--------|-----------------------| +| Unchanged | `static` `public` | | `boolean` | `elementsEqual`([`Iterable`], [`Iterable`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | \<[`T extends Object`]\> | [`Iterable`] | `filter`([`Iterable`], [`Predicate`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | \<[`T extends Object`]\> | [`Iterable`] | `filter`([`Iterable`], [`Class`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | \<[`F extends Object`], [`T extends Object`]\> | [`Iterable`] | `transform`([`Iterable`], [`Function`]) | **[`CheckReturnValue`]** | | ![Annotation added] | + +___ + + +### `com.google.common.collect.Iterators` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|-----------|------------------|-------|-------------|------------|-------|---------------------|-----------------------| +| Unchanged | `final` `public` | Class | `Iterators` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|-----------|-------------------|--------------------------|-----------------------------|-----------------------------------------------------|--------------------------|--------|-----------------------| +| Unchanged | `static` `public` | \<[`T extends Object`]\> | [`UnmodifiableIterator`] | `filter`([`Iterator`], [`Predicate`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | \<[`T extends Object`]\> | [`UnmodifiableIterator`] | `filter`([`Iterator`], [`Class`]) | **[`CheckReturnValue`]** | | ![Annotation added] | + +___ + + +### `com.google.common.collect.Lists` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------|------------------|-------|---------|------------|-------|---------------------|-----------------------| +| Modified | `final` `public` | Class | `Lists` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|-----------|-----------------------|------------------------------------------------|-------------------|----------------------------------------------------------------|--------------------------|--------|-----------------------| +| Modified | `static` **`public`** | \<[`B extends Object`]\> | [`List>`] | `cartesianProduct`([`List>`]) | | | ![No changes] | +| Modified | `static` **`public`** | \<[`B extends Object`]\> | [`List>`] | `cartesianProduct`([`List...`]) | | | ![No changes] | +| Unchanged | `static` `public` | \<[`T extends Object`]\> | [`List`] | `reverse`([`List`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | \<[`F extends Object`], [`T extends Object`]\> | [`List`] | `transform`([`List`], [`Function`]) | **[`CheckReturnValue`]** | | ![Annotation added] | + +___ + + +### `com.google.common.collect.MapConstraint` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|-----------|---------------------|-----------|-----------------|------------|-------|---------------------|-----------------------| +| Unchanged | `public` `abstract` | Interface | `MapConstraint` | [`Object`] | JDK 6 | ![Not serializable] | ![Annotation deprecated added] | + + +#### Generics + +| Status | Name | Extends | Compatibility Changes | +|-----------|------|------------|-----------------------| +| Unchanged | `K` | [`Object`] | ![No changes] | +| Unchanged | `V` | [`Object`] | ![No changes] | + + +#### Annotations + +| Status | Annotation | Compatibility Changes | +|--------|--------------------|-----------------------| +| Added | **[`Deprecated`]** | ![No changes] | + +___ + + +### `com.google.common.collect.MapConstraints` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|-----------|------------------|-------|------------------|------------|-------|---------------------|-----------------------| +| Unchanged | `final` `public` | Class | `MapConstraints` | [`Object`] | JDK 6 | ![Not serializable] | ![Annotation deprecated added] | + + +#### Annotations + +| Status | Annotation | Compatibility Changes | +|--------|--------------------|-----------------------| +| Added | **[`Deprecated`]** | ![No changes] | + +___ + + +### `com.google.common.collect.MapMaker` + +- [ ] Binary-compatible +- [ ] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------|------------------|-------|------------|-----------------------------|-------|---------------------|-----------------------| +| Modified | `final` `public` | Class | `MapMaker` | [`GenericMapMaker`] | JDK 6 | ![Not serializable] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|----------|--------------|----------|--------------|----------------|-------------|--------|-----------------------| +| Modified | ~~`public`~~ | | [`MapMaker`] | `softValues`() | | | ![Method less accessible] | + +___ + + +### `com.google.common.collect.Maps` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------|------------------|-------|--------|------------|-------|---------------------|-----------------------| +| Modified | `final` `public` | Class | `Maps` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|-----------|---------------------------|--------------------------------------------------------|-----------------------------|------------------------------------------------------------------|--------------------------|--------|-----------------------| +| Unchanged | `static` `public` | \<[`K extends Object`], [`V extends Object`]\> | [`Map`] | `filterEntries`([`Map`], [`Predicate>`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | \<[`K extends Object`], [`V extends Object`]\> | [`SortedMap`] | `filterEntries`([`SortedMap`], [`Predicate>`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | \<[`K extends Object`], [`V extends Object`]\> | [`NavigableMap`] | `filterEntries`([`NavigableMap`], [`Predicate>`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | \<[`K extends Object`], [`V extends Object`]\> | [`BiMap`] | `filterEntries`([`BiMap`], [`Predicate>`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | \<[`K extends Object`], [`V extends Object`]\> | [`Map`] | `filterKeys`([`Map`], [`Predicate`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | \<[`K extends Object`], [`V extends Object`]\> | [`SortedMap`] | `filterKeys`([`SortedMap`], [`Predicate`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | \<[`K extends Object`], [`V extends Object`]\> | [`NavigableMap`] | `filterKeys`([`NavigableMap`], [`Predicate`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | \<[`K extends Object`], [`V extends Object`]\> | [`BiMap`] | `filterKeys`([`BiMap`], [`Predicate`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | \<[`K extends Object`], [`V extends Object`]\> | [`Map`] | `filterValues`([`Map`], [`Predicate`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | \<[`K extends Object`], [`V extends Object`]\> | [`SortedMap`] | `filterValues`([`SortedMap`], [`Predicate`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | \<[`K extends Object`], [`V extends Object`]\> | [`NavigableMap`] | `filterValues`([`NavigableMap`], [`Predicate`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | \<[`K extends Object`], [`V extends Object`]\> | [`BiMap`] | `filterValues`([`BiMap`], [`Predicate`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Added | **`static`** **`public`** | \<**[`K extends Object`]**, **[`V extends Object`]**\> | **[`LinkedHashMap`]** | **`newLinkedHashMapWithExpectedSize`**(`int`) | | | ![Method added to public class] | + +___ + + +### `com.google.common.collect.MultimapBuilder` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|-----------|---------------------|-------|-------------------|------------|-------|---------------------|-----------------------| +| Unchanged | `public` `abstract` | Class | `MultimapBuilder` | [`Object`] | JDK 6 | ![Not serializable] | ![Annotation added] | + + +#### Generics + +| Status | Name | Extends | Compatibility Changes | +|-----------|------|------------|-----------------------| +| Unchanged | `K0` | [`Object`] | ![No changes] | +| Unchanged | `V0` | [`Object`] | ![No changes] | + + +#### Annotations + +| Status | Annotation | Compatibility Changes | +|--------|--------------------------|-----------------------| +| Added | **[`CheckReturnValue`]** | ![No changes] | + +___ + + +### `com.google.common.collect.Multimaps` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|-----------|------------------|-------|-------------|------------|-------|---------------------|-----------------------| +| Unchanged | `final` `public` | Class | `Multimaps` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|-----------|-------------------|------------------------------------------------|------------------------|-----------------------------------------------------------------|--------------------------|--------|-----------------------| +| Unchanged | `static` `public` | \<[`K extends Object`], [`V extends Object`]\> | [`Multimap`] | `filterEntries`([`Multimap`], [`Predicate>`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | \<[`K extends Object`], [`V extends Object`]\> | [`SetMultimap`] | `filterEntries`([`SetMultimap`], [`Predicate>`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | \<[`K extends Object`], [`V extends Object`]\> | [`Multimap`] | `filterKeys`([`Multimap`], [`Predicate`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | \<[`K extends Object`], [`V extends Object`]\> | [`SetMultimap`] | `filterKeys`([`SetMultimap`], [`Predicate`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | \<[`K extends Object`], [`V extends Object`]\> | [`ListMultimap`] | `filterKeys`([`ListMultimap`], [`Predicate`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | \<[`K extends Object`], [`V extends Object`]\> | [`Multimap`] | `filterValues`([`Multimap`], [`Predicate`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | \<[`K extends Object`], [`V extends Object`]\> | [`SetMultimap`] | `filterValues`([`SetMultimap`], [`Predicate`]) | **[`CheckReturnValue`]** | | ![Annotation added] | + +___ + + +### `com.google.common.collect.Multisets` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------|------------------|-------|-------------|------------|-------|---------------------|-----------------------| +| Modified | `final` `public` | Class | `Multisets` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|-----------|---------------------------|--------------------------|-----------------|-----------------------------------------------------------|--------------------------|--------|-----------------------| +| Unchanged | `static` `public` | \<[`E extends Object`]\> | [`Multiset`] | `filter`([`Multiset`], [`Predicate`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Added | **`static`** **`public`** | | **`boolean`** | **`removeOccurrences`**([`Multiset`], [`Multiset`]) | | | ![Method added to public class] | + +___ + + +### `com.google.common.collect.RangeMap` + +- [X] Binary-compatible +- [ ] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------|---------------------|-----------|------------|------------|-------|---------------------|-----------------------| +| Modified | `public` `abstract` | Interface | `RangeMap` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] | + + +#### Generics + +| Status | Name | Extends | Compatibility Changes | +|-----------|------|----------------|-----------------------| +| Unchanged | `K` | [`Comparable`] | ![No changes] | +| Unchanged | `V` | [`Object`] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|--------|-----------------------------|----------|--------------------------|---------------------------------|-------------|--------|-----------------------| +| Added | **`public`** **`abstract`** | | **[`Map, V>`]** | **`asDescendingMapOfRanges`**() | | | ![Method added to interface] | + +___ + + +### `com.google.common.collect.RangeSet` + +- [X] Binary-compatible +- [ ] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------|---------------------|-----------|------------|------------|-------|---------------------|-----------------------| +| Modified | `public` `abstract` | Interface | `RangeSet` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] | + + +#### Generics + +| Status | Name | Extends | Compatibility Changes | +|-----------|------|----------------|-----------------------| +| Unchanged | `C` | [`Comparable`] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|--------|-----------------------------|----------|-----------------------|---------------------------------|-------------|--------|-----------------------| +| Added | **`public`** **`abstract`** | | **[`Set>`]** | **`asDescendingSetOfRanges`**() | | | ![Method added to interface] | + +___ + + +### `com.google.common.collect.Sets` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|-----------|------------------|-------|--------|------------|-------|---------------------|-----------------------| +| Unchanged | `final` `public` | Class | `Sets` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|-----------|-------------------|--------------------------|---------------------|---------------------------------------------------------|--------------------------|--------|-----------------------| +| Unchanged | `static` `public` | \<[`E extends Object`]\> | [`Set`] | `filter`([`Set`], [`Predicate`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | \<[`E extends Object`]\> | [`SortedSet`] | `filter`([`SortedSet`], [`Predicate`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | \<[`E extends Object`]\> | [`NavigableSet`] | `filter`([`NavigableSet`], [`Predicate`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | \<[`E extends Object`]\> | [`Set`] | `newSetFromMap`([`Map`]) | **[`Deprecated`]** | | ![Annotation deprecated added] | + +___ + + +### `com.google.common.collect.Table` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|-----------|---------------------|-----------|---------|------------|-------|---------------------|-----------------------| +| Unchanged | `public` `abstract` | Interface | `Table` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] | + + +#### Generics + +| Status | Name | Extends | Compatibility Changes | +|-----------|------|------------|-----------------------| +| Unchanged | `C` | [`Object`] | ![No changes] | +| Unchanged | `R` | [`Object`] | ![No changes] | +| Unchanged | `V` | [`Object`] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|-----------|---------------------|----------|------------|----------------------------------|------------------|--------|-----------------------| +| Unchanged | `public` `abstract` | | [`Object`] | `put`(`R`, `C`, `V`) | **[`Nullable`]** | | ![Annotation added] | +| Unchanged | `public` `abstract` | | [`Object`] | `remove`([`Object`], [`Object`]) | **[`Nullable`]** | | ![Annotation added] | + +___ + + +### `com.google.common.collect.Table$Cell` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|-----------|------------------------------|-----------|--------|------------|-------|---------------------|-----------------------| +| Unchanged | `static` `public` `abstract` | Interface | `Cell` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] | + + +#### Generics + +| Status | Name | Extends | Compatibility Changes | +|-----------|------|------------|-----------------------| +| Unchanged | `C` | [`Object`] | ![No changes] | +| Unchanged | `R` | [`Object`] | ![No changes] | +| Unchanged | `V` | [`Object`] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|-----------|---------------------|----------|------------|------------------|------------------|--------|-----------------------| +| Unchanged | `public` `abstract` | | [`Object`] | `getColumnKey`() | **[`Nullable`]** | | ![Annotation added] | +| Unchanged | `public` `abstract` | | [`Object`] | `getRowKey`() | **[`Nullable`]** | | ![Annotation added] | +| Unchanged | `public` `abstract` | | [`Object`] | `getValue`() | **[`Nullable`]** | | ![Annotation added] | + +___ + + +### `com.google.common.collect.TreeRangeMap` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------|------------------|-------|----------------|------------|-------|---------------------|-----------------------| +| Modified | `final` `public` | Class | `TreeRangeMap` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] | + + +#### Generics + +| Status | Name | Extends | Compatibility Changes | +|-----------|------|----------------|-----------------------| +| Unchanged | `K` | [`Comparable`] | ![No changes] | +| Unchanged | `V` | [`Object`] | ![No changes] | + + +#### Implemented Interfaces + +| Status | Interface | Compatibility Changes | +|---------------------|--------------------|-----------------------| +| Source-incompatible | [`RangeMap`] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|--------|--------------|----------|--------------------------|---------------------------------|-------------|--------|-----------------------| +| Added | **`public`** | | **[`Map, V>`]** | **`asDescendingMapOfRanges`**() | | | ![Method added to public class] | + +___ + + +### `com.google.common.collect.TreeRangeSet` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------|-----------|-------|----------------|-------------------------|-------|---------------------|-----------------------| +| Modified | `public` | Class | `TreeRangeSet` | [`AbstractRangeSet`] | JDK 6 | ![Not serializable] | ![No changes] | + + +#### Generics + +| Status | Name | Extends | Compatibility Changes | +|-----------|------|-------------------|-----------------------| +| Unchanged | `C` | [`Comparable`] | ![No changes] | + + +#### Implemented Interfaces + +| Status | Interface | Compatibility Changes | +|---------------------|-----------------|-----------------------| +| Source-incompatible | [`RangeSet`] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|--------|--------------|----------|-----------------------|---------------------------------|-------------|--------|-----------------------| +| Added | **`public`** | | **[`Set>`]** | **`asDescendingSetOfRanges`**() | | | ![Method added to public class] | + +___ + + +### `com.google.common.eventbus.AsyncEventBus` + +- [ ] Binary-compatible +- [ ] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------|-----------|-------|-----------------|--------------|-------|---------------------|-----------------------| +| Modified | `public` | Class | `AsyncEventBus` | [`EventBus`] | JDK 6 | ![Not serializable] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|---------|-----------------|----------|------------|------------------------------|-------------|--------|-----------------------| +| Removed | ~~`protected`~~ | | ~~`void`~~ | ~~`dispatchQueuedEvents`~~() | | | ![Method removed] | + +___ + + +### `com.google.common.eventbus.DeadEvent` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------|-----------|-------|-------------|------------|-------|---------------------|-----------------------| +| Modified | `public` | Class | `DeadEvent` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|--------|--------------|----------|----------------|------------------|-------------|--------|-----------------------| +| Added | **`public`** | | **[`String`]** | **`toString`**() | | | ![Method added to public class] | + +___ + + +### `com.google.common.eventbus.EventBus` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------|-----------|-------|------------|------------|-------|---------------------|-----------------------| +| Modified | `public` | Class | `EventBus` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|--------|--------------------------|----------|----------------|--------------------|-------------|--------|-----------------------| +| Added | **`final`** **`public`** | | **[`String`]** | **`identifier`**() | | | ![Method added to public class] | +| Added | **`public`** | | **[`String`]** | **`toString`**() | | | ![Method added to public class] | + +___ + + +### `com.google.common.hash.BloomFilter` + +- [X] Binary-compatible +- [X] Source-compatible +- [ ] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------|------------------|-------|---------------|------------|-------|-------------------------------------|-----------------------| +| Modified | `final` `public` | Class | `BloomFilter` | [`Object`] | JDK 6 | ![Default serialversionuid changed] | ![No changes] | + + +#### Generics + +| Status | Name | Extends | Compatibility Changes | +|-----------|------|------------|-----------------------| +| Unchanged | `T` | [`Object`] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|-----------|---------------------------|------------------------------|------------------------|-------------------------------------------------------|--------------------------|-----------------|-----------------------| +| Unchanged | `public` | | `boolean` | `apply`(`T`) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `public` | | [`BloomFilter`] | `copy`() | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | \<[`T extends Object`]\> | [`BloomFilter`] | `create`([`Funnel`], `int`, `double`) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | \<[`T extends Object`]\> | [`BloomFilter`] | `create`([`Funnel`], `int`) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Added | **`static`** **`public`** | \<**[`T extends Object`]**\> | **[`BloomFilter`]** | **`create`**([`Funnel`], `long`, `double`) | **[`CheckReturnValue`]** | | ![Method added to public class] ![Annotation added] | +| Added | **`static`** **`public`** | \<**[`T extends Object`]**\> | **[`BloomFilter`]** | **`create`**([`Funnel`], `long`) | **[`CheckReturnValue`]** | | ![Method added to public class] ![Annotation added] | +| Unchanged | `public` | | `double` | `expectedFpp`() | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `public` | | `boolean` | `isCompatible`([`BloomFilter`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `public` | | `boolean` | `mightContain`(`T`) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | \<[`T extends Object`]\> | [`BloomFilter`] | `readFrom`([`InputStream`], [`Funnel`]) | **[`CheckReturnValue`]** | [`IOException`] | ![Annotation added] | + +___ + + +### `com.google.common.hash.Funnels` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|-----------|------------------|-------|-----------|------------|-------|---------------------|-----------------------| +| Unchanged | `final` `public` | Class | `Funnels` | [`Object`] | JDK 6 | ![Not serializable] | ![Annotation added] | + + +#### Annotations + +| Status | Annotation | Compatibility Changes | +|--------|--------------------------|-----------------------| +| Added | **[`CheckReturnValue`]** | ![No changes] | + +___ + + +### `com.google.common.hash.HashCode` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|-----------|---------------------|-------|------------|------------|-------|---------------------|-----------------------| +| Unchanged | `public` `abstract` | Class | `HashCode` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|-----------|---------------------|----------|--------------|--------------------------|--------------------------|--------|-----------------------| +| Unchanged | `public` `abstract` | | `byte[]` | `asBytes`() | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `public` `abstract` | | `int` | `asInt`() | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `public` `abstract` | | `long` | `asLong`() | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `public` `abstract` | | `int` | `bits`() | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | | [`HashCode`] | `fromBytes`(`byte[]`) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | | [`HashCode`] | `fromInt`(`int`) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | | [`HashCode`] | `fromLong`(`long`) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | | [`HashCode`] | `fromString`([`String`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `public` `abstract` | | `long` | `padToLong`() | **[`CheckReturnValue`]** | | ![Annotation added] | + +___ + + +### `com.google.common.hash.Hasher` + +- [X] Binary-compatible +- [ ] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------|---------------------|-----------|----------|------------|-------|---------------------|-----------------------| +| Modified | `public` `abstract` | Interface | `Hasher` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|-----------|-----------------------------|----------|--------------|------------------|--------------------------|--------|-----------------------| +| Unchanged | `public` `abstract` | | [`HashCode`] | `hash`() | **[`CheckReturnValue`]** | | ![Annotation added] | +| Added | **`public`** **`abstract`** | | **`int`** | **`hashCode`**() | **[`Deprecated`]** | | ![Method added to interface] ![Annotation deprecated added] | + +___ + + +### `com.google.common.hash.Hashing` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------|------------------|-------|-----------|------------|-------|---------------------|-----------------------| +| Modified | `final` `public` | Class | `Hashing` | [`Object`] | JDK 6 | ![Not serializable] | ![Annotation added] | + + +#### Annotations + +| Status | Annotation | Compatibility Changes | +|--------|--------------------------|-----------------------| +| Added | **[`CheckReturnValue`]** | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|--------|---------------------------|----------|----------------------|-------------------------------------------------|-------------|--------|-----------------------| +| Added | **`static`** **`public`** | | **[`HashFunction`]** | **`concatenating`**([`HashFunction`], [`HashFunction`], [`HashFunction...`]) | | | ![Method added to public class] | +| Added | **`static`** **`public`** | | **[`HashFunction`]** | **`concatenating`**([`Iterable`]) | | | ![Method added to public class] | +| Added | **`static`** **`public`** | | **[`HashFunction`]** | **`sha384`**() | | | ![Method added to public class] | + +___ + + +### `com.google.common.hash.HashingInputStream` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|-----------|------------------|-------|----------------------|-----------------------|-------|---------------------|-----------------------| +| Unchanged | `final` `public` | Class | `HashingInputStream` | [`FilterInputStream`] | JDK 6 | ![Not serializable] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|-----------|-----------|----------|--------------|-------------------|--------------------------|--------|-----------------------| +| Unchanged | `public` | | [`HashCode`] | `hash`() | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `public` | | `boolean` | `markSupported`() | **[`CheckReturnValue`]** | | ![Annotation added] | + +___ + + +### `com.google.common.hash.HashingOutputStream` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|-----------|------------------|-------|-----------------------|------------------------|-------|---------------------|-----------------------| +| Unchanged | `final` `public` | Class | `HashingOutputStream` | [`FilterOutputStream`] | JDK 6 | ![Not serializable] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|-----------|-----------|----------|--------------|----------|--------------------------|--------|-----------------------| +| Unchanged | `public` | | [`HashCode`] | `hash`() | **[`CheckReturnValue`]** | | ![Annotation added] | + +___ + + +### `com.google.common.io.BaseEncoding` + +- [ ] Binary-compatible +- [ ] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------|---------------------|-------|----------------|------------|-------|---------------------|-----------------------| +| Modified | `public` `abstract` | Class | `BaseEncoding` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|----------|-------------------------------------|----------|------------------|------------------------------|-------------|--------|-----------------------| +| Modified | ~~`final`~~ `public` **`abstract`** | | [`InputStream`] | `decodingStream`([`Reader`]) | | | ![Method now abstract] | +| Modified | ~~`final`~~ `public` **`abstract`** | | [`OutputStream`] | `encodingStream`([`Writer`]) | | | ![Method now abstract] | + +___ + + +### `com.google.common.io.ByteSource` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------|---------------------|-------|--------------|------------|-------|---------------------|-----------------------| +| Modified | `public` `abstract` | Class | `ByteSource` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|--------|--------------|----------|------------------------|---------------------|-------------|--------|-----------------------| +| Added | **`public`** | | **[`Optional`]** | **`sizeIfKnown`**() | | | ![Method added to public class] | + +___ + + +### `com.google.common.io.CharSource` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------|---------------------|-------|--------------|------------|-------|---------------------|-----------------------| +| Modified | `public` `abstract` | Class | `CharSource` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|--------|--------------|----------|------------------------|-----------------------|-------------|---------------------|-----------------------| +| Added | **`public`** | | **`long`** | **`length`**() | | **[`IOException`]** | ![Method added to public class] | +| Added | **`public`** | | **[`Optional`]** | **`lengthIfKnown`**() | | | ![Method added to public class] | + +___ + + +### `com.google.common.net.HttpHeaders` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------|------------------|-------|---------------|------------|-------|---------------------|-----------------------| +| Modified | `final` `public` | Class | `HttpHeaders` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] | + + +#### Fields + +| Status | Modifiers | Type | Name | Annotations | Compatibility Changes | +|--------|---------------------------------------|----------------|-------------|-------------|-----------------------| +| Added | **`public`** **`static`** **`final`** | **[`String`]** | `PING_FROM` | | ![No changes] | +| Added | **`public`** **`static`** **`final`** | **[`String`]** | `PING_TO` | | ![No changes] | + +___ + + +### `com.google.common.net.MediaType` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------|------------------|-------|-------------|------------|-------|---------------------|-----------------------| +| Modified | `final` `public` | Class | `MediaType` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] | + + +#### Fields + +| Status | Modifiers | Type | Name | Annotations | Compatibility Changes | +|--------|---------------------------------------|-------------------|-----------------------|-------------|-----------------------| +| Added | **`public`** **`static`** **`final`** | **[`MediaType`]** | `APPLE_PASSBOOK` | | ![No changes] | +| Added | **`public`** **`static`** **`final`** | **[`MediaType`]** | `DART_UTF_8` | | ![No changes] | +| Added | **`public`** **`static`** **`final`** | **[`MediaType`]** | `MANIFEST_JSON_UTF_8` | | ![No changes] | + +___ + + +### `com.google.common.primitives.Booleans` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|-----------|------------------|-------|------------|------------|-------|---------------------|-----------------------| +| Unchanged | `final` `public` | Class | `Booleans` | [`Object`] | JDK 6 | ![Not serializable] | ![Annotation added] | + + +#### Annotations + +| Status | Annotation | Compatibility Changes | +|--------|--------------------------|-----------------------| +| Added | **[`CheckReturnValue`]** | ![No changes] | + +___ + + +### `com.google.common.primitives.Bytes` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|-----------|------------------|-------|---------|------------|-------|---------------------|-----------------------| +| Unchanged | `final` `public` | Class | `Bytes` | [`Object`] | JDK 6 | ![Not serializable] | ![Annotation added] | + + +#### Annotations + +| Status | Annotation | Compatibility Changes | +|--------|--------------------------|-----------------------| +| Added | **[`CheckReturnValue`]** | ![No changes] | + +___ + + +### `com.google.common.primitives.Chars` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|-----------|------------------|-------|---------|------------|-------|---------------------|-----------------------| +| Unchanged | `final` `public` | Class | `Chars` | [`Object`] | JDK 6 | ![Not serializable] | ![Annotation added] | + + +#### Annotations + +| Status | Annotation | Compatibility Changes | +|--------|--------------------------|-----------------------| +| Added | **[`CheckReturnValue`]** | ![No changes] | + +___ + + +### `com.google.common.primitives.Doubles` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|-----------|------------------|-------|-----------|------------|-------|---------------------|-----------------------| +| Unchanged | `final` `public` | Class | `Doubles` | [`Object`] | JDK 6 | ![Not serializable] | ![Annotation added] | + + +#### Annotations + +| Status | Annotation | Compatibility Changes | +|--------|--------------------------|-----------------------| +| Added | **[`CheckReturnValue`]** | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|-----------|-------------------|----------|------------|------------------------|----------------------|--------|-----------------------| +| Unchanged | `static` `public` | | [`Double`] | `tryParse`([`String`]) | **[`CheckForNull`]** | | ![Annotation added] | + +___ + + +### `com.google.common.primitives.Floats` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|-----------|------------------|-------|----------|------------|-------|---------------------|-----------------------| +| Unchanged | `final` `public` | Class | `Floats` | [`Object`] | JDK 6 | ![Not serializable] | ![Annotation added] | + + +#### Annotations + +| Status | Annotation | Compatibility Changes | +|--------|--------------------------|-----------------------| +| Added | **[`CheckReturnValue`]** | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|-----------|-------------------|----------|-----------|------------------------|----------------------|--------|-----------------------| +| Unchanged | `static` `public` | | [`Float`] | `tryParse`([`String`]) | **[`CheckForNull`]** | | ![Annotation added] | + +___ + + +### `com.google.common.primitives.Ints` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------|------------------|-------|--------|------------|-------|---------------------|-----------------------| +| Modified | `final` `public` | Class | `Ints` | [`Object`] | JDK 6 | ![Not serializable] | ![Annotation added] | + + +#### Annotations + +| Status | Annotation | Compatibility Changes | +|--------|--------------------------|-----------------------| +| Added | **[`CheckReturnValue`]** | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|-----------|-----------------------|----------|-------------|-------------------------------|------------------|--------|-----------------------| +| Unchanged | `static` `public` | | [`Integer`] | `tryParse`([`String`]) | **[`Nullable`]** | | ![Annotation added] | +| Modified | `static` **`public`** | | [`Integer`] | `tryParse`([`String`], `int`) | **[`Nullable`]** | | ![Annotation added] | + +___ + + +### `com.google.common.primitives.Longs` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------|------------------|-------|---------|------------|-------|---------------------|-----------------------| +| Modified | `final` `public` | Class | `Longs` | [`Object`] | JDK 6 | ![Not serializable] | ![Annotation added] | + + +#### Annotations + +| Status | Annotation | Compatibility Changes | +|--------|--------------------------|-----------------------| +| Added | **[`CheckReturnValue`]** | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|-----------|---------------------------|----------|--------------|-----------------------------------|------------------------------------------|--------|-----------------------| +| Unchanged | `static` `public` | | [`Long`] | `tryParse`([`String`]) | **[`CheckForNull`]**
**[`Nullable`]** | | ![Annotation added] | +| Added | **`static`** **`public`** | | **[`Long`]** | **`tryParse`**([`String`], `int`) | **[`CheckForNull`]**
**[`Nullable`]** | | ![Method added to public class] ![Annotation added] | + +___ + + +### `com.google.common.primitives.Primitives` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|-----------|------------------|-------|--------------|------------|-------|---------------------|-----------------------| +| Unchanged | `final` `public` | Class | `Primitives` | [`Object`] | JDK 6 | ![Not serializable] | ![Annotation added] | + + +#### Annotations + +| Status | Annotation | Compatibility Changes | +|--------|--------------------------|-----------------------| +| Added | **[`CheckReturnValue`]** | ![No changes] | + +___ + + +### `com.google.common.primitives.Shorts` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|-----------|------------------|-------|----------|------------|-------|---------------------|-----------------------| +| Unchanged | `final` `public` | Class | `Shorts` | [`Object`] | JDK 6 | ![Not serializable] | ![Annotation added] | + + +#### Annotations + +| Status | Annotation | Compatibility Changes | +|--------|--------------------------|-----------------------| +| Added | **[`CheckReturnValue`]** | ![No changes] | + +___ + + +### `com.google.common.primitives.SignedBytes` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|-----------|------------------|-------|---------------|------------|-------|---------------------|-----------------------| +| Unchanged | `final` `public` | Class | `SignedBytes` | [`Object`] | JDK 6 | ![Not serializable] | ![Annotation added] | + + +#### Annotations + +| Status | Annotation | Compatibility Changes | +|--------|--------------------------|-----------------------| +| Added | **[`CheckReturnValue`]** | ![No changes] | + +___ + + +### `com.google.common.primitives.UnsignedBytes` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|-----------|------------------|-------|-----------------|------------|-------|---------------------|-----------------------| +| Unchanged | `final` `public` | Class | `UnsignedBytes` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|-----------|-------------------|----------|----------------|-------------------------------|--------------------------|--------|-----------------------| +| Unchanged | `static` `public` | | `int` | `compare`(`byte`, `byte`) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | | [`String`] | `join`([`String`], `byte...`) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | | [`Comparator`] | `lexicographicalComparator`() | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | | `byte` | `max`(`byte...`) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | | `byte` | `min`(`byte...`) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | | `int` | `toInt`(`byte`) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | | [`String`] | `toString`(`byte`) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | | [`String`] | `toString`(`byte`, `int`) | **[`CheckReturnValue`]** | | ![Annotation added] | + +___ + + +### `com.google.common.primitives.UnsignedInteger` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|-----------|------------------|-------|-------------------|------------|-------|---------------|-----------------------| +| Unchanged | `final` `public` | Class | `UnsignedInteger` | [`Number`] | JDK 6 | ![Compatible] | ![Annotation added] | + + +#### Annotations + +| Status | Annotation | Compatibility Changes | +|--------|--------------------------|-----------------------| +| Added | **[`CheckReturnValue`]** | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|-----------|-----------|----------|---------------------|----------------------------------|--------------------------|--------|-----------------------| +| Unchanged | `public` | | [`UnsignedInteger`] | `dividedBy`([`UnsignedInteger`]) | ~~[`CheckReturnValue`]~~ | | ![Annotation removed] | +| Unchanged | `public` | | [`UnsignedInteger`] | `minus`([`UnsignedInteger`]) | ~~[`CheckReturnValue`]~~ | | ![Annotation removed] | +| Unchanged | `public` | | [`UnsignedInteger`] | `mod`([`UnsignedInteger`]) | ~~[`CheckReturnValue`]~~ | | ![Annotation removed] | +| Unchanged | `public` | | [`UnsignedInteger`] | `plus`([`UnsignedInteger`]) | ~~[`CheckReturnValue`]~~ | | ![Annotation removed] | +| Unchanged | `public` | | [`UnsignedInteger`] | `times`([`UnsignedInteger`]) | ~~[`CheckReturnValue`]~~ | | ![Annotation removed] | + +___ + + +### `com.google.common.primitives.UnsignedInts` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|-----------|------------------|-------|----------------|------------|-------|---------------------|-----------------------| +| Unchanged | `final` `public` | Class | `UnsignedInts` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|-----------|-------------------|----------|----------------|-------------------------------|--------------------------|--------|-----------------------| +| Unchanged | `static` `public` | | `int` | `compare`(`int`, `int`) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | | `int` | `divide`(`int`, `int`) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | | [`String`] | `join`([`String`], `int...`) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | | [`Comparator`] | `lexicographicalComparator`() | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | | `int` | `max`(`int...`) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | | `int` | `min`(`int...`) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | | `int` | `remainder`(`int`, `int`) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | | `long` | `toLong`(`int`) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | | [`String`] | `toString`(`int`) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | | [`String`] | `toString`(`int`, `int`) | **[`CheckReturnValue`]** | | ![Annotation added] | + +___ + + +### `com.google.common.primitives.UnsignedLong` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|-----------|------------------|-------|----------------|------------|-------|---------------|-----------------------| +| Unchanged | `final` `public` | Class | `UnsignedLong` | [`Number`] | JDK 6 | ![Compatible] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|-----------|-----------|----------|------------------|---------------------------|--------------------------|--------|-----------------------| +| Unchanged | `public` | | [`UnsignedLong`] | `minus`([`UnsignedLong`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `public` | | [`UnsignedLong`] | `plus`([`UnsignedLong`]) | **[`CheckReturnValue`]** | | ![Annotation added] | + +___ + + +### `com.google.common.primitives.UnsignedLongs` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|-----------|------------------|-------|-----------------|------------|-------|---------------------|-----------------------| +| Unchanged | `final` `public` | Class | `UnsignedLongs` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|-----------|-------------------|----------|----------------|-------------------------------|--------------------------|--------|-----------------------| +| Unchanged | `static` `public` | | `int` | `compare`(`long`, `long`) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | | `long` | `divide`(`long`, `long`) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | | [`String`] | `join`([`String`], `long...`) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | | [`Comparator`] | `lexicographicalComparator`() | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | | `long` | `max`(`long...`) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | | `long` | `min`(`long...`) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | | `long` | `remainder`(`long`, `long`) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | | [`String`] | `toString`(`long`) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | | [`String`] | `toString`(`long`, `int`) | **[`CheckReturnValue`]** | | ![Annotation added] | + +___ + + +### `com.google.common.reflect.ClassPath$ResourceInfo` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------|-------------------|-------|----------------|------------|-------|---------------------|-----------------------| +| Modified | `static` `public` | Class | `ResourceInfo` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|----------|------------------|----------|---------|---------|-------------|--------------------------------|-----------------------| +| Modified | `final` `public` | | [`URL`] | `url`() | | **[`NoSuchElementException`]** | ![No changes] | + +___ + + +### `com.google.common.reflect.TypeToken` + +- [X] Binary-compatible +- [X] Source-compatible +- [ ] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------|---------------------|-------|-------------|--------------------|-------|-------------------------------------|-----------------------| +| Modified | `public` `abstract` | Class | `TypeToken` | [`TypeCapture`] | JDK 6 | ![Default serialversionuid changed] | ![No changes] | + + +#### Generics + +| Status | Name | Extends | Compatibility Changes | +|-----------|------|------------|-----------------------| +| Unchanged | `T` | [`Object`] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|-----------|--------------------------|----------|---------------|---------------------------------------|--------------------|--------|-----------------------| +| Unchanged | `final` `public` | | `boolean` | `isAssignableFrom`([`TypeToken`]) | **[`Deprecated`]** | | ![Annotation deprecated added] | +| Unchanged | `final` `public` | | `boolean` | `isAssignableFrom`([`Type`]) | **[`Deprecated`]** | | ![Annotation deprecated added] | +| Added | **`final`** **`public`** | | **`boolean`** | **`isSubtypeOf`**([`TypeToken`]) | | | ![Method added to public class] | +| Added | **`final`** **`public`** | | **`boolean`** | **`isSubtypeOf`**([`Type`]) | | | ![Method added to public class] | +| Added | **`final`** **`public`** | | **`boolean`** | **`isSupertypeOf`**([`TypeToken`]) | | | ![Method added to public class] | +| Added | **`final`** **`public`** | | **`boolean`** | **`isSupertypeOf`**([`Type`]) | | | ![Method added to public class] | + +___ + + +### `com.google.common.util.concurrent.AbstractFuture` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------|---------------------|-------|------------------|------------|-------|---------------------|-----------------------| +| Modified | `public` `abstract` | Class | `AbstractFuture` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] | + + +#### Generics + +| Status | Name | Extends | Compatibility Changes | +|-----------|------|------------|-----------------------| +| Unchanged | `V` | [`Object`] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|--------|-----------------|----------|---------------|----------------------------------------------------|-------------|--------|-----------------------| +| Added | **`protected`** | | **`boolean`** | **`setFuture`**([`ListenableFuture`]) | | | ![No changes] | + +___ + + +### `com.google.common.util.concurrent.AbstractListeningExecutorService` + +- [ ] Binary-compatible +- [ ] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------|---------------------|-------|------------------------------------|-----------------------------|-------|---------------------|-----------------------| +| Modified | `public` `abstract` | Class | `AbstractListeningExecutorService` | [`AbstractExecutorService`] | JDK 6 | ![Not serializable] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|----------|---------------------|--------------------------|------------------------------------------------------------------|---------------------------------|-------------|--------|-----------------------| +| Modified | `final` `protected` | \<[`T extends Object`]\> | ~~[`ListenableFutureTask`]~~ → **[`RunnableFuture`]** | `newTaskFor`([`Runnable`], `T`) | | | ![Method return type changed] | +| Modified | `final` `protected` | \<[`T extends Object`]\> | ~~[`ListenableFutureTask`]~~ → **[`RunnableFuture`]** | `newTaskFor`([`Callable`]) | | | ![Method return type changed] | + +___ + + +### `com.google.common.util.concurrent.FutureFallback` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|-----------|---------------------|-----------|------------------|------------|-------|---------------------|-----------------------| +| Unchanged | `public` `abstract` | Interface | `FutureFallback` | [`Object`] | JDK 6 | ![Not serializable] | ![Annotation deprecated added] | + + +#### Generics + +| Status | Name | Extends | Compatibility Changes | +|-----------|------|------------|-----------------------| +| Unchanged | `V` | [`Object`] | ![No changes] | + + +#### Annotations + +| Status | Annotation | Compatibility Changes | +|--------|--------------------|-----------------------| +| Added | **[`Deprecated`]** | ![No changes] | + +___ + + +### `com.google.common.util.concurrent.Futures` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------|------------------|-------|-----------|----------------------------------------------------------------|-------|---------------------|-----------------------| +| Modified | `final` `public` | Class | `Futures` | ~~[`Object`]~~ → **[`GwtFuturesCatchingSpecialization`]** | JDK 6 | ![Not serializable] | ![Superclass added] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|-----------|---------------------------|-----------------------------------------------------------|----------------------------------------|----------------------------------------------------------|-------------------------------------------------|-------------------|-----------------------| +| Unchanged | `static` `public` | \<[`V extends Object`]\> | [`ListenableFuture>`] | `allAsList`([`ListenableFuture...`]) | **[`CheckReturnValue`]**
**[`SafeVarargs`]** | | ![Annotation added] | +| Unchanged | `static` `public` | \<[`V extends Object`]\> | [`ListenableFuture>`] | `allAsList`([`Iterable>`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Added | **`static`** **`public`** | \<**[`V extends Object`]**, **[`X extends Throwable`]**\> | **[`ListenableFuture`]** | **`catching`**([`ListenableFuture`], [`Class`], [`Function`]) | **[`CheckReturnValue`]** | | ![Method added to public class] ![Annotation added] | +| Added | **`static`** **`public`** | \<**[`V extends Object`]**, **[`X extends Throwable`]**\> | **[`ListenableFuture`]** | **`catching`**([`ListenableFuture`], [`Class`], [`Function`], [`Executor`]) | **[`CheckReturnValue`]** | | ![Method added to public class] ![Annotation added] | +| Added | **`static`** **`public`** | \<**[`V extends Object`]**, **[`X extends Throwable`]**\> | **[`ListenableFuture`]** | **`catchingAsync`**([`ListenableFuture`], [`Class`], [`AsyncFunction`]) | | | ![Method added to public class] | +| Added | **`static`** **`public`** | \<**[`V extends Object`]**, **[`X extends Throwable`]**\> | **[`ListenableFuture`]** | **`catchingAsync`**([`ListenableFuture`], [`Class`], [`AsyncFunction`], [`Executor`]) | | | ![Method added to public class] | +| Unchanged | `static` `public` | \<[`V extends Object`]\> | [`ListenableFuture`] | `dereference`([`ListenableFuture>`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | \<[`V extends Object`], [`X extends Exception`]\> | [`Object`] | `get`([`Future`], [`Class`]) | **[`Deprecated`]** | [`Exception`] | ![Annotation deprecated added] | +| Unchanged | `static` `public` | \<[`V extends Object`], [`X extends Exception`]\> | [`Object`] | `get`([`Future`], `long`, [`TimeUnit`], [`Class`]) | **[`Deprecated`]** | [`Exception`] | ![Annotation deprecated added] | +| Added | **`static`** **`public`** | \<**[`V extends Object`]**, **[`X extends Exception`]**\> | **[`Object`]** | **`getChecked`**([`Future`], [`Class`]) | | **[`Exception`]** | ![Method added to public class] | +| Added | **`static`** **`public`** | \<**[`V extends Object`]**, **[`X extends Exception`]**\> | **[`Object`]** | **`getChecked`**([`Future`], [`Class`], `long`, [`TimeUnit`]) | | **[`Exception`]** | ![Method added to public class] | +| Unchanged | `static` `public` | \<[`V extends Object`]\> | [`ListenableFuture`] | `immediateCancelledFuture`() | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | \<[`V extends Object`], [`X extends Exception`]\> | [`CheckedFuture`] | `immediateCheckedFuture`(`V`) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | \<[`V extends Object`], [`X extends Exception`]\> | [`CheckedFuture`] | `immediateFailedCheckedFuture`(`X`) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | \<[`V extends Object`]\> | [`ListenableFuture`] | `immediateFailedFuture`([`Throwable`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | \<[`V extends Object`]\> | [`ListenableFuture`] | `immediateFuture`(`V`) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | \<[`T extends Object`]\> | [`ImmutableList>`] | `inCompletionOrder`([`Iterable>`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | \<[`I extends Object`], [`O extends Object`]\> | [`Future`] | `lazyTransform`([`Future`], [`Function`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | \<[`V extends Object`], [`X extends Exception`]\> | [`CheckedFuture`] | `makeChecked`([`ListenableFuture`], [`Function`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | \<[`V extends Object`]\> | [`ListenableFuture`] | `nonCancellationPropagating`([`ListenableFuture`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | \<[`V extends Object`]\> | [`ListenableFuture>`] | `successfulAsList`([`ListenableFuture...`]) | **[`CheckReturnValue`]**
**[`SafeVarargs`]** | | ![Annotation added] | +| Unchanged | `static` `public` | \<[`V extends Object`]\> | [`ListenableFuture>`] | `successfulAsList`([`Iterable>`]) | **[`CheckReturnValue`]** | | ![Annotation added] | +| Unchanged | `static` `public` | \<[`I extends Object`], [`O extends Object`]\> | [`ListenableFuture`] | `transform`([`ListenableFuture`], [`AsyncFunction`]) | **[`Deprecated`]** | | ![Annotation deprecated added] | +| Unchanged | `static` `public` | \<[`I extends Object`], [`O extends Object`]\> | [`ListenableFuture`] | `transform`([`ListenableFuture`], [`AsyncFunction`], [`Executor`]) | **[`Deprecated`]** | | ![Annotation deprecated added] | +| Added | **`static`** **`public`** | \<**[`I extends Object`]**, **[`O extends Object`]**\> | **[`ListenableFuture`]** | **`transformAsync`**([`ListenableFuture`], [`AsyncFunction`]) | | | ![Method added to public class] | +| Added | **`static`** **`public`** | \<**[`I extends Object`]**, **[`O extends Object`]**\> | **[`ListenableFuture`]** | **`transformAsync`**([`ListenableFuture`], [`AsyncFunction`], [`Executor`]) | | | ![Method added to public class] | +| Unchanged | `static` `public` | \<[`V extends Object`]\> | [`ListenableFuture`] | `withFallback`([`ListenableFuture`], [`FutureFallback`]) | **[`CheckReturnValue`]**
**[`Deprecated`]** | | ![Annotation added] ![Annotation deprecated added] | +| Unchanged | `static` `public` | \<[`V extends Object`]\> | [`ListenableFuture`] | `withFallback`([`ListenableFuture`], [`FutureFallback`], [`Executor`]) | **[`CheckReturnValue`]**
**[`Deprecated`]** | | ![Annotation added] ![Annotation deprecated added] | +| Added | **`static`** **`public`** | \<**[`V extends Object`]**\> | **[`ListenableFuture`]** | **`withTimeout`**([`ListenableFuture`], `long`, [`TimeUnit`], [`ScheduledExecutorService`]) | **[`CheckReturnValue`]** | | ![Method added to public class] ![Annotation added] | + +___ + + +### `com.google.common.util.concurrent.SettableFuture` + +- [X] Binary-compatible +- [X] Source-compatible +- [X] Serialization-compatible + +| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes | +|----------|------------------|-------|------------------|-----------------------------------------------------------|-------|---------------------|-----------------------| +| Modified | `final` `public` | Class | `SettableFuture` | ~~[`AbstractFuture`]~~ → **[`TrustedFuture`]** | JDK 6 | ![Not serializable] | ![Superclass added] | + + +#### Generics + +| Status | Name | Extends | Compatibility Changes | +|-----------|------|------------|-----------------------| +| Unchanged | `V` | [`Object`] | ![No changes] | + + +#### Methods + +| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes | +|--------|--------------|----------|---------------|----------------------------------------------------|-------------|--------|-----------------------| +| Added | **`public`** | | **`boolean`** | **`setFuture`**([`ListenableFuture`]) | | | ![Method added to public class] | + + +
+ + +___ + +*Generated on: 2024-07-29 17:08:40.539+0000*. + +[1]: # "java.lang.Object[]" +[2]: # "com.google.common.base.Objects$ToStringHelper" +[3]: # "com.google.common.collect.ImmutableBiMap$Builder" +[4]: # "com.google.common.collect.ImmutableMultimap$Builder" +[5]: # "com.google.common.collect.ImmutableListMultimap$Builder" +[6]: # "com.google.common.collect.ImmutableMap" +[7]: # "com.google.common.collect.ImmutableMap$Builder" +[8]: # "com.google.common.collect.ImmutableMultimap" +[9]: # "com.google.common.collect.ImmutableMultimap$Builder" +[10]: # "com.google.common.collect.ImmutableSetMultimap$Builder" +[11]: # "com.google.common.collect.ImmutableSortedMap$Builder" +[Annotation added]: https://img.shields.io/badge/Annotation_added-yellow "Annotation added" +[Annotation deprecated added]: https://img.shields.io/badge/Annotation_deprecated_added-orange "Annotation deprecated added" +[Annotation removed]: https://img.shields.io/badge/Annotation_removed-yellow "Annotation removed" +[Class generic template generics changed]: https://img.shields.io/badge/Class_generic_template_generics_changed-orange "Class generic template generics changed" +[Class now final]: https://img.shields.io/badge/Class_now_final-red "Class now final" +[Compatible]: https://img.shields.io/badge/Compatible-green "Compatible" +[Default serialversionuid changed]: https://img.shields.io/badge/Incompatible-red "Default serialversionuid changed" +[Interface added]: https://img.shields.io/badge/Interface_added-orange "Interface added" +[Method added to interface]: https://img.shields.io/badge/Method_added_to_interface-orange "Method added to interface" +[Method added to public class]: https://img.shields.io/badge/Method_added_to_public_class-yellow "Method added to public class" +[Method less accessible]: https://img.shields.io/badge/Method_less_accessible-red "Method less accessible" +[Method now abstract]: https://img.shields.io/badge/Method_now_abstract-red "Method now abstract" +[Method removed]: https://img.shields.io/badge/Method_removed-red "Method removed" +[Method return type changed]: https://img.shields.io/badge/Method_return_type_changed-red "Method return type changed" +[Method return type generics changed]: https://img.shields.io/badge/Method_return_type_generics_changed-orange "Method return type generics changed" +[No changes]: https://img.shields.io/badge/No_changes-green "No changes" +[Not serializable]: https://img.shields.io/badge/Not_serializable-green "Not serializable" +[Superclass added]: https://img.shields.io/badge/Superclass_added-orange "Superclass added" +[Superclass modified]: https://img.shields.io/badge/Incompatible-red "Superclass modified" +[`AbstractCollection`]: # "java.util.AbstractCollection" +[`AbstractExecutorService`]: # "java.util.concurrent.AbstractExecutorService" +[`AbstractFuture`]: # "com.google.common.util.concurrent.AbstractFuture" +[`AbstractMap`]: # "java.util.AbstractMap" +[`AbstractMultimap`]: # "com.google.common.collect.AbstractMultimap" +[`AbstractRangeSet`]: # "com.google.common.collect.AbstractRangeSet" +[`AsyncFunction`]: # "com.google.common.util.concurrent.AsyncFunction" +[`AsyncFunction`]: # "com.google.common.util.concurrent.AsyncFunction" +[`B extends Object`]: # "B extends java.lang.Object" +[`BiMap`]: # "com.google.common.collect.BiMap" +[`BloomFilter`]: # "com.google.common.hash.BloomFilter" +[`Boolean`]: # "java.lang.Boolean" +[`Builder`]: # "com.google.common.collect.ImmutableSortedMultiset$Builder" +[`Builder`]: # "com.google.common.collect.ImmutableMap$Builder" +[`Callable`]: # "java.util.concurrent.Callable" +[`CharMatcher`]: # "com.google.common.base.CharMatcher" +[`CharSequence`]: # "java.lang.CharSequence" +[`CheckForNull`]: # "javax.annotation.CheckForNull" +[`CheckReturnValue`]: # "javax.annotation.CheckReturnValue" +[`CheckedFuture`]: # "com.google.common.util.concurrent.CheckedFuture" +[`Class`]: # "java.lang.Class" +[`Class`]: # "java.lang.Class" +[`Class`]: # "java.lang.Class" +[`Class`]: # "java.lang.Class" +[`Collection`]: # "java.util.Collection" +[`Collection`]: # "java.util.Collection" +[`Comparable`]: # "java.lang.Comparable" +[`Comparable`]: # "java.lang.Comparable" +[`Comparator`]: # "java.util.Comparator" +[`Comparator`]: # "java.util.Comparator" +[`Comparator`]: # "java.util.Comparator" +[`Comparator`]: # "java.util.Comparator" +[`ComparisonChain`]: # "com.google.common.collect.ComparisonChain" +[`Deprecated`]: # "java.lang.Deprecated" +[`Double`]: # "java.lang.Double" +[`E extends Comparable`]: # "E extends java.lang.Comparable" +[`E extends Comparable`]: # "E extends java.lang.Comparable" +[`E extends Object`]: # "E extends java.lang.Object" +[`Entry`]: # "java.util.Map$Entry" +[`Enum`]: # "java.lang.Enum>" +[`EventBus`]: # "com.google.common.eventbus.EventBus" +[`Exception`]: # "java.lang.Exception" +[`Executor`]: # "java.util.concurrent.Executor" +[`F extends Object`]: # "F extends java.lang.Object" +[`FilterInputStream`]: # "java.io.FilterInputStream" +[`FilterOutputStream`]: # "java.io.FilterOutputStream" +[`Float`]: # "java.lang.Float" +[`FluentIterable`]: # "com.google.common.collect.FluentIterable" +[`FluentIterable`]: # "com.google.common.collect.FluentIterable" +[`ForwardingMap`]: # "com.google.common.collect.ForwardingMap" +[`Function>`]: # "com.google.common.base.Function>" +[`Function`]: # "com.google.common.base.Function" +[`Function`]: # "com.google.common.base.Function" +[`Function`]: # "com.google.common.base.Function" +[`Function`]: # "com.google.common.base.Function" +[`Function`]: # "com.google.common.base.Function" +[`Function`]: # "com.google.common.base.Function" +[`Function`]: # "com.google.common.base.Function" +[`Funnel`]: # "com.google.common.hash.Funnel" +[`Funnel`]: # "com.google.common.hash.Funnel" +[`Future`]: # "java.util.concurrent.Future" +[`Future`]: # "java.util.concurrent.Future" +[`Future`]: # "java.util.concurrent.Future" +[`FutureFallback`]: # "com.google.common.util.concurrent.FutureFallback" +[`GenericMapMaker`]: # "com.google.common.collect.GenericMapMaker" +[`GwtFuturesCatchingSpecialization`]: # "com.google.common.util.concurrent.GwtFuturesCatchingSpecialization" +[`HashCode`]: # "com.google.common.hash.HashCode" +[`HashFunction...`]: # "com.google.common.hash.HashFunction..." +[`HashFunction`]: # "com.google.common.hash.HashFunction" +[`I extends Object`]: # "I extends java.lang.Object" +[`IOException`]: # "java.io.IOException" +[`ImmutableBiMap`]: # "com.google.common.collect.ImmutableBiMap" +[`ImmutableClassToInstanceMap`]: # "com.google.common.collect.ImmutableClassToInstanceMap" +[`ImmutableCollection`]: # "com.google.common.collect.ImmutableCollection" +[`ImmutableCollection`]: # "com.google.common.collect.ImmutableCollection" +[`ImmutableList`]: # "com.google.common.collect.ImmutableList" +[`ImmutableList>`]: # "com.google.common.collect.ImmutableList>" +[`ImmutableListMultimap`]: # "com.google.common.collect.ImmutableListMultimap" +[`ImmutableListMultimap`]: # "com.google.common.collect.ImmutableListMultimap" +[`ImmutableMap`]: # "com.google.common.collect.ImmutableMap" +[`ImmutableMap`]: # "com.google.common.collect.ImmutableMap" +[`ImmutableMap`]: # "com.google.common.collect.ImmutableMap" +[`ImmutableMap, V>`]: # "com.google.common.collect.ImmutableMap, V>" +[`ImmutableMultimap`]: # "com.google.common.collect.ImmutableMultimap" +[`ImmutableMultiset`]: # "com.google.common.collect.ImmutableMultiset" +[`ImmutableSet`]: # "com.google.common.collect.ImmutableSet" +[`ImmutableSet>`]: # "com.google.common.collect.ImmutableSet>" +[`ImmutableSetMultimap`]: # "com.google.common.collect.ImmutableSetMultimap" +[`ImmutableSortedMap`]: # "com.google.common.collect.ImmutableSortedMap" +[`ImmutableSortedMapFauxverideShim`]: # "com.google.common.collect.ImmutableSortedMapFauxverideShim" +[`ImmutableSortedSet`]: # "com.google.common.collect.ImmutableSortedSet" +[`ImmutableSortedSet`]: # "com.google.common.collect.ImmutableSortedSet" +[`ImmutableSortedSetFauxverideShim`]: # "com.google.common.collect.ImmutableSortedSetFauxverideShim" +[`ImmutableSorted…etFauxverideShim`]: # "com.google.common.collect.ImmutableSortedMultisetFauxverideShim" +[`InputStream`]: # "java.io.InputStream" +[`Integer`]: # "java.lang.Integer" +[`Iterable>`]: # "java.lang.Iterable>" +[`Iterable>`]: # "java.lang.Iterable>" +[`Iterable>`]: # "java.lang.Iterable>" +[`Iterable>`]: # "java.lang.Iterable>" +[`Iterable`]: # "java.lang.Iterable" +[`Iterable`]: # "java.lang.Iterable" +[`Iterable`]: # "java.lang.Iterable" +[`Iterable`]: # "java.lang.Iterable" +[`Iterable`]: # "java.lang.Iterable" +[`Iterable`]: # "java.lang.Iterable" +[`Iterator>`]: # "java.util.Iterator>" +[`Iterator`]: # "java.util.Iterator" +[`Iterator`]: # "java.util.Iterator" +[`IteratorBasedAbstractMap`]: # "com.google.common.collect.Maps$IteratorBasedAbstractMap" +[`Joiner`]: # "com.google.common.base.Joiner" +[`K extends Object`]: # "K extends java.lang.Object" +[`LinkedHashMap`]: # "java.util.LinkedHashMap" +[`List...`]: # "java.util.List..." +[`List>`]: # "java.util.List>" +[`List`]: # "java.util.List" +[`List>`]: # "java.util.List>" +[`List`]: # "java.util.List" +[`List`]: # "java.util.List" +[`List`]: # "java.util.List" +[`List`]: # "java.util.List" +[`ListMultimap`]: # "com.google.common.collect.ListMultimap" +[`ListenableFuture...`]: # "com.google.common.util.concurrent.ListenableFuture..." +[`ListenableFuture>`]: # "com.google.common.util.concurrent.ListenableFuture>" +[`ListenableFuture`]: # "com.google.common.util.concurrent.ListenableFuture" +[`ListenableFuture`]: # "com.google.common.util.concurrent.ListenableFuture" +[`ListenableFuture>`]: # "com.google.common.util.concurrent.ListenableFuture>" +[`ListenableFuture`]: # "com.google.common.util.concurrent.ListenableFuture" +[`ListenableFuture`]: # "com.google.common.util.concurrent.ListenableFuture" +[`ListenableFutureTask`]: # "com.google.common.util.concurrent.ListenableFutureTask" +[`Long`]: # "java.lang.Long" +[`Map`]: # "java.util.Map" +[`Map`]: # "java.util.Map" +[`Map`]: # "java.util.Map" +[`Map, V>`]: # "java.util.Map, V>" +[`Map`]: # "java.util.Map" +[`MapMaker`]: # "com.google.common.collect.MapMaker" +[`MediaType`]: # "com.google.common.net.MediaType" +[`Multimap`]: # "com.google.common.collect.Multimap" +[`Multiset`]: # "com.google.common.collect.Multiset" +[`Multiset`]: # "com.google.common.collect.Multiset" +[`NavigableMap`]: # "java.util.NavigableMap" +[`NavigableSet`]: # "java.util.NavigableSet" +[`NoSuchElementException`]: # "java.util.NoSuchElementException" +[`Nullable`]: # "javax.annotation.Nullable" +[`Number`]: # "java.lang.Number" +[`O extends Object`]: # "O extends java.lang.Object" +[`Object...`]: # "java.lang.Object..." +[`Object`]: # "java.lang.Object" +[`Optional`]: # "com.google.common.base.Optional" +[`Optional`]: # "com.google.common.base.Optional" +[`OutputStream`]: # "java.io.OutputStream" +[`Pattern`]: # "java.util.regex.Pattern" +[`Predicate`]: # "com.google.common.base.Predicate" +[`Predicate>`]: # "com.google.common.base.Predicate>" +[`Predicate`]: # "com.google.common.base.Predicate" +[`Predicate`]: # "com.google.common.base.Predicate" +[`Predicate`]: # "com.google.common.base.Predicate" +[`RangeMap`]: # "com.google.common.collect.RangeMap" +[`RangeSet`]: # "com.google.common.collect.RangeSet" +[`Reader`]: # "java.io.Reader" +[`RemovalCause`]: # "com.google.common.cache.RemovalCause" +[`RemovalNotification`]: # "com.google.common.cache.RemovalNotification" +[`RunnableFuture`]: # "java.util.concurrent.RunnableFuture" +[`Runnable`]: # "java.lang.Runnable" +[`RuntimeException`]: # "java.lang.RuntimeException" +[`SafeVarargs`]: # "java.lang.SafeVarargs" +[`ScheduledExecutorService`]: # "java.util.concurrent.ScheduledExecutorService" +[`Serializable`]: # "java.io.Serializable" +[`Set`]: # "java.util.Set" +[`Set>`]: # "java.util.Set>" +[`Set>`]: # "java.util.Set>" +[`SetMultimap`]: # "com.google.common.collect.SetMultimap" +[`Set`]: # "java.util.Set" +[`SortedMap`]: # "java.util.SortedMap" +[`SortedSet`]: # "java.util.SortedSet" +[`Splitter`]: # "com.google.common.base.Splitter" +[`Stopwatch`]: # "com.google.common.base.Stopwatch" +[`String`]: # "java.lang.String" +[`T extends Object`]: # "T extends java.lang.Object" +[`Throwable`]: # "java.lang.Throwable" +[`Ticker`]: # "com.google.common.base.Ticker" +[`TimeUnit`]: # "java.util.concurrent.TimeUnit" +[`ToStringHelper`]: # "com.google.common.base.MoreObjects$ToStringHelper" +[`TrustedFuture`]: # "com.google.common.util.concurrent.AbstractFuture$TrustedFuture" +[`TypeCapture`]: # "com.google.common.reflect.TypeCapture" +[`TypeToken`]: # "com.google.common.reflect.TypeToken" +[`Type`]: # "java.lang.reflect.Type" +[`URL`]: # "java.net.URL" +[`UnmodifiableIterator`]: # "com.google.common.collect.UnmodifiableIterator" +[`UnsignedInteger`]: # "com.google.common.primitives.UnsignedInteger" +[`UnsignedLong`]: # "com.google.common.primitives.UnsignedLong" +[`UnsupportedOperationException`]: # "java.lang.UnsupportedOperationException" +[`V extends Object`]: # "V extends java.lang.Object" +[`Writer`]: # "java.io.Writer" +[`X extends Exception`]: # "X extends java.lang.Exception" +[`X extends Throwable`]: # "X extends java.lang.Throwable" +[com.google.common.base.Ascii]: #user-content-com.google.common.base.ascii +[com.google.common.base.CaseFormat]: #user-content-com.google.common.base.caseformat +[com.google.common.base.CharMatcher]: #user-content-com.google.common.base.charmatcher +[com.google.common.base.Defaults]: #user-content-com.google.common.base.defaults +[com.google.common.base.Enums]: #user-content-com.google.common.base.enums +[com.google.common.base.Equivalence]: #user-content-com.google.common.base.equivalence +[com.google.common.base.Functions]: #user-content-com.google.common.base.functions +[com.google.common.base.Joiner]: #user-content-com.google.common.base.joiner +[com.google.common.base.Joiner$MapJoiner]: #user-content-com.google.common.base.joiner$mapjoiner +[com.google.common.base.MoreObjects]: #user-content-com.google.common.base.moreobjects +[com.google.common.base.MoreObjects$ToStringHelper]: #user-content-com.google.common.base.moreobjects$tostringhelper +[com.google.common.base.Objects]: #user-content-com.google.common.base.objects +[com.google.common.base.Optional]: #user-content-com.google.common.base.optional +[com.google.common.base.Predicates]: #user-content-com.google.common.base.predicates +[com.google.common.base.Splitter]: #user-content-com.google.common.base.splitter +[com.google.common.base.Splitter$MapSplitter]: #user-content-com.google.common.base.splitter$mapsplitter +[com.google.common.base.StandardSystemProperty]: #user-content-com.google.common.base.standardsystemproperty +[com.google.common.base.Stopwatch]: #user-content-com.google.common.base.stopwatch +[com.google.common.base.Strings]: #user-content-com.google.common.base.strings +[com.google.common.base.Suppliers]: #user-content-com.google.common.base.suppliers +[com.google.common.base.Throwables]: #user-content-com.google.common.base.throwables +[com.google.common.base.Ticker]: #user-content-com.google.common.base.ticker +[com.google.common.base.Utf8]: #user-content-com.google.common.base.utf8 +[com.google.common.base.VerifyException]: #user-content-com.google.common.base.verifyexception +[com.google.common.cache.CacheLoader$UnsupportedLoadingOperationException]: #user-content-com.google.common.cache.cacheloader$unsupportedloadingoperationexception +[com.google.common.cache.RemovalNotification]: #user-content-com.google.common.cache.removalnotification +[com.google.common.collect.BiMap]: #user-content-com.google.common.collect.bimap +[com.google.common.collect.Collections2]: #user-content-com.google.common.collect.collections2 +[com.google.common.collect.ComparisonChain]: #user-content-com.google.common.collect.comparisonchain +[com.google.common.collect.FluentIterable]: #user-content-com.google.common.collect.fluentiterable +[com.google.common.collect.HashBiMap]: #user-content-com.google.common.collect.hashbimap +[com.google.common.collect.ImmutableBiMap]: #user-content-com.google.common.collect.immutablebimap +[com.google.common.collect.ImmutableBiMap$Builder]: #user-content-com.google.common.collect.immutablebimap$builder +[com.google.common.collect.ImmutableClassToInstanceMap]: #user-content-com.google.common.collect.immutableclasstoinstancemap +[com.google.common.collect.ImmutableCollection]: #user-content-com.google.common.collect.immutablecollection +[com.google.common.collect.ImmutableList]: #user-content-com.google.common.collect.immutablelist +[com.google.common.collect.ImmutableListMultimap]: #user-content-com.google.common.collect.immutablelistmultimap +[com.google.common.collect.ImmutableListMultimap$Builder]: #user-content-com.google.common.collect.immutablelistmultimap$builder +[com.google.common.collect.ImmutableMap]: #user-content-com.google.common.collect.immutablemap +[com.google.common.collect.ImmutableMap$Builder]: #user-content-com.google.common.collect.immutablemap$builder +[com.google.common.collect.ImmutableMultimap]: #user-content-com.google.common.collect.immutablemultimap +[com.google.common.collect.ImmutableMultimap$Builder]: #user-content-com.google.common.collect.immutablemultimap$builder +[com.google.common.collect.ImmutableMultiset]: #user-content-com.google.common.collect.immutablemultiset +[com.google.common.collect.ImmutableRangeMap]: #user-content-com.google.common.collect.immutablerangemap +[com.google.common.collect.ImmutableRangeSet]: #user-content-com.google.common.collect.immutablerangeset +[com.google.common.collect.ImmutableSetMultimap]: #user-content-com.google.common.collect.immutablesetmultimap +[com.google.common.collect.ImmutableSetMultimap$Builder]: #user-content-com.google.common.collect.immutablesetmultimap$builder +[com.google.common.collect.ImmutableSortedMap]: #user-content-com.google.common.collect.immutablesortedmap +[com.google.common.collect.ImmutableSortedMap$Builder]: #user-content-com.google.common.collect.immutablesortedmap$builder +[com.google.common.collect.ImmutableSortedMultiset]: #user-content-com.google.common.collect.immutablesortedmultiset +[com.google.common.collect.ImmutableSortedSet]: #user-content-com.google.common.collect.immutablesortedset +[com.google.common.collect.Iterables]: #user-content-com.google.common.collect.iterables +[com.google.common.collect.Iterators]: #user-content-com.google.common.collect.iterators +[com.google.common.collect.Lists]: #user-content-com.google.common.collect.lists +[com.google.common.collect.MapConstraint]: #user-content-com.google.common.collect.mapconstraint +[com.google.common.collect.MapConstraints]: #user-content-com.google.common.collect.mapconstraints +[com.google.common.collect.MapMaker]: #user-content-com.google.common.collect.mapmaker +[com.google.common.collect.Maps]: #user-content-com.google.common.collect.maps +[com.google.common.collect.MultimapBuilder]: #user-content-com.google.common.collect.multimapbuilder +[com.google.common.collect.Multimaps]: #user-content-com.google.common.collect.multimaps +[com.google.common.collect.Multisets]: #user-content-com.google.common.collect.multisets +[com.google.common.collect.RangeMap]: #user-content-com.google.common.collect.rangemap +[com.google.common.collect.RangeSet]: #user-content-com.google.common.collect.rangeset +[com.google.common.collect.Sets]: #user-content-com.google.common.collect.sets +[com.google.common.collect.Table]: #user-content-com.google.common.collect.table +[com.google.common.collect.Table$Cell]: #user-content-com.google.common.collect.table$cell +[com.google.common.collect.TreeRangeMap]: #user-content-com.google.common.collect.treerangemap +[com.google.common.collect.TreeRangeSet]: #user-content-com.google.common.collect.treerangeset +[com.google.common.eventbus.AsyncEventBus]: #user-content-com.google.common.eventbus.asynceventbus +[com.google.common.eventbus.DeadEvent]: #user-content-com.google.common.eventbus.deadevent +[com.google.common.eventbus.EventBus]: #user-content-com.google.common.eventbus.eventbus +[com.google.common.hash.BloomFilter]: #user-content-com.google.common.hash.bloomfilter +[com.google.common.hash.Funnels]: #user-content-com.google.common.hash.funnels +[com.google.common.hash.HashCode]: #user-content-com.google.common.hash.hashcode +[com.google.common.hash.Hasher]: #user-content-com.google.common.hash.hasher +[com.google.common.hash.Hashing]: #user-content-com.google.common.hash.hashing +[com.google.common.hash.HashingInputStream]: #user-content-com.google.common.hash.hashinginputstream +[com.google.common.hash.HashingOutputStream]: #user-content-com.google.common.hash.hashingoutputstream +[com.google.common.io.BaseEncoding]: #user-content-com.google.common.io.baseencoding +[com.google.common.io.ByteSource]: #user-content-com.google.common.io.bytesource +[com.google.common.io.CharSource]: #user-content-com.google.common.io.charsource +[com.google.common.net.HttpHeaders]: #user-content-com.google.common.net.httpheaders +[com.google.common.net.MediaType]: #user-content-com.google.common.net.mediatype +[com.google.common.primitives.Booleans]: #user-content-com.google.common.primitives.booleans +[com.google.common.primitives.Bytes]: #user-content-com.google.common.primitives.bytes +[com.google.common.primitives.Chars]: #user-content-com.google.common.primitives.chars +[com.google.common.primitives.Doubles]: #user-content-com.google.common.primitives.doubles +[com.google.common.primitives.Floats]: #user-content-com.google.common.primitives.floats +[com.google.common.primitives.Ints]: #user-content-com.google.common.primitives.ints +[com.google.common.primitives.Longs]: #user-content-com.google.common.primitives.longs +[com.google.common.primitives.Primitives]: #user-content-com.google.common.primitives.primitives +[com.google.common.primitives.Shorts]: #user-content-com.google.common.primitives.shorts +[com.google.common.primitives.SignedBytes]: #user-content-com.google.common.primitives.signedbytes +[com.google.common.primitives.UnsignedBytes]: #user-content-com.google.common.primitives.unsignedbytes +[com.google.common.primitives.UnsignedInteger]: #user-content-com.google.common.primitives.unsignedinteger +[com.google.common.primitives.UnsignedInts]: #user-content-com.google.common.primitives.unsignedints +[com.google.common.primitives.UnsignedLong]: #user-content-com.google.common.primitives.unsignedlong +[com.google.common.primitives.UnsignedLongs]: #user-content-com.google.common.primitives.unsignedlongs +[com.google.common.reflect.ClassPath$ResourceInfo]: #user-content-com.google.common.reflect.classpath$resourceinfo +[com.google.common.reflect.TypeToken]: #user-content-com.google.common.reflect.typetoken +[com.google.common.util.concurrent.AbstractFuture]: #user-content-com.google.common.util.concurrent.abstractfuture +[com.google.common.util.concurrent.AbstractListeningExecutorService]: #user-content-com.google.common.util.concurrent.abstractlisteningexecutorservice +[com.google.common.util.concurrent.FutureFallback]: #user-content-com.google.common.util.concurrent.futurefallback +[com.google.common.util.concurrent.Futures]: #user-content-com.google.common.util.concurrent.futures +[com.google.common.util.concurrent.SettableFuture]: #user-content-com.google.common.util.concurrent.settablefuture diff --git a/doc/japicmp_guava_markdown.png b/doc/japicmp_guava_markdown.png new file mode 100644 index 0000000000000000000000000000000000000000..c7fc15aed3cfbeb8508d1f1b5ecae6646534f45d GIT binary patch literal 219594 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ℜ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

)ggqTg^Ld_e@bWfjYtmc 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

*%GO=Mb0nkm*W<@Yg}(S+8e3IW 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⪻0Y+SH3girf%l2xYB})^~%`tC+-SS63&q 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 WA(*S}DPf>*krI;^trq?j@P7g5;c&VD literal 0 HcmV?d00001 diff --git a/src/site/markdown/Examples.md b/src/site/markdown/Examples.md index d4fdf766f..7f4d88096 100644 --- a/src/site/markdown/Examples.md +++ b/src/site/markdown/Examples.md @@ -30,6 +30,11 @@ are marked with a trailing star (*). ... ``` +At your preference, japicmp can generate a [Markdown](https://www.markdownguide.org/) report. +You can see an example [here](https://github.com/siom79/japicmp/blob/master/doc/japicmp_guava.md). + +![Markdown Report](https://raw.github.com/siom79/japicmp/master/doc/japicmp_guava_markdown.png) + Optionally japicmp can also create an HTML report. An example for such a report can be found [here](http://htmlpreview.github.io/?https://github.com/siom79/japicmp/blob/master/doc/japicmp_guava.html): diff --git a/src/site/markdown/index.md b/src/site/markdown/index.md index 9b646a168..0355c52d5 100644 --- a/src/site/markdown/index.md +++ b/src/site/markdown/index.md @@ -107,7 +107,7 @@ Features * Comparison of two jar archives without the need to add all of their dependencies to the classpath. * Differences are printed on the command line in a simple diff format. -* Differences can optionally be printed as XML or HTML file. +* Differences can optionally be printed as [Markdown](https://www.markdownguide.org/), XML or HTML file. * Per default private and package protected classes and class members are not compared. If necessary, the access modifier of the classes and class members to be compared can be set to public, protected, package or private. * Per default all classes are tracked. If necessary, certain packages, classes, methods or fields can be excluded or explicitly included. Inclusion and exclusion is also possible based on annotations. From 98fe35bcd0d6c509f8dccf5231631f91d784844e Mon Sep 17 00:00:00 2001 From: Guillermo Calvo Date: Tue, 20 Aug 2024 19:11:00 +0200 Subject: [PATCH 11/15] Move the Markdown section below the HTML section --- src/site/markdown/Examples.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/site/markdown/Examples.md b/src/site/markdown/Examples.md index 7f4d88096..9523674e6 100644 --- a/src/site/markdown/Examples.md +++ b/src/site/markdown/Examples.md @@ -30,16 +30,16 @@ are marked with a trailing star (*). ... ``` -At your preference, japicmp can generate a [Markdown](https://www.markdownguide.org/) report. -You can see an example [here](https://github.com/siom79/japicmp/blob/master/doc/japicmp_guava.md). - -![Markdown Report](https://raw.github.com/siom79/japicmp/master/doc/japicmp_guava_markdown.png) - Optionally japicmp can also create an HTML report. An example for such a report can be found [here](http://htmlpreview.github.io/?https://github.com/siom79/japicmp/blob/master/doc/japicmp_guava.html): HTML Report +At your preference, japicmp can generate a [Markdown](https://www.markdownguide.org/) report. +You can see an example [here](https://github.com/siom79/japicmp/blob/master/doc/japicmp_guava.md). + +![Markdown Report](https://raw.github.com/siom79/japicmp/master/doc/japicmp_guava_markdown.png) + You can also let japicmp create an XML report like the following one: ``` From 1c73c30a9474c077807cd7e0ccc63b0017ec9692 Mon Sep 17 00:00:00 2001 From: Guillermo Calvo Date: Tue, 20 Aug 2024 19:19:12 +0200 Subject: [PATCH 12/15] Switch only the stdout output; avoid affecting the file output: HTML/XML --- japicmp/src/main/java/japicmp/cli/JApiCli.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/japicmp/src/main/java/japicmp/cli/JApiCli.java b/japicmp/src/main/java/japicmp/cli/JApiCli.java index f2ecd96e7..9cd4a8487 100644 --- a/japicmp/src/main/java/japicmp/cli/JApiCli.java +++ b/japicmp/src/main/java/japicmp/cli/JApiCli.java @@ -47,12 +47,6 @@ private void generateOutput(Options options, List jApiClasses, JarArc System.out.println(output); return; } - if (options.isMarkdown()) { - MarkdownOutputGenerator markdownOutputGenerator = new MarkdownOutputGenerator(options, jApiClasses); - String output = markdownOutputGenerator.generate(); - System.out.println(output); - return; - } SemverOut semverOut = new SemverOut(options, jApiClasses); if (options.getXmlOutputFile().isPresent()) { XmlOutputGeneratorOptions xmlOutputGeneratorOptions = new XmlOutputGeneratorOptions(); @@ -76,6 +70,12 @@ private void generateOutput(Options options, List jApiClasses, JarArc throw new JApiCmpException(JApiCmpException.Reason.IoException, "Could not write HTML file: " + e.getMessage(), e); } } + if (options.isMarkdown()) { + MarkdownOutputGenerator markdownOutputGenerator = new MarkdownOutputGenerator(options, jApiClasses); + String output = markdownOutputGenerator.generate(); + System.out.println(output); + return; + } StdoutOutputGenerator stdoutOutputGenerator = new StdoutOutputGenerator(options, jApiClasses); String output = stdoutOutputGenerator.generate(); System.out.println(output); From e00fd6afa0cb73dd8a4d3034c058c2196eb96cc6 Mon Sep 17 00:00:00 2001 From: Guillermo Calvo Date: Tue, 20 Aug 2024 19:22:08 +0200 Subject: [PATCH 13/15] Small refactor (don't override `toString()`) --- .../japicmp/output/markdown/MarkdownOutputGenerator.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/japicmp/src/main/java/japicmp/output/markdown/MarkdownOutputGenerator.java b/japicmp/src/main/java/japicmp/output/markdown/MarkdownOutputGenerator.java index 10eafa765..c6fa29671 100644 --- a/japicmp/src/main/java/japicmp/output/markdown/MarkdownOutputGenerator.java +++ b/japicmp/src/main/java/japicmp/output/markdown/MarkdownOutputGenerator.java @@ -41,11 +41,6 @@ public MarkdownOutputGenerator(Options options, List jApiClasses) { @Override public String generate() { - return toString(); - } - - @Override - public String toString() { final String semver = new SemverOut(options, jApiClasses).generate(); return renderHeading(0, md.title.report) + md.message.getSemverBadge(semver) + EOL + From c4659f1b9f89a95d297a7b3df752cb5ca9ebd03b Mon Sep 17 00:00:00 2001 From: Guillermo Calvo Date: Tue, 20 Aug 2024 19:42:34 +0200 Subject: [PATCH 14/15] Small refactor (simplify formatting JDK version) --- .../JApiClassFileFormatVersionHelper.java | 41 ++----------------- 1 file changed, 3 insertions(+), 38 deletions(-) diff --git a/japicmp/src/main/java/japicmp/util/JApiClassFileFormatVersionHelper.java b/japicmp/src/main/java/japicmp/util/JApiClassFileFormatVersionHelper.java index 545f928c4..58569548e 100644 --- a/japicmp/src/main/java/japicmp/util/JApiClassFileFormatVersionHelper.java +++ b/japicmp/src/main/java/japicmp/util/JApiClassFileFormatVersionHelper.java @@ -27,44 +27,9 @@ private static String getJdkVersion(int major, int minor) { return "JDK 1.3"; } else if (major == 48) { return "JDK 1.4"; - } else if (major == 49) { - return "JDK 5.0"; - } else if (major == 50) { - return "JDK 6"; - } else if (major == 51) { - return "JDK 7"; - } else if (major == 52) { - return "JDK 8"; - } else if (major == 53) { - return "JDK 9"; - } else if (major == 54) { - return "JDK 10"; - } else if (major == 55) { - return "JDK 11"; - } else if (major == 56) { - return "JDK 12"; - } else if (major == 57) { - return "JDK 13"; - } else if (major == 58) { - return "JDK 14"; - } else if (major == 59) { - return "JDK 15"; - } else if (major == 60) { - return "JDK 16"; - } else if (major == 61) { - return "JDK 17"; - } else if (major == 62) { - return "JDK 18"; - } else if (major == 63) { - return "JDK 19"; - } else if (major == 64) { - return "JDK 20"; - } else if (major == 65) { - return "JDK 21"; - } else if (major == 66) { - return "JDK 22"; - } else if (major == 67) { - return "JDK 23"; + } else if (major >= 49 && major <= 70) { + // JDK 5 to 26, according to: https://andbin.github.io/java-versions-cheat-sheet/ + return "JDK " + (major - 44); } return "Version " + major + "." + minor; } From 554a6c6c046ccf35c60daec92ca16bcca8ff48ba Mon Sep 17 00:00:00 2001 From: Guillermo Calvo Date: Tue, 20 Aug 2024 20:56:10 +0200 Subject: [PATCH 15/15] Extract complex expression to help JDK 8 make sense of the Java types MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Full explanation: JDK 8 doesn't realize we want to handle a stream of `JApiCompatibility` elements. Instead, the compiler thinks we want to create a stream of `JApiHasChangeStatus` elements. So I just extracted the complex expression to a constant with the appropriate type and it works fine. Other JDK versions get it right without the type hint. ¯\_(ツ)_/¯ Root cause of the problem: ``` Caused by: java.lang.invoke.LambdaConversionException: Invalid receiver type interface japicmp.model.JApiHasChangeStatus; not a subtype of implementation type interface japicmp.model.JApiCompatibility at java.lang.invoke.AbstractValidatingLambdaMetafactory.validateMetafactoryArgs(AbstractValidatingLambdaMetafactory.java:233) at java.lang.invoke.LambdaMetafactory.metafactory(LambdaMetafactory.java:303) at java.lang.invoke.CallSite.makeSite(CallSite.java:302) ... 54 more ``` --- .../japicmp/output/markdown/MarkdownOutputGenerator.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/japicmp/src/main/java/japicmp/output/markdown/MarkdownOutputGenerator.java b/japicmp/src/main/java/japicmp/output/markdown/MarkdownOutputGenerator.java index c6fa29671..0666647ef 100644 --- a/japicmp/src/main/java/japicmp/output/markdown/MarkdownOutputGenerator.java +++ b/japicmp/src/main/java/japicmp/output/markdown/MarkdownOutputGenerator.java @@ -384,7 +384,7 @@ private final String renderCompatibilityChanges(List> allCompatibilityChanges = Stream.of( singletonList(clazz), singletonList(clazz.getClassFileFormatVersion()), singletonList(clazz.getSuperclass()), @@ -397,7 +397,8 @@ private String renderAllCompatibilityChanges(JApiClass clazz) { clazz.getMethods(), clazz.getMethods().stream().map(JApiMethod::getReturnType).collect(toList()), clazz.getMethods().stream().map(JApiMethod::getParameters).flatMap(List::stream).collect(toList()), - clazz.getFields()) + clazz.getFields()); + return renderCompatibilityChanges(allCompatibilityChanges .flatMap(List::stream) .map(JApiCompatibility::getCompatibilityChanges) .flatMap(List::stream)