Skip to content

Commit 5061f1f

Browse files
committed
make creation of ServiceMap and ParameterMap lazy
Currently one can not use PHPStans `bootstrapFiles` to create the container (dump) which could then be ready by `symfony.containerXmlPath`. This as the order of initialization results in the `XmlServiceMapFactory` / `XmlParameterMapFactory` `create` methods being called before the `bootstrapFiles` are executed. By making the `ServiceMap` / `ParameterMap` lazy these will only be created when actually used, which is after the `bootstrapFiles` have been executed.
1 parent f4b9407 commit 5061f1f

13 files changed

+84
-14
lines changed

extension.neon

+2-2
Original file line numberDiff line numberDiff line change
@@ -128,14 +128,14 @@ services:
128128
class: PHPStan\Symfony\ServiceMapFactory
129129
factory: PHPStan\Symfony\XmlServiceMapFactory
130130
-
131-
factory: @symfony.serviceMapFactory::create()
131+
factory: PHPStan\Symfony\LazyServiceMap
132132

133133
# parameter map
134134
symfony.parameterMapFactory:
135135
class: PHPStan\Symfony\ParameterMapFactory
136136
factory: PHPStan\Symfony\XmlParameterMapFactory
137137
-
138-
factory: @symfony.parameterMapFactory::create()
138+
factory: PHPStan\Symfony\LazyParameterMap
139139

140140
# ControllerTrait::get()/has() return type
141141
-

src/Rules/Symfony/ContainerInterfacePrivateServiceRule.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public function processNode(Node $node, Scope $scope): array
6565
return [];
6666
}
6767

68-
$serviceId = $this->serviceMap::getServiceIdFromNode($node->getArgs()[0]->value, $scope);
68+
$serviceId = $this->serviceMap->getServiceIdFromNode($node->getArgs()[0]->value, $scope);
6969
if ($serviceId !== null) {
7070
$service = $this->serviceMap->getService($serviceId);
7171
if ($service !== null && !$service->isPublic()) {

src/Rules/Symfony/ContainerInterfaceUnknownServiceRule.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public function processNode(Node $node, Scope $scope): array
6565
return [];
6666
}
6767

68-
$serviceId = $this->serviceMap::getServiceIdFromNode($node->getArgs()[0]->value, $scope);
68+
$serviceId = $this->serviceMap->getServiceIdFromNode($node->getArgs()[0]->value, $scope);
6969
if ($serviceId !== null) {
7070
$service = $this->serviceMap->getService($serviceId);
7171
$serviceIdType = $scope->getType($node->getArgs()[0]->value);

src/Symfony/DefaultParameterMap.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public function getParameter(string $key): ?ParameterDefinition
3535
return $this->parameters[$key] ?? null;
3636
}
3737

38-
public static function getParameterKeysFromNode(Expr $node, Scope $scope): array
38+
public function getParameterKeysFromNode(Expr $node, Scope $scope): array
3939
{
4040
$strings = TypeUtils::getConstantStrings($scope->getType($node));
4141

src/Symfony/DefaultServiceMap.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public function getService(string $id): ?ServiceDefinition
3434
return $this->services[$id] ?? null;
3535
}
3636

37-
public static function getServiceIdFromNode(Expr $node, Scope $scope): ?string
37+
public function getServiceIdFromNode(Expr $node, Scope $scope): ?string
3838
{
3939
$strings = TypeUtils::getConstantStrings($scope->getType($node));
4040
return count($strings) === 1 ? $strings[0]->getValue() : null;

src/Symfony/FakeParameterMap.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public function getParameter(string $key): ?ParameterDefinition
2121
return null;
2222
}
2323

24-
public static function getParameterKeysFromNode(Expr $node, Scope $scope): array
24+
public function getParameterKeysFromNode(Expr $node, Scope $scope): array
2525
{
2626
return [];
2727
}

src/Symfony/FakeServiceMap.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public function getService(string $id): ?ServiceDefinition
2121
return null;
2222
}
2323

24-
public static function getServiceIdFromNode(Expr $node, Scope $scope): ?string
24+
public function getServiceIdFromNode(Expr $node, Scope $scope): ?string
2525
{
2626
return null;
2727
}

