rector/packages/NodeTypeResolver/DependencyInjection/PHPStanServicesFactory.php

139 lines
5.1 KiB
PHP
Raw Normal View History

2019-10-13 05:59:52 +00:00
<?php
declare (strict_types=1);
2022-06-06 16:43:29 +00:00
namespace RectorPrefix20220606\Rector\NodeTypeResolver\DependencyInjection;
2022-06-06 16:43:29 +00:00
use RectorPrefix20220606\PhpParser\Lexer;
use RectorPrefix20220606\PHPStan\Analyser\NodeScopeResolver;
use RectorPrefix20220606\PHPStan\Analyser\ScopeFactory;
use RectorPrefix20220606\PHPStan\Dependency\DependencyResolver;
use RectorPrefix20220606\PHPStan\DependencyInjection\Container;
use RectorPrefix20220606\PHPStan\DependencyInjection\ContainerFactory;
use RectorPrefix20220606\PHPStan\ExtensionInstaller\GeneratedConfig;
use RectorPrefix20220606\PHPStan\File\FileHelper;
use RectorPrefix20220606\PHPStan\Parser\Parser;
use RectorPrefix20220606\PHPStan\PhpDoc\TypeNodeResolver;
use RectorPrefix20220606\PHPStan\Reflection\ReflectionProvider;
use RectorPrefix20220606\Rector\Core\Configuration\Option;
use RectorPrefix20220606\Rector\Core\Exception\ShouldNotHappenException;
use RectorPrefix20220606\Rector\NodeTypeResolver\Reflection\BetterReflection\SourceLocatorProvider\DynamicSourceLocatorProvider;
use ReflectionClass;
use RectorPrefix20220606\Symplify\PackageBuilder\Parameter\ParameterProvider;
/**
* Factory so Symfony app can use services from PHPStan container
*/
final class PHPStanServicesFactory
{
/**
* @readonly
* @var \PHPStan\DependencyInjection\Container
*/
private $container;
2022-06-06 16:43:29 +00:00
public function __construct(ParameterProvider $parameterProvider)
{
2022-06-06 16:43:29 +00:00
$containerFactory = new ContainerFactory(\getcwd());
$additionalConfigFiles = [];
2022-06-06 16:43:29 +00:00
if ($parameterProvider->hasParameter(Option::PHPSTAN_FOR_RECTOR_PATH)) {
$additionalConfigFiles[] = $parameterProvider->provideStringParameter(Option::PHPSTAN_FOR_RECTOR_PATH);
}
$additionalConfigFiles[] = __DIR__ . '/../../../config/phpstan/static-reflection.neon';
$additionalConfigFiles[] = __DIR__ . '/../../../config/phpstan/better-infer.neon';
$additionalConfigFiles[] = __DIR__ . '/../../../config/phpstan/parser.neon';
$extensionConfigFiles = $this->resolveExtensionConfigs();
$additionalConfigFiles = \array_merge($additionalConfigFiles, $extensionConfigFiles);
$existingAdditionalConfigFiles = \array_filter($additionalConfigFiles, 'file_exists');
$this->container = $containerFactory->create(\sys_get_temp_dir(), $existingAdditionalConfigFiles, []);
}
2020-03-28 23:06:05 +00:00
/**
* @api
*/
2022-06-06 16:43:29 +00:00
public function createReflectionProvider() : ReflectionProvider
{
2022-06-06 16:43:29 +00:00
return $this->container->getByType(ReflectionProvider::class);
}
/**
* @api
*/
2022-06-06 16:43:29 +00:00
public function createEmulativeLexer() : Lexer
{
return $this->container->getService('currentPhpVersionLexer');
}
/**
* @api
*/
2022-06-06 16:43:29 +00:00
public function createPHPStanParser() : Parser
{
return $this->container->getService('currentPhpVersionRichParser');
}
2020-03-28 23:06:05 +00:00
/**
* @api
*/
2022-06-06 16:43:29 +00:00
public function createNodeScopeResolver() : NodeScopeResolver
{
2022-06-06 16:43:29 +00:00
return $this->container->getByType(NodeScopeResolver::class);
}
2020-03-28 23:06:05 +00:00
/**
* @api
*/
2022-06-06 16:43:29 +00:00
public function createScopeFactory() : ScopeFactory
{
2022-06-06 16:43:29 +00:00
return $this->container->getByType(ScopeFactory::class);
}
2020-04-01 01:55:44 +00:00
/**
* @api
*/
2022-06-06 16:43:29 +00:00
public function createDependencyResolver() : DependencyResolver
2020-04-01 01:55:44 +00:00
{
2022-06-06 16:43:29 +00:00
return $this->container->getByType(DependencyResolver::class);
2020-04-01 01:55:44 +00:00
}
/**
* @api
*/
2022-06-06 16:43:29 +00:00
public function createFileHelper() : FileHelper
2020-04-01 01:55:44 +00:00
{
2022-06-06 16:43:29 +00:00
return $this->container->getByType(FileHelper::class);
2020-04-01 01:55:44 +00:00
}
2020-03-28 23:06:05 +00:00
/**
* @api
*/
2022-06-06 16:43:29 +00:00
public function createTypeNodeResolver() : TypeNodeResolver
{
2022-06-06 16:43:29 +00:00
return $this->container->getByType(TypeNodeResolver::class);
}
/**
* @api
*/
2022-06-06 16:43:29 +00:00
public function createDynamicSourceLocatorProvider() : DynamicSourceLocatorProvider
{
2022-06-06 16:43:29 +00:00
return $this->container->getByType(DynamicSourceLocatorProvider::class);
}
/**
* @return string[]
*/
private function resolveExtensionConfigs() : array
{
// same logic as in PHPStan for extension installed - https://github.com/phpstan/phpstan-src/blob/5956ec4f6cd09c8d7db9466ed4e7f25706f37a43/src/Command/CommandHelper.php#L195-L222
2022-06-06 16:43:29 +00:00
if (!\class_exists(GeneratedConfig::class)) {
return [];
}
2022-06-06 16:43:29 +00:00
$reflectionClass = new ReflectionClass(GeneratedConfig::class);
$generatedConfigClassFileName = $reflectionClass->getFileName();
if ($generatedConfigClassFileName === \false) {
2022-06-06 16:43:29 +00:00
throw new ShouldNotHappenException();
}
$generatedConfigDirectory = \dirname($generatedConfigClassFileName);
$extensionConfigFiles = [];
2022-06-06 16:43:29 +00:00
foreach (GeneratedConfig::EXTENSIONS as $extension) {
$fileNames = $extension['extra']['includes'] ?? [];
foreach ($fileNames as $fileName) {
$configFilePath = $generatedConfigDirectory . '/' . $extension['relative_install_path'] . '/' . $fileName;
if (!\file_exists($configFilePath)) {
continue;
}
$extensionConfigFiles[] = $configFilePath;
}
}
return $extensionConfigFiles;
}
}