Problem/Motivation

Child 9 of #3624396: Plan: Harden InstanceInterface, IslandInterface and DisplayBuildableInterface as public API before RC1, the last one. Nothing in the module says what contrib may rely on. No class carries @api, and few carry @internal: 3 of 103 in the main module, 8 of 64 in the submodules. The project rule, "anything in src/ that is not a contract, base class, event, enum or attribute is internal", leaves open whether the protected members of a base class are API. Core's policy treats them as internal unless the class is @api, while an island cannot be written without them.

After RC1, every change to an unmarked class is a possible BC break.

Proposed resolution

Follow core, decision D3 of the plan:

  • @api on the classes and traits plugin authors extend, which makes their protected members supported: IslandPluginBase, DisplayBuildablePluginBase, ConfigBuildablePluginBase, IslandConfigurationFormTrait, IslandReloadEventsTrait and the two traits it uses, RenderableBuilderTrait, and IslandWithFormTrait unless #3627260: Island forms: one pattern, through PluginWithFormsInterface, with one build info retires it.
  • @api on what the API hands out or throws: the three source interfaces, InvalidNodeException, DisplayReference, PageDisplays, PublicationStatus, and ProfileIslandsUpdater for its create() and fluent methods. Its one-off beta statics are @internal: #3624068: Remove the beta update hooks at RC1, with 1.0.0-beta10 as the required stepping stone removes two of them at RC1.
  • @internal on the protected members of an @api class that are not for contrib: getPrefix(), routeExists() and instanceListUrl() of DisplayBuildablePluginBase, which #3616313: Check static methods on DisplayBuildableInterface may replace.
  • @internal on every other class in src/ and the submodules, the controller interfaces included. SourceTree too.
  • Both alter hooks documented in display_builder.api.php, beside hook_display_builder_page_displays(), under the names the plan's D7 settles.
  • docs/public-api.md lists what is supported. The rule in the module CLAUDE.md becomes "not @api is internal".
  • No BC impact, so in the same pass: ConfigBuildablePluginBase gets its services by injection rather than \Drupal::, and its private languageManager() stops shadowing the protected $languageManager.

Remaining tasks

  • Wait for children 1 to 8: this marks what they leave.
  • D4 of the plan: what stays of SseState and HtmxEvents, and whether they are API.
  • D7 of the plan: the names of the alter hook and of the island plugin manager service.

User interface changes

None.

API changes

The supported API is declared: @api where contrib may rely on it, @internal everywhere else. No code behavior changes.

Data model changes

None.

Comments

mogtofu33 created an issue. See original summary.

pdureau’s picture

If it is a RC blocker, it must no be postponed.

pdureau’s picture

Status: Postponed » Active