src/Symfony/LazyParameterMap.php

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Symfony;
4+
5+
use PhpParser\Node\Expr;
6+
use PHPStan\Analyser\Scope;
7+
8+
class LazyParameterMap implements ParameterMap
9+
{
10+
11+
private ParameterMapFactory $factory;
12+
13+
private ?ParameterMap $parameterMap = null;
14+
15+
public function __construct(ParameterMapFactory $factory)
16+
{
17+
$this->factory = $factory;
18+
}
19+
20+
public function getParameters(): array
21+
{
22+
return ($this->parameterMap ??= $this->factory->create())->getParameters();
23+
}
24+
25+
public function getParameter(string $key): ?ParameterDefinition
26+
{
27+
return ($this->parameterMap ??= $this->factory->create())->getParameter($key);
28+
}
29+
30+
public function getParameterKeysFromNode(Expr $node, Scope $scope): array
31+
{
32+
return ($this->parameterMap ??= $this->factory->create())->getParameterKeysFromNode($node, $scope);
33+
}
34+
35+
}

src/Symfony/LazyServiceMap.php

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Symfony;
4+
5+
use PhpParser\Node\Expr;
6+
use PHPStan\Analyser\Scope;
7+
8+
class LazyServiceMap implements ServiceMap
9+
{
10+
11+
private ServiceMapFactory $factory;
12+
13+
private ?ServiceMap $serviceMap = null;
14+
15+
public function __construct(ServiceMapFactory $factory)
16+
{
17+
$this->factory = $factory;
18+
}
19+
20+
public function getServices(): array
21+
{
22+
return ($this->serviceMap ??= $this->factory->create())->getServices();
23+
}
24+
25+
public function getService(string $id): ?ServiceDefinition
26+
{
27+
return ($this->serviceMap ??= $this->factory->create())->getService($id);
28+
}
29+
30+
public function getServiceIdFromNode(Expr $node, Scope $scope): ?string
31+
{
32+
return ($this->serviceMap ??= $this->factory->create())->getServiceIdFromNode($node, $scope);
33+
}
34+
35+
}

src/Symfony/ParameterMap.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,6 @@ public function getParameter(string $key): ?ParameterDefinition;
1818
/**
1919
* @return array<string>
2020
*/
21-
public static function getParameterKeysFromNode(Expr $node, Scope $scope): array;
21+
public function getParameterKeysFromNode(Expr $node, Scope $scope): array;
2222

2323
}

src/Symfony/ServiceMap.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,6 @@ public function getServices(): array;
1515

1616
public function getService(string $id): ?ServiceDefinition;
1717

18-
public static function getServiceIdFromNode(Expr $node, Scope $scope): ?string;
18+
public function getServiceIdFromNode(Expr $node, Scope $scope): ?string;
1919

2020
}

src/Type/Symfony/ParameterDynamicReturnTypeExtension.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ private function getGetTypeFromMethodCall(
123123
return $defaultReturnType;
124124
}
125125

126-
$parameterKeys = $this->parameterMap::getParameterKeysFromNode($methodCall->getArgs()[0]->value, $scope);
126+
$parameterKeys = $this->parameterMap->getParameterKeysFromNode($methodCall->getArgs()[0]->value, $scope);
127127
if ($parameterKeys === []) {
128128
return $defaultReturnType;
129129
}
@@ -222,7 +222,7 @@ private function getHasTypeFromMethodCall(
222222
return $defaultReturnType;
223223
}
224224

225-
$parameterKeys = $this->parameterMap::getParameterKeysFromNode($methodCall->getArgs()[0]->value, $scope);
225+
$parameterKeys = $this->parameterMap->getParameterKeysFromNode($methodCall->getArgs()[0]->value, $scope);
226226
if ($parameterKeys === []) {
227227
return $defaultReturnType;
228228
}

src/Type/Symfony/ServiceDynamicReturnTypeExtension.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ private function getGetTypeFromMethodCall(
8888
return $returnType;
8989
}
9090

91-
$serviceId = $this->serviceMap::getServiceIdFromNode($methodCall->getArgs()[0]->value, $scope);
91+
$serviceId = $this->serviceMap->getServiceIdFromNode($methodCall->getArgs()[0]->value, $scope);
9292
if ($serviceId !== null) {
9393
$service = $this->serviceMap->getService($serviceId);
9494
if ($service !== null && (!$service->isSynthetic() || $service->getClass() !== null)) {
@@ -134,7 +134,7 @@ private function getHasTypeFromMethodCall(
134134
return $returnType;
135135
}
136136

137-
$serviceId = $this->serviceMap::getServiceIdFromNode($methodCall->getArgs()[0]->value, $scope);
137+
$serviceId = $this->serviceMap->getServiceIdFromNode($methodCall->getArgs()[0]->value, $scope);
138138
if ($serviceId !== null) {
139139
$service = $this->serviceMap->getService($serviceId);
140140
return new ConstantBooleanType($service !== null && $service->isPublic());

0 commit comments

Comments
 (0)