diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 9a763720..7e50016c 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -22,8 +22,6 @@ parameters: path: 'src/PhpParser/NodeVisitor/Resolver/OriginalNameResolver.php' - message: '#NamespaceManipulator::getOriginalName\(\) should return#' path: 'src/PhpParser/NodeVisitor/NamespaceStmt/NamespaceManipulator.php' - - message: '#DummyScoperFactory extends @final#' - path: 'tests/Console/Command/DummyScoperFactory.php' - message: '#Anonymous function should return string but returns array#' path: 'tests/Console/Command/AddPrefixCommandIntegrationTest.php' - message: '#AddPrefixCommandIntegrationTest\:\:getNormalizeDisplay\(\) should return string but returns array#' @@ -63,3 +61,5 @@ parameters: # Fixed in https://github.com/nikic/PHP-Parser/pull/1003 - message: '#Standard constructor expects array#' path: 'src/Container.php' + - message: '#Standard constructor expects array#' + path: 'src/PhpParser/Printer/StandardPrinterFactory.php' diff --git a/src/Console/Command/AddPrefixCommand.php b/src/Console/Command/AddPrefixCommand.php index 390c3f5c..21c82acd 100644 --- a/src/Console/Command/AddPrefixCommand.php +++ b/src/Console/Command/AddPrefixCommand.php @@ -27,7 +27,7 @@ use Humbug\PhpScoper\Configuration\Throwable\UnknownConfigurationKey; use Humbug\PhpScoper\Console\ConfigLoader; use Humbug\PhpScoper\Console\ConsoleScoper; -use Humbug\PhpScoper\Scoper\ScoperFactory; +use Humbug\PhpScoper\Scoper\Factory\ScoperFactory; use InvalidArgumentException; use Symfony\Component\Console\Exception\RuntimeException; use Symfony\Component\Console\Input\InputArgument; diff --git a/src/Console/Command/InspectCommand.php b/src/Console/Command/InspectCommand.php index 82d079d4..0735e786 100644 --- a/src/Console/Command/InspectCommand.php +++ b/src/Console/Command/InspectCommand.php @@ -23,7 +23,7 @@ use Humbug\PhpScoper\Configuration\Configuration; use Humbug\PhpScoper\Configuration\ConfigurationFactory; use Humbug\PhpScoper\Console\ConfigLoader; -use Humbug\PhpScoper\Scoper\ScoperFactory; +use Humbug\PhpScoper\Scoper\Factory\ScoperFactory; use Humbug\PhpScoper\Symbol\SymbolsRegistry; use InvalidArgumentException; use Symfony\Component\Console\Input\InputArgument; diff --git a/src/Console/ConsoleScoper.php b/src/Console/ConsoleScoper.php index f354e4fb..57b66430 100644 --- a/src/Console/ConsoleScoper.php +++ b/src/Console/ConsoleScoper.php @@ -19,8 +19,8 @@ use Humbug\PhpScoper\Autoload\ComposerFileHasher; use Humbug\PhpScoper\Autoload\ScoperAutoloadGenerator; use Humbug\PhpScoper\Configuration\Configuration; +use Humbug\PhpScoper\Scoper\Factory\ScoperFactory; use Humbug\PhpScoper\Scoper\Scoper; -use Humbug\PhpScoper\Scoper\ScoperFactory; use Humbug\PhpScoper\Symbol\SymbolsRegistry; use Humbug\PhpScoper\Throwable\Exception\ParsingException; use Symfony\Component\Filesystem\Filesystem; diff --git a/src/Container.php b/src/Container.php index 61dac2aa..46f7553c 100644 --- a/src/Container.php +++ b/src/Container.php @@ -17,16 +17,17 @@ use Humbug\PhpScoper\Configuration\ConfigurationFactory; use Humbug\PhpScoper\Configuration\RegexChecker; use Humbug\PhpScoper\Configuration\SymbolsConfigurationFactory; +use Humbug\PhpScoper\PhpParser\Parser\ParserFactory; +use Humbug\PhpScoper\PhpParser\Parser\StandardParserFactory; use Humbug\PhpScoper\PhpParser\Printer\Printer; +use Humbug\PhpScoper\PhpParser\Printer\PrinterFactory; use Humbug\PhpScoper\PhpParser\Printer\StandardPrinter; -use Humbug\PhpScoper\Scoper\ScoperFactory; +use Humbug\PhpScoper\PhpParser\Printer\StandardPrinterFactory; +use Humbug\PhpScoper\Scoper\Factory\ScoperFactory; +use Humbug\PhpScoper\Scoper\Factory\StandardScoperFactory; use Humbug\PhpScoper\Symbol\EnrichedReflectorFactory; use Humbug\PhpScoper\Symbol\Reflector; -use PhpParser\Lexer; -use PhpParser\Lexer\Emulative; use PhpParser\Parser; -use PhpParser\Parser\Php7; -use PhpParser\Parser\Php8; use PhpParser\PhpVersion; use PhpParser\PrettyPrinter\Standard; use Symfony\Component\Filesystem\Filesystem; @@ -36,12 +37,14 @@ final class Container { private Filesystem $filesystem; private ConfigurationFactory $configFactory; + private ParserFactory $parserFactory; private Parser $parser; private ?PhpVersion $parserPhpVersion = null; private ?PhpVersion $printerPhpVersion = null; private Reflector $reflector; private ScoperFactory $scoperFactory; private EnrichedReflectorFactory $enrichedReflectorFactory; + private PrinterFactory $printerFactory; private Printer $printer; public function getFileSystem(): Filesystem @@ -67,24 +70,27 @@ public function getConfigurationFactory(): ConfigurationFactory return $this->configFactory; } - public function getScoperFactory(?PhpVersion $phpVersion = null): ScoperFactory + public function getScoperFactory(): ScoperFactory { if (!isset($this->scoperFactory)) { - $this->scoperFactory = new ScoperFactory( - $this->getParser($phpVersion), + $this->scoperFactory = new StandardScoperFactory( $this->getEnrichedReflectorFactory(), - $this->getPrinter(), + $this->getParserFactory(), + $this->getPrinterFactory(), ); } return $this->scoperFactory; } + /** + * @deprecated Use ::getParserFactory() instead. + */ public function getParser(?PhpVersion $phpVersion = null): Parser { if (!isset($this->parser)) { $this->parserPhpVersion = $phpVersion; - $this->parser = $this->createParser($phpVersion); + $this->parser = $this->getParserFactory()->createParser($phpVersion); } self::checkSamePhpVersion($this->parserPhpVersion, $phpVersion); @@ -92,14 +98,13 @@ public function getParser(?PhpVersion $phpVersion = null): Parser return $this->parser; } - private function createParser(?PhpVersion $phpVersion): Parser + public function getParserFactory(): ParserFactory { - $version = $phpVersion ?? PhpVersion::getHostVersion(); - $lexer = $version->isHostVersion() ? new Lexer() : new Emulative($version); + if (!isset($this->parserFactory)) { + $this->parserFactory = new StandardParserFactory(); + } - return $version->id >= 80_000 - ? new Php8($lexer, $version) - : new Php7($lexer, $version); + return $this->parserFactory; } public function getReflector(): Reflector @@ -122,6 +127,9 @@ public function getEnrichedReflectorFactory(): EnrichedReflectorFactory return $this->enrichedReflectorFactory; } + /** + * @deprecated use ::getPrinterFactory() instead. + */ public function getPrinter(?PhpVersion $phpVersion = null): Printer { if (!isset($this->printer)) { @@ -138,6 +146,15 @@ public function getPrinter(?PhpVersion $phpVersion = null): Printer return $this->printer; } + public function getPrinterFactory(): PrinterFactory + { + if (!isset($this->printerFactory)) { + $this->printerFactory = new StandardPrinterFactory(); + } + + return $this->printerFactory; + } + private static function checkSamePhpVersion( ?PhpVersion $versionUsed, ?PhpVersion $versionRequest, diff --git a/src/PhpParser/Parser/ParserFactory.php b/src/PhpParser/Parser/ParserFactory.php new file mode 100644 index 00000000..bc3f14ed --- /dev/null +++ b/src/PhpParser/Parser/ParserFactory.php @@ -0,0 +1,23 @@ +, + * Pádraic Brady + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Humbug\PhpScoper\PhpParser\Parser; + +use PhpParser\Parser; +use PhpParser\PhpVersion; + +interface ParserFactory +{ + public function createParser(?PhpVersion $phpVersion = null): Parser; +} diff --git a/src/PhpParser/Parser/StandardParserFactory.php b/src/PhpParser/Parser/StandardParserFactory.php new file mode 100644 index 00000000..b936dbec --- /dev/null +++ b/src/PhpParser/Parser/StandardParserFactory.php @@ -0,0 +1,38 @@ +, + * Pádraic Brady + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Humbug\PhpScoper\PhpParser\Parser; + +use PhpParser\Lexer; +use PhpParser\Lexer\Emulative; +use PhpParser\Parser; +use PhpParser\Parser\Php7; +use PhpParser\Parser\Php8; +use PhpParser\PhpVersion; + +final class StandardParserFactory implements ParserFactory +{ + public function createParser(?PhpVersion $phpVersion = null): Parser + { + $version = $phpVersion ?? PhpVersion::getHostVersion(); + + $lexer = $version->isHostVersion() + ? new Lexer() + : new Emulative($version); + + return $version->id >= 80_000 + ? new Php8($lexer, $version) + : new Php7($lexer, $version); + } +} diff --git a/src/PhpParser/Printer/PrinterFactory.php b/src/PhpParser/Printer/PrinterFactory.php new file mode 100644 index 00000000..ddfb45f9 --- /dev/null +++ b/src/PhpParser/Printer/PrinterFactory.php @@ -0,0 +1,22 @@ +, + * Pádraic Brady + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Humbug\PhpScoper\PhpParser\Printer; + +use PhpParser\PhpVersion; + +interface PrinterFactory +{ + public function createPrinter(?PhpVersion $phpVersion = null): Printer; +} diff --git a/src/PhpParser/Printer/StandardPrinterFactory.php b/src/PhpParser/Printer/StandardPrinterFactory.php new file mode 100644 index 00000000..78a612e1 --- /dev/null +++ b/src/PhpParser/Printer/StandardPrinterFactory.php @@ -0,0 +1,30 @@ +, + * Pádraic Brady + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Humbug\PhpScoper\PhpParser\Printer; + +use PhpParser\PhpVersion; +use PhpParser\PrettyPrinter\Standard; + +final class StandardPrinterFactory implements PrinterFactory +{ + public function createPrinter(?PhpVersion $phpVersion = null): Printer + { + return new StandardPrinter( + new Standard([ + 'phpVersion' => $phpVersion, + ]), + ); + } +} diff --git a/src/Scoper/Factory/ScoperFactory.php b/src/Scoper/Factory/ScoperFactory.php new file mode 100644 index 00000000..207a124b --- /dev/null +++ b/src/Scoper/Factory/ScoperFactory.php @@ -0,0 +1,29 @@ +, + * Pádraic Brady + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Humbug\PhpScoper\Scoper\Factory; + +use Humbug\PhpScoper\Configuration\Configuration; +use Humbug\PhpScoper\Scoper\Scoper; +use Humbug\PhpScoper\Symbol\SymbolsRegistry; +use PhpParser\PhpVersion; + +interface ScoperFactory +{ + public function createScoper( + Configuration $configuration, + SymbolsRegistry $symbolsRegistry, + ?PhpVersion $phpVersion = null, + ): Scoper; +} diff --git a/src/Scoper/Factory/StandardScoperFactory.php b/src/Scoper/Factory/StandardScoperFactory.php new file mode 100644 index 00000000..0d874556 --- /dev/null +++ b/src/Scoper/Factory/StandardScoperFactory.php @@ -0,0 +1,85 @@ +, + * Pádraic Brady + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Humbug\PhpScoper\Scoper\Factory; + +use Humbug\PhpScoper\Configuration\Configuration; +use Humbug\PhpScoper\PhpParser\Parser\ParserFactory; +use Humbug\PhpScoper\PhpParser\Printer\PrinterFactory; +use Humbug\PhpScoper\PhpParser\TraverserFactory; +use Humbug\PhpScoper\Scoper\Composer\AutoloadPrefixer; +use Humbug\PhpScoper\Scoper\Composer\InstalledPackagesScoper; +use Humbug\PhpScoper\Scoper\Composer\JsonFileScoper; +use Humbug\PhpScoper\Scoper\NullScoper; +use Humbug\PhpScoper\Scoper\PatchScoper; +use Humbug\PhpScoper\Scoper\PhpScoper; +use Humbug\PhpScoper\Scoper\Scoper; +use Humbug\PhpScoper\Scoper\SymfonyScoper; +use Humbug\PhpScoper\Symbol\EnrichedReflectorFactory; +use Humbug\PhpScoper\Symbol\SymbolsRegistry; +use PhpParser\PhpVersion; + +final readonly class StandardScoperFactory implements ScoperFactory +{ + public function __construct( + private EnrichedReflectorFactory $enrichedReflectorFactory, + private ParserFactory $parserFactory, + private PrinterFactory $printerFactory, + ) { + } + + public function createScoper( + Configuration $configuration, + SymbolsRegistry $symbolsRegistry, + ?PhpVersion $phpVersion = null, + ): Scoper { + $prefix = $configuration->getPrefix(); + $symbolsConfiguration = $configuration->getSymbolsConfiguration(); + $enrichedReflector = $this->enrichedReflectorFactory->create($symbolsConfiguration); + + $parser = $this->parserFactory->createParser($phpVersion); + $printer = $this->printerFactory->createPrinter($phpVersion); + + $autoloadPrefixer = new AutoloadPrefixer( + $prefix, + $enrichedReflector, + ); + + return new PatchScoper( + new PhpScoper( + $parser, + new JsonFileScoper( + new InstalledPackagesScoper( + new SymfonyScoper( + new NullScoper(), + $prefix, + $enrichedReflector, + $symbolsRegistry, + ), + $autoloadPrefixer, + ), + $autoloadPrefixer, + ), + new TraverserFactory( + $enrichedReflector, + $prefix, + $symbolsRegistry, + ), + $printer, + ), + $prefix, + $configuration->getPatcher(), + ); + } +} diff --git a/src/Scoper/ScoperFactory.php b/src/Scoper/ScoperFactory.php index 978cc83a..7212efa6 100644 --- a/src/Scoper/ScoperFactory.php +++ b/src/Scoper/ScoperFactory.php @@ -26,6 +26,8 @@ /** * @final + * + * @deprecated Deprecated in favour of \Humbug\PhpScoper\Scoper\Factory\ScoperFactory */ class ScoperFactory { diff --git a/tests/Console/Command/AddPrefixCommandTest.php b/tests/Console/Command/AddPrefixCommandTest.php index 04046f4f..036d96b5 100644 --- a/tests/Console/Command/AddPrefixCommandTest.php +++ b/tests/Console/Command/AddPrefixCommandTest.php @@ -28,11 +28,8 @@ use Humbug\PhpScoper\Console\ConsoleScoper; use Humbug\PhpScoper\Container; use Humbug\PhpScoper\FileSystemTestCase; -use Humbug\PhpScoper\PhpParser\FakeParser; -use Humbug\PhpScoper\PhpParser\FakePrinter; +use Humbug\PhpScoper\Scoper\Factory\DummyScoperFactory; use Humbug\PhpScoper\Scoper\Scoper; -use Humbug\PhpScoper\Symbol\EnrichedReflectorFactory; -use Humbug\PhpScoper\Symbol\Reflector; use PhpParser\Error as PhpParserError; use PHPUnit\Framework\Attributes\CoversClass; use Prophecy\Argument; @@ -680,14 +677,7 @@ private function createAppTester(): ApplicationTester new SymfonyCommand( new AddPrefixCommand( $fileSystem, - new DummyScoperFactory( - new FakeParser(), - new EnrichedReflectorFactory( - Reflector::createEmpty(), - ), - new FakePrinter(), - $scoper, - ), + new DummyScoperFactory($scoper), $innerApp, new ConfigurationFactory( $fileSystem, diff --git a/tests/Console/Command/AppIntegrationTest.php b/tests/Console/Command/AppIntegrationTest.php index 40345716..d0223886 100644 --- a/tests/Console/Command/AppIntegrationTest.php +++ b/tests/Console/Command/AppIntegrationTest.php @@ -24,11 +24,8 @@ use Humbug\PhpScoper\Console\AppTesterTestCase; use Humbug\PhpScoper\Container; use Humbug\PhpScoper\FileSystemTestCase; -use Humbug\PhpScoper\PhpParser\FakeParser; -use Humbug\PhpScoper\PhpParser\FakePrinter; +use Humbug\PhpScoper\Scoper\Factory\DummyScoperFactory; use Humbug\PhpScoper\Scoper\Scoper; -use Humbug\PhpScoper\Symbol\EnrichedReflectorFactory; -use Humbug\PhpScoper\Symbol\Reflector; use PHPUnit\Framework\Attributes\CoversNothing; use PHPUnit\Framework\Attributes\Group; use Prophecy\Argument; @@ -158,12 +155,7 @@ private function createAppTester(): ApplicationTester new SymfonyCommand( new AddPrefixCommand( $fileSystem, - new DummyScoperFactory( - new FakeParser(), - new EnrichedReflectorFactory(Reflector::createEmpty()), - new FakePrinter(), - $scoper, - ), + new DummyScoperFactory($scoper), $innerApp, new ConfigurationFactory( $fileSystem, diff --git a/tests/Console/Command/DummyScoperFactory.php b/tests/Console/Command/DummyScoperFactory.php deleted file mode 100644 index eca95df7..00000000 --- a/tests/Console/Command/DummyScoperFactory.php +++ /dev/null @@ -1,44 +0,0 @@ -, - * Pádraic Brady - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Humbug\PhpScoper\Console\Command; - -use Humbug\PhpScoper\Configuration\Configuration; -use Humbug\PhpScoper\PhpParser\Printer\Printer; -use Humbug\PhpScoper\Scoper\Scoper; -use Humbug\PhpScoper\Scoper\ScoperFactory; -use Humbug\PhpScoper\Symbol\EnrichedReflectorFactory; -use Humbug\PhpScoper\Symbol\SymbolsRegistry; -use PhpParser\Parser; - -final class DummyScoperFactory extends ScoperFactory -{ - public function __construct( - Parser $parser, - EnrichedReflectorFactory $enrichedReflectorFactory, - Printer $printer, - private readonly Scoper $scoper - ) { - parent::__construct( - $parser, - $enrichedReflectorFactory, - $printer, - ); - } - - public function createScoper(Configuration $configuration, SymbolsRegistry $symbolsRegistry): Scoper - { - return $this->scoper; - } -} diff --git a/tests/PhpParser/Parser/DummyParserFactory.php b/tests/PhpParser/Parser/DummyParserFactory.php new file mode 100644 index 00000000..6696b30a --- /dev/null +++ b/tests/PhpParser/Parser/DummyParserFactory.php @@ -0,0 +1,31 @@ +, + * Pádraic Brady + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Humbug\PhpScoper\PhpParser\Parser; + +use PhpParser\Parser; +use PhpParser\PhpVersion; + +final readonly class DummyParserFactory implements ParserFactory +{ + public function __construct( + private Parser $parser, + ) { + } + + public function createParser(?PhpVersion $phpVersion = null): Parser + { + return $this->parser; + } +} diff --git a/tests/PhpParser/Printer/DummyPrinterFactory.php b/tests/PhpParser/Printer/DummyPrinterFactory.php new file mode 100644 index 00000000..95b88947 --- /dev/null +++ b/tests/PhpParser/Printer/DummyPrinterFactory.php @@ -0,0 +1,30 @@ +, + * Pádraic Brady + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Humbug\PhpScoper\PhpParser\Printer; + +use PhpParser\PhpVersion; + +final readonly class DummyPrinterFactory implements PrinterFactory +{ + public function __construct( + private Printer $printer, + ) { + } + + public function createPrinter(?PhpVersion $phpVersion = null): Printer + { + return $this->printer; + } +} diff --git a/tests/Scoper/Factory/DummyScoperFactory.php b/tests/Scoper/Factory/DummyScoperFactory.php new file mode 100644 index 00000000..8c69206c --- /dev/null +++ b/tests/Scoper/Factory/DummyScoperFactory.php @@ -0,0 +1,36 @@ +, + * Pádraic Brady + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Humbug\PhpScoper\Scoper\Factory; + +use Humbug\PhpScoper\Configuration\Configuration; +use Humbug\PhpScoper\Scoper\Scoper; +use Humbug\PhpScoper\Symbol\SymbolsRegistry; +use PhpParser\PhpVersion; + +final readonly class DummyScoperFactory implements ScoperFactory +{ + public function __construct( + private Scoper $scoper, + ) { + } + + public function createScoper( + Configuration $configuration, + SymbolsRegistry $symbolsRegistry, + ?PhpVersion $phpVersion = null, + ): Scoper { + return $this->scoper; + } +} diff --git a/tests/Scoper/ScoperFactoryTest.php b/tests/Scoper/Factory/StandardScoperFactoryTest.php similarity index 76% rename from tests/Scoper/ScoperFactoryTest.php rename to tests/Scoper/Factory/StandardScoperFactoryTest.php index 060a022e..eb1fdf67 100644 --- a/tests/Scoper/ScoperFactoryTest.php +++ b/tests/Scoper/Factory/StandardScoperFactoryTest.php @@ -12,13 +12,15 @@ * file that was distributed with this source code. */ -namespace Humbug\PhpScoper\Scoper; +namespace Humbug\PhpScoper\Scoper\Factory; use Humbug\PhpScoper\Configuration\Configuration; use Humbug\PhpScoper\Configuration\SymbolsConfiguration; use Humbug\PhpScoper\Patcher\FakePatcher; use Humbug\PhpScoper\PhpParser\FakeParser; use Humbug\PhpScoper\PhpParser\FakePrinter; +use Humbug\PhpScoper\PhpParser\Parser\DummyParserFactory; +use Humbug\PhpScoper\PhpParser\Printer\DummyPrinterFactory; use Humbug\PhpScoper\Symbol\EnrichedReflectorFactory; use Humbug\PhpScoper\Symbol\Reflector; use Humbug\PhpScoper\Symbol\SymbolsRegistry; @@ -28,17 +30,17 @@ /** * @internal */ -#[CoversClass(ScoperFactory::class)] -final class ScoperFactoryTest extends TestCase +#[CoversClass(StandardScoperFactory::class)] +final class StandardScoperFactoryTest extends TestCase { public function test_it_can_create_a_scoper(): void { - $factory = new ScoperFactory( - new FakeParser(), + $factory = new StandardScoperFactory( new EnrichedReflectorFactory( Reflector::createEmpty(), ), - new FakePrinter(), + new DummyParserFactory(new FakeParser()), + new DummyPrinterFactory(new FakePrinter()), ); $factory->createScoper( diff --git a/tests/functions.php b/tests/functions.php index 94e4fec2..3367aee4 100644 --- a/tests/functions.php +++ b/tests/functions.php @@ -15,11 +15,12 @@ namespace Humbug\PhpScoper; use PhpParser\Parser; +use PhpParser\PhpVersion; /** * @private */ -function create_parser(): Parser +function create_parser(?PhpVersion $phpVersion = null): Parser { - return (new Container())->getParser(); + return (new Container())->getParserFactory()->createParser($phpVersion); }