API Javadoc tags
Certain API usage rules cannot be checked by tools because they are not formally specified in the source code. The most common example is an interface that clients are not intended to implement. It is a breaking API change to add methods to an interface that clients can implement, so it is important to be able to infer this from the API contract. Typically, this is specified in the API contract language, but not in a formal way that tools can detect. There is a PDE API Tools incubator project that is creating tooling for performing API comparisons, checking correctness of API specs, and detecting misbehaving API clients. These tools are weakened by the inability to check for certain API constraints.
The Old Solution
An earlier generation of API tools introduced the notion of a formal component description file to specify these API constraints. The problem with this approach is that the component description files are hard to keep synchronized as the API evolves because they are in a separate document. As a result, component descriptions become stale and the utility of the information is decreased.
The New Solution
The proposed new solution is to encode these API constraints directly into the API javadoc via javadoc tags. Specifically, the following tags are proposed:
- @noreference - Indicates that other bundles must not reference this member by name. I.e., the member is internal. This tag is intended to be used very rarely when a public class wants to restrict access to one of its members, but is not intended for general usage. This tag is ignored on all other members except for method declarations and non-final field declarations.
- @noimplement - Indicates that other bundles must not implement this interface. This tag is ignored for all types except for interfaces.
- @noextend - Indicates that other bundles must not extend the class or interface it appears on. This tag is ignored for all members that are not interfaces or classes.
- @noinstantiate - Indicates that other bundles must not create instances of this class. This tag is ignored for all other types that are not classes.
- @nooverride - Indicates that other bundles must not extend (re-implement with a call to the overridden parent) or re-implement (with no call to the overridden parent) this method. This tag is ignored for all other members except method declarations.
Since tags alone are not sufficient for a human reader, all such tags should be accompanied by a written javadoc contract statement that says the same thing. For example:
- @noimplement This interface is not intended to be implemented by clients.
- @noextend This class is not intended to be subclassed by clients.
The proposal is to encourage Eclipse project component owners to use these tags in their API javadoc. Use of these tags would not be required, but using the tags would allow them to take full advantage of the available API tools. For example, API tools would be able to properly suggest appropriate bundle version number changes, flag contract violations in client code, and detect breaking API contract changes.