Skip to content

Commit 58abfa6

Browse files
committed
Clean up service map and remove legacy extension
1 parent 04185f6 commit 58abfa6

14 files changed

+99
-213
lines changed

extension.neon

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,13 @@ parameters:
1212
- profile
1313
- engine
1414
drupal:
15-
serviceMap: {}
1615
entityTypeStorageMapping:
1716
node: Drupal\node\NodeStorage
1817
taxonomy_term: Drupal\taxonomy\TermStorage
1918
user: Drupal\user\UserStorage
2019
parametersSchema:
2120
drupal: structure([
2221
drupal_root: string()
23-
serviceMap: listOf(string())
2422
entityTypeStorageMapping: arrayOf(string())
2523
])
2624
rules:
@@ -30,11 +28,9 @@ rules:
3028
- PHPStan\Rules\Drupal\PluginManager\PluginManagerSetsCacheBackendRule
3129
- PHPStan\Rules\Deprecations\AccessDeprecatedConstant
3230
services:
33-
drupal.serviceMapFactory:
34-
class: PHPStan\Drupal\ServiceMapFactory
35-
factory: PHPStan\Drupal\ServiceMapFactory(%drupal.serviceMap%)
3631
-
37-
factory: @drupal.serviceMapFactory::create()
32+
class: PHPStan\Drupal\ServiceMap
33+
3834
-
3935
class: PHPStan\Type\EntityTypeManagerGetStorageDynamicReturnTypeExtension
4036
arguments:

phpstan.neon

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@ includes:
33
- vendor/phpstan/phpstan-deprecation-rules/rules.neon
44
parameters:
55
level: 7
6+
checkGenericClassInNonGenericObjectType: false
7+
checkMissingIterableValueType: false

src/DependencyInjection/DrupalExtension.php

Lines changed: 0 additions & 146 deletions
This file was deleted.

src/Drupal/DrupalAutoloader.php

Lines changed: 70 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,10 @@
66
use DrupalFinder\DrupalFinder;
77
use Nette\Utils\Finder;
88
use PHPStan\DependencyInjection\Container;
9+
use Symfony\Component\Yaml\Yaml;
910

1011
class DrupalAutoloader
1112
{
12-
/**
13-
* @var array
14-
*/
15-
protected $defaultConfig = [
16-
'modules' => [],
17-
'themes' => [],
18-
];
1913

2014
/**
2115
* @var \Composer\Autoload\ClassLoader
@@ -42,14 +36,19 @@ class DrupalAutoloader
4236
protected $themeData = [];
4337

4438
/**
45-
* @var array
39+
* @var array<array<string, string>>
4640
*/
47-
private $modules = [];
41+
private $serviceMap = [];
4842

4943
/**
50-
* @var array
44+
* @var array<string, string>
5145
*/
52-
private $themes = [];
46+
private $serviceYamls = [];
47+
48+
/**
49+
* @var array<string, string>
50+
*/
51+
private $serviceClassProviders = [];
5352

5453
/**
5554
* @var ?\PHPStan\Drupal\ExtensionDiscovery
@@ -88,6 +87,10 @@ public function register(Container $container): void
8887

8988
$this->autoloader = include $drupalVendorRoot . '/autoload.php';
9089

90+
$this->serviceYamls['core'] = $drupalRoot . '/core/core.services.yml';
91+
$this->serviceClassProviders['core'] = '\Drupal\Core\CoreServiceProvider';
92+
$this->serviceMap['service_provider.core.service_provider'] = ['class' => $this->serviceClassProviders['core']];
93+
9194
$this->extensionDiscovery = new ExtensionDiscovery($this->drupalRoot);
9295
$this->extensionDiscovery->setProfileDirectories([]);
9396
$profiles = $this->extensionDiscovery->scan('profile');
@@ -156,6 +159,45 @@ public function register(Container $container): void
156159
}
157160
}
158161
}
162+
163+
foreach ($this->serviceYamls as $extension => $serviceYaml) {
164+
$yaml = Yaml::parseFile($serviceYaml);
165+
// Weed out service files which only provide parameters.
166+
if (!isset($yaml['services']) || !is_array($yaml['services'])) {
167+
continue;
168+
}
169+
foreach ($yaml['services'] as $serviceId => $serviceDefinition) {
170+
// Prevent \Nette\DI\ContainerBuilder::completeStatement from array_walk_recursive into the arguments
171+
// and thinking these are real services for PHPStan's container.
172+
if (isset($serviceDefinition['arguments']) && is_array($serviceDefinition['arguments'])) {
173+
array_walk($serviceDefinition['arguments'], function (&$argument) : void {
174+
if (is_array($argument)) {
175+
// @todo fix for @http_kernel.controller.argument_metadata_factory
176+
$argument = '';
177+
} else {
178+
$argument = str_replace('@', '', $argument);
179+
}
180+
});
181+
}
182+
// @todo sanitize "calls" and "configurator" and "factory"
183+
/**
184+
jsonapi.params.enhancer:
185+
class: Drupal\jsonapi\Routing\JsonApiParamEnhancer
186+
calls:
187+
- [setContainer, ['@service_container']]
188+
tags:
189+
- { name: route_enhancer }
190+
*/
191+
unset($serviceDefinition['tags'], $serviceDefinition['calls'], $serviceDefinition['configurator'], $serviceDefinition['factory']);
192+
$this->serviceMap[$serviceId] = $serviceDefinition;
193+
}
194+
}
195+
196+
$service_map = $container->getByType(ServiceMap::class);
197+
assert($service_map instanceof ServiceMap);
198+
// @todo this is not updating the reference in the container.
199+
$service_map->setDrupalServices($this->serviceMap);
200+
159201
}
160202

