diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a6924d..5721084 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,28 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## 0.3.2 - 2021-12-17 + +### Added + +- Nothing. + +### Changed + +- Nothing. + +### Deprecated + +- Nothing. + +### Removed + +- Nothing. + +### Fixed + +- Check the contents of the file before parsing, to see if any of the formatting functions exist; if not, skip parsing the file + ## 0.3.1 - 2021-12-17 ### Added diff --git a/src/Console/Command/ExtractCommand.php b/src/Console/Command/ExtractCommand.php index 0365f67..4c283a3 100644 --- a/src/Console/Command/ExtractCommand.php +++ b/src/Console/Command/ExtractCommand.php @@ -45,6 +45,7 @@ use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; +use function array_filter; use function array_map; use function array_merge; use function array_unique; @@ -275,7 +276,7 @@ private function buildOptions(InputInterface $input): MessageExtractorOptions /** @var string $inputFunctionNames */ $inputFunctionNames = $input->getOption('addl-func') ?? ''; - $additionalFunctionNames = array_map('trim', explode(',', $inputFunctionNames)); + $additionalFunctionNames = array_filter(array_map('trim', explode(',', $inputFunctionNames))); $options->functionNames = array_unique(array_merge($options->functionNames, $additionalFunctionNames)); return $options; diff --git a/src/Extractor/Parser/Descriptor/PhpParser.php b/src/Extractor/Parser/Descriptor/PhpParser.php index c2b2c3c..aad1498 100644 --- a/src/Extractor/Parser/Descriptor/PhpParser.php +++ b/src/Extractor/Parser/Descriptor/PhpParser.php @@ -30,6 +30,7 @@ use FormatPHP\Extractor\MessageExtractorOptions; use FormatPHP\Extractor\Parser\DescriptorParserInterface; use FormatPHP\Extractor\Parser\ParserErrorCollection; +use FormatPHP\Icu\MessageFormat\Parser; use FormatPHP\Util\FileSystemHelper; use LogicException; use PhpParser\Lexer; @@ -43,6 +44,7 @@ use function assert; use function count; use function in_array; +use function mb_strpos; use function pathinfo; use const PATHINFO_EXTENSION; @@ -88,9 +90,14 @@ public function __invoke( return new DescriptorCollection(); } + $fileContents = $this->fileSystemHelper->getContents($filePath); + if (!$this->hasFormattingFunctions($fileContents, $options->functionNames)) { + return new DescriptorCollection(); + } + $lexer = new Emulative(self::LEXER_OPTIONS); $parser = new Php7Parser($lexer); - $statements = $parser->parse($this->fileSystemHelper->getContents($filePath)); + $statements = $parser->parse($fileContents); $descriptorCollector = new DescriptorCollectorVisitor( $filePath, @@ -199,4 +206,18 @@ private function isPhpFile(string $filePath): bool return in_array($extension, self::PHP_PATH_EXTENSIONS); } + + /** + * @param string[] $functions + */ + private function hasFormattingFunctions(string $code, array $functions): bool + { + foreach ($functions as $function) { + if (mb_strpos($code, $function, 0, Parser::ENCODING) !== false) { + return true; + } + } + + return false; + } } diff --git a/tests/Extractor/Parser/Descriptor/PhpParserTest.php b/tests/Extractor/Parser/Descriptor/PhpParserTest.php index 2e22b3b..1e98fe6 100644 --- a/tests/Extractor/Parser/Descriptor/PhpParserTest.php +++ b/tests/Extractor/Parser/Descriptor/PhpParserTest.php @@ -423,6 +423,36 @@ public function testParse11(): void $this->assertCount(0, $receivedErrors); } + /** + * This test covers situations where the formatting functions are not + * present in the source code being analyzed, so we should short-circuit + * and skip parsing the file. + */ + public function testParse12(): void + { + $fileSystemHelper = $this->mockery(FileSystemHelper::class); + + $fileSystemHelper + ->expects() + ->getContents(__DIR__ . '/fixtures/php-parser-12.php') + ->andReturn(file_get_contents(__DIR__ . '/fixtures/php-parser-12.php')); + + $fileSystemHelper->shouldNotReceive('writeContents'); + + $errors = new ParserErrorCollection(); + + $options = new MessageExtractorOptions(); + $options->functionNames = ['formatMessage', 'translate', 't']; + + $parser = new PhpParser($fileSystemHelper); + $descriptors = $parser(__DIR__ . '/fixtures/php-parser-12.php', $options, $errors); + $receivedErrors = $this->compileErrors($errors); + + $this->assertContainsOnlyInstancesOf(DescriptorInterface::class, $descriptors); + $this->assertCount(0, $descriptors); + $this->assertCount(0, $receivedErrors); + } + /** * @return string[] */ diff --git a/tests/Extractor/Parser/Descriptor/fixtures/php-parser-12.php b/tests/Extractor/Parser/Descriptor/fixtures/php-parser-12.php new file mode 100644 index 0000000..708fad8 --- /dev/null +++ b/tests/Extractor/Parser/Descriptor/fixtures/php-parser-12.php @@ -0,0 +1,8 @@ +