Stable interface policy

This stable interface policy defines which parts of the PHP code in MediaWiki core (mediawiki/core.git) can be considered stable and safe for use by extensions and other code outside the core module. Any code that is part of the stable interface is subject to the deprecation policy. Any code that is not part of the stable interface is subject to change without notice.

The motivation for this policy is two-fold: On the one hand, it offers guarantees to extension developers, providing guidance on what aspects of MediaWiki core they can safely rely upon. On the other hand, it provides guarantees to developers working on MediaWiki core, telling them what aspects of the code they can safely change without having to worry about breaking extensions.

Through this, this policy is designed to make extensions more robust against changes in MediaWiki core, and provide more freedom for the core code to evolve.

Principles and Recommendations
Code outside of MediaWiki core, in particular in extensions, should consider the following principles and recommendations:


 * It's generally safe for extensions to call public methods and access public fields in classes defined by MediaWiki core, unless these methods are documented to be unsafe (e.g. annotated with @deprecated or @unstable or @internal).
 * It's generally unsafe for extensions to extend (subclass) a class or implement an interface defined by MediaWiki core, unless that class or interface was designated to be safe for that purpose. In particular, the constructor signature may change, and abstract methods may be added. Thus, extensions should not implement interfaces, extend classes, or override methods, unless annotated with @fixed or @extensible.
 * It's generally unsafe for extensions to directly instantiate (using new) a class defined by MediaWiki core, unless that class is designated to be safe for this purpose. Thus, extensions should not directly create instances of classes that do not have the @newable annotation.
 * It's generally unsafe for extensions to rely on global variables. Static methods such as MediaWikiServices::getInstance should be used instead.

Code in MediaWiki core the provides extension points should consider the following principles and recommendations, in order to provide extensions with a stable interface without removing flexibility from the code in core:


 * MediaWiki extension points should use base classes marked with the @extensible annotation. Any methods to be implemented or overwritten should be explicitly marked as @fixed to indicate that their signature will not change in an incompatible way.
 * Base classes are preferred over interfaces as extension points. MediaWiki extension points may also use PHP interfaces if these are marked with the @fixed annotation. This however means that no method can ever be added to them, since that would break any extension implementing the interface.
 * Pure value objects defined by MediaWiki should be marked with the @newable annotation if extensions would benefit from being able to construct such objects directly. The constructor of a @newable class should be marked as @stable.
 * For objects that extensions may need to instantiate, but which for which a stable constructor cannot be guaranteed, a factory service should be provided . This is especially true for objects that may in the future need to have a service instance injected.

Definition of the Stable Interface
The following is considered part of the stable interface, and therefore subject to this deprecation policy, after having been present in at least one release of MediaWiki:


 * Global functions with the "wf" prefix, unless declared otherwise using the annotation tags defined below.
 * All public methods and fields, for calling, unless declared otherwise using the annotation tags defined below. This does not include methods and fields that are lacking any access modifiers. This does not guarantee public methods to be stable for overriding.
 * All documented hooks, unless declared otherwise using the annotation tags defined below.
 * Any code explicitly documented to be part of the stable interface, especially when annotated with the @stable, @fixed, @extensible or @newable tags, to the extent defined below for each of these tags.

In contrast, the following things are not part of the stable interface, and are therefore subject to change without notice:
 * Protected methods and fields, unless the class is marked as an extension point using the @extensible annotation.
 * Method signatures as needed for overriding, unless the method is marked with the @fixed annotation.
 * Constructor signatures, unless marked as stable for calling using the @stable annotation. Stable constructor signatures can also be assumed for classes marked @extensible or @newable.
 * Interface signatures, unless the interface is marked to be safe for implementation using the @fixed or @extensible annotation. This means that extensions should not directly implement interfaces that are not documented to be safe for this purpose. An extensible base class should be provided for the use of extensions instead.
 * Global variables, including those with the "wg" prefix. MediaWikiServices should be used as an entry point that provides access to service objects and configuration instead.
 * Methods and fields lacking explicit access modifiers. Access modifiers should be added to such methods as soon as possible, according to their current usage in extensions.
 * Any code explicitly documented to be unstable or internal, particularly when annotated with the tags @deprecated, @internal, @unstable, or @experimental.

Annotations
As described above, the following defaults apply:


 * Public methods of classes and interfaces are considered stable unless marked with @deprecated, @internal, or @unstable. They are however considered not fixed, meaning they are not safe to override.
 * Protected methods are considered unstable unless marked with @stable or @fixed.
 * Constructor signatures are considered unstable unless marked with @stable or @fixed.
 * Signatures of interfaces are considered not fixed unless the interface is marked with @fixed. Methods and optional arguments may be added without notice.
 * Similarly, the set of required abstract methods is considered unstable unless the class is marked with @extensible (@stable does not suffice). Methods and optional arguments may be added without notice.

The following annotations can be used to depart from the defaults above,

to remove guarantees:


 * @deprecated: do not use outside the module, may be removed following the procedure defined by the deprecation policy. Should always be accompanied by instructions of what to use instead.
 * @internal: do not use outside the module, subject to change without notice. Same as @unstable, except that internal typically stays internal.
 * @unstable: do not use outside the module, subject to change without notice. Same as @internal, except that unstable things are intended to become stable in the future.
 * @experimental: same as @unstable.

to add guarantees:


 * @stable: backwards compatibility will be maintained for calls; changes that impact callers are subject to the deprecation policy. This applies to the function's or method's contract as well as its signature. Note that a method can only safely be overridden if it is declared to be fixed, being stable is not sufficient.
 * @fixed: backwards compatibility will be maintained for calls, overriding, implementing, and subclassing; thus, only very limited changes to signatures are possible. All such changes are subject to the deprecation policy. Applicable to the signatures and contracts of public and protected methods as well as entire interfaces. Only fixed interfaces are safe to implement outside the module, only fixed methods are safe to be overwritten.
 * @extensible: class is safe to subclass; changes affecting subclasses will be done in a backwards compatible way. This implies that the constructor is stable, and no abstract methods can be added. Note that only methods declared to be fixed can be overwritten safely. If applied to an interface, @extensible should be considered to mean the same as @fixed, to avoid confusion. Constructors of extensible classes should be marked as @stable for clarity.
 * @newable: The class is safe to be instantiated. This implies that the constructor is stable. Generally, only plain value objects should be newable, since any other kind of object may require dependency injection.

Stable interfaces up to MediaWiki 1.34
''The following definition of stable interfaces, as given on the deprecation policy page, is applicable to MediaWiki up to version 1.34. Staring with version 1.35, the more restrictive policy above applies. With the release of MediaWiki 1.35, this section becomes obsolete and should be removed.''

The stable part of the PHP API is comprised of all code in MediaWiki core (mediawiki/core.git) codebase that is explicitly marked public, and has been included in at least one stable release. In addition, some classes expect to be subclassed in extensions; in those cases protected functions also are included in the API. These classes should have a note in their documentation comment that they expect subclassing. If no note is present, it SHOULD be assumed that the class is not expected to be subclassed. Hooks are considered part of the PHP API.

Note: Typically PHP code would use private or final, however those are not supported by PHPUnit's mocking features, and as a result not really used in MediaWiki code.

Classes and/or functions with public visibility MAY also have,   or   annotations to indicate they are not stable interfaces that SHOULD NOT be depended upon.

Some legacy code may not have any visibility modifiers, in which case it is not considered to be part of the stable, public interface. Developers SHOULD add visibility modifiers as soon as possible, and use judgement when making this code protected or private. Where known users exist, developers should still consider following the full deprecation process. New code MUST have explicit visiblity set on all properties and functions.