diff --git a/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/builder/BaseApiAnalyzer.java b/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/builder/BaseApiAnalyzer.java index c26265d2c5..1eca08a265 100644 --- a/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/builder/BaseApiAnalyzer.java +++ b/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/builder/BaseApiAnalyzer.java @@ -2307,14 +2307,41 @@ private void checkApiComponentPackageVersions(BundleComponent referenceBundle, B .collect(Collectors.toMap(ExportPackageDescription::getName, Function.identity())); // a mapping between a package name and a required change Map requiredChanges = new HashMap<>(); + Set microChanged = new HashSet<>(); + // here we check for problems that are actually only a micro change in package + // version in the compatible category + for (IDelta delta : compatibleChanges) { + if (isMicroPackageChange(delta)) { + microChanged.add(delta); + analyzePackageDelta(delta, IApiProblem.MICRO_VERSION_CHANGE_PACKAGE, referencePackages, + componentPackages, requiredChanges); + } + } + // here we check for problems that are actually only a micro change in package + // version in the breaking category + for (IDelta delta : breakingChanges) { + if (isMicroPackageChange(delta)) { + microChanged.add(delta); + analyzePackageDelta(delta, IApiProblem.MICRO_VERSION_CHANGE_PACKAGE, referencePackages, + componentPackages, requiredChanges); + } + } // we must compare compatible changes first, so these where overwritten later by - // breaking changes probably + // breaking changes for a package probably for (IDelta delta : compatibleChanges) { + if (microChanged.contains(delta)) { + // we have already identified the delta as a micro change + continue; + } // a compatible change must result in a minor package version increment analyzePackageDelta(delta, IApiProblem.MINOR_VERSION_CHANGE_PACKAGE, referencePackages, componentPackages, requiredChanges); } for (IDelta delta : breakingChanges) { + if (microChanged.contains(delta)) { + // we have already identified the delta as a micro change + continue; + } // a breaking change must result in a major package change analyzePackageDelta(delta, IApiProblem.MAJOR_VERSION_CHANGE_PACKAGE, referencePackages, componentPackages, requiredChanges); @@ -2330,6 +2357,21 @@ private void checkApiComponentPackageVersions(BundleComponent referenceBundle, B } } + private boolean isMicroPackageChange(IDelta delta) { + if (delta.getElementType() == IDelta.INTERFACE_ELEMENT_TYPE) { + // for interface types we can have some changes that are actually compatible + // even with provider version range + if (delta.getKind() == IDelta.ADDED) { + if (delta.getFlags() == IDelta.FIELD) { + // adding a field to an interface is a binary compatible change for provider and + // consumer + return true; + } + } + } + return false; + } + private void analyzePackageDelta(IDelta delta, int category, Map referencePackages, Map componentPackages, @@ -2353,7 +2395,10 @@ private void analyzePackageDelta(IDelta delta, int category, return; } Version suggested; - if (IApiProblem.MINOR_VERSION_CHANGE_PACKAGE == category) { + if (IApiProblem.MICRO_VERSION_CHANGE_PACKAGE == category) { + suggested = new Version(baselineVersion.getMajor(), baselineVersion.getMinor(), + baselineVersion.getMicro() + 1); + } else if (IApiProblem.MINOR_VERSION_CHANGE_PACKAGE == category) { suggested = new Version(baselineVersion.getMajor(), baselineVersion.getMinor() + 1, 0); } else { suggested = new Version(baselineVersion.getMajor() + 1, baselineVersion.getMinor(), 0); @@ -2366,11 +2411,17 @@ private void analyzePackageDelta(IDelta delta, int category, if (compVersion.getMajor() > baselineVersion.getMajor()) { return; } - if (IApiProblem.MINOR_VERSION_CHANGE_PACKAGE == category) { + if (IApiProblem.MINOR_VERSION_CHANGE_PACKAGE == category + || IApiProblem.MICRO_VERSION_CHANGE_PACKAGE == category) { if (compVersion.getMinor() > baselineVersion.getMinor()) { return; } } + if (IApiProblem.MICRO_VERSION_CHANGE_PACKAGE == category) { + if (compVersion.getMicro() > baselineVersion.getMicro()) { + return; + } + } requiredChanges.put(packageName, new RequiredPackageVersionChange(category, baselineVersion, compVersion, suggested)); } diff --git a/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/problems/ApiProblemFactory.java b/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/problems/ApiProblemFactory.java index 6d8e47ec71..1b9869265f 100644 --- a/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/problems/ApiProblemFactory.java +++ b/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/problems/ApiProblemFactory.java @@ -594,6 +594,8 @@ public static int getProblemMessageId(int category, int element, int kind, int f return 65; case IApiProblem.MINOR_VERSION_CHANGE_PACKAGE: return 63; + case IApiProblem.MICRO_VERSION_CHANGE_PACKAGE: + return 68; default: break; } diff --git a/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/problems/problemmessages.properties b/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/problems/problemmessages.properties index e46d4ebd25..e25673e3ac 100644 --- a/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/problems/problemmessages.properties +++ b/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/problems/problemmessages.properties @@ -11,7 +11,7 @@ # Contributors: # IBM Corporation - initial API and implementation ############################################################################### -# available message ids 68, 70, 71, 75, 80, +# available message ids 70, 71, 75, 80, # 82, 83, 88, 90, 93 #API baseline @@ -39,6 +39,7 @@ 62 = The major version should be incremented in version {0}, because the bundle {1} is no longer re-exported 63 = The minor version for the package ''{0}'' should be incremented to version {1}, since new APIs have been added since version {2} 65 = The major version for the package ''{0}'' should be incremented to version {1}, since API breakage occurred since version {2} +68 = The micro version for the package ''{0}'' should be incremented to version {1}, since API changes occurred since version {2} #API usage problems #{0} = referenced type name diff --git a/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/provisional/problems/IApiProblem.java b/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/provisional/problems/IApiProblem.java index 0a26a6e9e2..44450089aa 100644 --- a/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/provisional/problems/IApiProblem.java +++ b/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/provisional/problems/IApiProblem.java @@ -262,6 +262,16 @@ public interface IApiProblem { */ public static final int MINOR_VERSION_CHANGE_PACKAGE = 12; + /** + * Constant representing the value of the micro version change + * {@link IApiProblem} kind for a package.
+ * Value is: 13 + * + * @see #getKind() + * @see #CATEGORY_VERSION + */ + public static final int MICRO_VERSION_CHANGE_PACKAGE = 13; + public static final int ILLEGAL_EXTEND = 1; /**