You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 8b7d263
Browse filesBrowse the repository at this point in the historyBrowse files
Register services from DI attributes found in configured directories
PHPStan's dependency injection attributes were only usable from
phpstan-src itself. They are collected at composer install time into
vendor/attributes.php, which only ever covers phpstan-src's own src
directory, and inside the PHAR the collector lives under a
build-specific namespace prefix. Extensions shipped as separate
packages therefore had no way in, and had to list every rule, type
extension and collector by hand in a services: section.
Add an autowiredServiceDirectories parameter. Each configuration file
contributes its own directories, and because the parameter is a list
the entries merge rather than overwrite, so one extension adding to it
cannot hide another's classes. AutowiredServiceDiscoverer scans those
directories, using the bundled parser only as a filter for classes
carrying a known attribute, then reflects on the survivors to build the
same TargetClass and TargetMethodParameter objects the collector
produces. The compiler extensions merge both sources, so discovered
classes go through the existing registration paths unchanged, including
the auto-tagging derived from #[ExtensionInterface].
The scanned files feed the container cache key - otherwise editing a
discovered rule would keep being served from the cached container.
Parsing is deferred to the first attribute lookup, so a container that
never asks does no work beyond listing the files, and the pre-filter
matches the namespace the attributes live in rather than their names,
which is both a single needle per file and immune to grouped or
aliased use statements.
getInterfaceTagMapping() now takes the ContainerBuilder, since the
mapping depends on the configured directories and two containers in
one process can disagree about them. Hoist its result out of the loop
over autowired services in AutowiredAttributeServicesExtension: it used
to be a free static memo, and calling it per service would otherwise
re-derive the discoverer several hundred times per compile.
#[ContainerExtension] is rejected with an explicit message. Nette
snapshots its extension list before any of this runs, so compiler
extensions still need an extensions: section.
Mark the attributes extensions are now expected to reach for as @api.
if (strcasecmp($parameter->method, '__construct') !== 0) {
61
66
thrownewShouldNotHappenException(sprintf('Attribute #[AutowiredExtensions] is only supported on constructor parameters, found on %s::%s() $%s.', $parameter->class, $parameter->method, $parameter->name));
0 commit comments