From dcc5510545c5b9b6817aa71a3154787badb49916 Mon Sep 17 00:00:00 2001 From: "Giuseppe.Esposito" Date: Fri, 6 Nov 2026 21:50:17 +0100 Subject: [PATCH] Roadmap items for unknown plugin IDs and annotation class names Assisted-by: claude-code/claude-opus-5-5 --- docs/todo.md | 2 ++ docs/todo/bugs.md | 34 +++++++++++++++++++++++++++++++++ docs/todo/drupal.md | 46 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 82 insertions(+) diff --git a/docs/todo.md b/docs/todo.md index ec2bf4ca4..490d36565 100644 --- a/docs/todo.md +++ b/docs/todo.md @@ -141,6 +141,8 @@ ships, remove every row that names it. | DR22 | [Complete permissions built in code](todo/drupal.md#dr22-complete-permissions-built-in-code) | Low-Medium | Medium | | DR23 | [Warn on unknown permission names](todo/drupal.md#dr23-warn-on-unknown-permission-names) | Medium | Low-Medium | | DR24 | [Warn on unknown theme hook names](todo/drupal.md#dr24-warn-on-unknown-theme-hook-names) | Low-Medium | Medium-High | +| DR25 | [Warn on unknown plugin IDs](todo/drupal.md#dr25-warn-on-unknown-plugin-ids) | Medium | Low-Medium | +| DR26 | [Annotation class names](todo/drupal.md#dr26-annotation-class-names) | Low-Medium | Low-Medium | ## Yii diff --git a/docs/todo/bugs.md b/docs/todo/bugs.md index 8e7c2e036..859cc39a3 100644 --- a/docs/todo/bugs.md +++ b/docs/todo/bugs.md @@ -150,6 +150,40 @@ resolves, and so does every name once the whole project is indexed (as the imports from `import_block_at`, and how a file loaded on demand records its `use` map in its `FileState`. +### B707. A docblock annotation does not name its class + +**Impact: Medium · Complexity: Low-Medium** + +```php +use Doctrine\ORM\Mapping as ORM; // Unused import 'Doctrine\ORM\Mapping' +use Symfony\Component\Routing\Annotation\Route; // Unused import + +/** @ORM\Entity */ +final class User +{ + /** @Route("/users") */ + public function list(): Response { … } +} +``` + +Doctrine-style annotations (Doctrine ORM, older Symfony, JMS, Drupal +plugins) name a class with their tag, resolved through the file's `use` +imports like any other class name. The tag is read as an unknown docblock +tag instead, so an import only an annotation uses is reported as unused, +and the quick fix and `phpantom_lsp fix` remove it, which breaks the +annotation at run time. Go-to-definition, hover, references and rename +miss the class too. + +Record an annotation tag (`@` then a name, at the start of a docblock +line or inside another annotation's arguments) as a class reference when +its name resolves to a class, the way a docblock type is. A tag PHPDoc +or a tool defines (`@param`, `@phpstan-*`, `@psalm-*`) is never one, and +a lowercase tag with no class behind it stays silent. + +**Where to look:** `extract_docblock_symbols` (`src/symbol_map/docblock.rs`), +which emits the class references `unused_imports.rs` and the navigation +features read. + ## Code actions No outstanding items. diff --git a/docs/todo/drupal.md b/docs/todo/drupal.md index 060f0e19f..b9e030e02 100644 --- a/docs/todo/drupal.md +++ b/docs/todo/drupal.md @@ -354,3 +354,49 @@ implementation cannot be read, would silence every site. Report a name only once those hooks are read, or with a rule that knows which names such an implementation can add. A suggestion such as `acme_greeting__compact` is valid when its base hook is. + +--- + +## DR25. Warn on unknown plugin IDs + +**Impact: Medium · Complexity: Low-Medium** + +```php +$fields['total'] = BaseFieldDefinition::create('decimel'); +$block = $this->blockManager->createInstance('acme_order_sumary'); +``` + +A plugin ID that no plugin of its type declares is a typo or a module the +site lacks. The plugin manager throws for it, except for widgets and +formatters, which silently fall back to the field type's default. Report +one wherever [DR10](#dr10-plugin-ids) reads plugin IDs: field types, +widgets and formatters, constraints, and a plugin manager's +`createInstance()`. A derivative ID (`system_menu_block:main`) is known +only at run time, so an ID whose base plugin has a deriver must not +warn. This depends on DR10. + +--- + +## DR26. Annotation class names + +**Impact: Low-Medium · Complexity: Low-Medium** + +```php +/** + * @Block( + * id = "acme_order_summary", + * admin_label = @Translation("Order summary"), + * ) + */ +final class OrderSummaryBlock extends BlockBase { … } +``` + +Plugins written before Drupal 10.2 declare themselves in a docblock +annotation, and many contributed modules still do. `@Block` and +`@Translation` name annotation classes, but Drupal's annotated plugin +discovery finds them without a `use` import: it reads a plugin type's +annotation class and namespaces from its plugin manager, not from the +file. Once [B707](bugs.md#b707-a-docblock-annotation-does-not-name-its-class) +reads annotations through the imports, resolve a name the imports don't +cover through the namespaces of the plugin type the class is discovered +for, so that go-to-definition, hover, and references reach the class.