Add PrivateApi and ReservedSubclassing annotations

This commit is contained in:
Clément Fournier
2018-08-13 10:32:47 +02:00
parent 7e53729baa
commit a9c8ad7d97
5 changed files with 156 additions and 0 deletions

View File

@ -13,6 +13,7 @@ This is a minor release.
### Table Of Contents
* [New and noteworthy](#new-and-noteworthy)
* [Drawing a line between private and public API](#drawing-a-line-between-private-and-public-api)
* [New Rules](#new-rules)
* [Fixed Issues](#fixed-issues)
* [API Changes](#api-changes)
@ -20,6 +21,63 @@ This is a minor release.
### New and noteworthy
#### Drawing a line between private and public API
Until now, all released public members and types were implicitly considered part
of PMD's public API, including inheritance-specific members (protected members, abstract methods).
We have maintained those APIs with the goal to preserve full binary compatibility between minor releases,
only breaking those APIs infrequently, for major releases.
In order to allow PMD to move forward at a faster pace, this implicit contract will
be invalidated with PMD 7.0.0. We now introduce more fine-grained distinctions between
the type of compatibility support we guarantee for our libraries, and ways to make
them explicit to clients of PMD.
##### `.internal` packages and `@InternalApi` annotation
*Internal API* is meant for use *only* by the main PMD codebase. Internal types and methods
may be modified in any way, or even removed, at any time.
Any API in a package that contains an `.internal` segment is considered internal.
The `@InternalApi` annotation will be used for APIs that have to live outside of
these packages, e.g. methods of a public type that shouldn't be used outside of PMD (again,
these can be removed anytime).
##### `@ReservedSubclassing`
Types marked with the `@ReservedSubclassing` annotation are only meant to be subclassed
by classes within PMD. As such, we may add new abstract methods, or remove protected methods,
at any time. All published public members remain supported. The annotation is *not* inherited, which
means a reserved interface doesn't prevent its implementors to be subclassed.
##### `@Beta`
APIs marked with the `@Beta` annotation at the class or method level are subject to change.
They can be modified in any way, or even removed, at any time. If your code is a library
itself (i.e. it is used on the CLASSPATH of users outside your own control), you should not
use beta APIs, unless you repackage them (e.g. using ProGuard, shading, etc).
##### `@Experimental`
APIs marked with the `@Experimental` annotation at the class or method level will almost certainly
change. They can be modified in any way, or even removed, at any time. You should not use or rely
on them in any production code. They are purely to allow broad testing and feedback.
##### `@Deprecated`
APIs marked with the `@Deprecated` annotation at the class or method level will remain supported
until the next major release but it is recommended to stop using them.
##### The transition
*All currently supported APIs will remain so until 7.0.0*. All APIs that are to be moved to
`.internal` packages or hidden will be tagged `@InternalApi` before that major release, and
the breaking API changes will be performed in 7.0.0.
#### New Rules
* The new Java rule [`LinguisticNaming`](pmd_rules_java_codestyle.html#linguisticnaming) (`java-codestyle`)

View File

@ -0,0 +1,18 @@
/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.annotation;
import java.lang.annotation.Documented;
/**
* Indicates the feature is in beta state: it will be most likely stay but
* the signature may change between versions without warning.
*
* @since 6.7.0
*/
@Documented
public @interface Beta {
}

View File

@ -0,0 +1,18 @@
/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.annotation;
import java.lang.annotation.Documented;
/**
* Indicates the feature is in experimental state: its existence, signature or behavior
* might change without warning from one release to the next.
*
* @since 6.7.0
*/
@Documented
public @interface Experimental {
}

View File

@ -0,0 +1,25 @@
/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.annotation;
import java.lang.annotation.Documented;
/**
* Tags API members that are not publicly supported API.
* Such members may be removed, renamed, moved, or otherwise
* broken at any time and should not be relied upon outside
* of the main PMD codebase.
*
* <p>Members and types tagged with this annotation will remain
* supported until 7.0.0, after which some will be moved to internal
* packages, or will see their visibility reduced.
*
* @since 6.7.0
*/
// NOTE: use @Deprecated with this annotation to raise a compiler warning until 7.0.0
@Documented
public @interface InternalApi {
}

View File

@ -0,0 +1,37 @@
/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
/**
* Indicates that subclassing this type is not publicly
* supported API. Abstract methods may be added or removed
* at any time, which could break binary compatibility with
* existing implementors. Protected methods are also part of
* the private API of this type.
*
* <p>The API that is not inheritance-specific (unless {@linkplain InternalApi noted otherwise},
* all public members), is still public API and will remain binary-
* compatible between major releases.
*
* <p>Types tagged with this annotation will remain supported
* until 7.0.0, at which point no guarantees will be maintained
* about the stability of the inheritance hierarchy for external
* clients.
*
* <p>This should be used for example for base rule classes that
* are meant to be used in PMD only, or for AST-related interfaces
* and abstract classes.
*
* @since 6.7.0
*/
@Target(ElementType.TYPE)
@Documented
public @interface ReservedSubclassing {
}