161203
protected function loadLegacyIncludes(): void
@@ -216,6 +258,18 @@ protected function addModuleNamespaces(): void
216258
}
217259
}
218260
}
261+
262+
$servicesFileName = $module_dir . '/' . $module_name . '.services.yml';
263+
if (file_exists($servicesFileName)) {
264+
$this->serviceYamls[$module_name] = $servicesFileName;
265+
}
266+
$camelized = $this->camelize($module_name);
267+
$name = "{$camelized}ServiceProvider";
268+
$class = "Drupal\\{$module_name}\\{$name}";
269+
270+
$this->serviceClassProviders[$module_name] = $class;
271+
$serviceId = "service_provider.$module_name.service_provider";
272+
$this->serviceMap[$serviceId] = ['class' => $class];
219273
}
220274
}
221275
protected function addThemeNamespaces(): void
@@ -261,4 +315,9 @@ protected function loadAndCatchErrors(string $path): void
261315
@trigger_error("$path failed loading due to {$e->getMessage()}", E_USER_WARNING);
262316
}
263317
}
318+
319+
protected function camelize(string $id): string
320+
{
321+
return strtr(ucwords(strtr($id, ['_' => ' ', '.' => '_ ', '\\' => '_ '])), [' ' => '']);
322+
}
264323
}

src/Drupal/ServiceMap.php

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@ class ServiceMap
77
/** @var \PHPStan\Drupal\DrupalServiceDefinition[] */
88
private $services;
99

10-
/**
11-
* ServiceMap constructor.
12-
* @param array $drupalServices
13-
*/
14-
public function __construct(array $drupalServices)
10+
public function getService(string $id): ?DrupalServiceDefinition
11+
{
12+
return $this->services[$id] ?? null;
13+
}
14+
15+
public function setDrupalServices(array $drupalServices): void
1516
{
1617
$this->services = [];
1718

@@ -32,9 +33,4 @@ public function __construct(array $drupalServices)
3233
);
3334
}
3435
}
35-
36-
public function getService(string $id): ?DrupalServiceDefinition
37-
{
38-
return $this->services[$id] ?? null;
39-
}
4036
}

src/Drupal/ServiceMapFactory.php

Lines changed: 0 additions & 21 deletions
This file was deleted.

src/Drupal/ServiceMapFactoryInterface.php

Lines changed: 0 additions & 8 deletions
This file was deleted.

src/Rules/Classes/PluginManagerInspectionRule.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ private function inspectYamlPluginManager(Node\Stmt\Class_ $class): array
9898
{
9999
$errors = [];
100100

101-
$fqn = (string)$class->namespacedName;
101+
$fqn = $class->namespacedName;
102102
$reflection = new \ReflectionClass($fqn);
103103
$constructor = $reflection->getConstructor();
104104

src/Rules/Deprecations/AccessDeprecatedConstant.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use PHPStan\Analyser\Scope;
77
use PHPStan\Broker\Broker;
88
use PHPStan\Reflection\DeprecatableReflection;
9+
use PHPStan\Reflection\FunctionReflection;
910

1011
class AccessDeprecatedConstant implements \PHPStan\Rules\Rule
1112
{
@@ -33,7 +34,7 @@ public function processNode(Node $node, Scope $scope): array
3334
return [];
3435
}
3536
$function = $scope->getFunction();
36-
if ($function instanceof DeprecatableReflection && $function->isDeprecated()) {
37+
if ($function instanceof FunctionReflection && $function->isDeprecated()->yes()) {
3738
return [];
3839
}
3940

0 commit comments

Comments
 (0)