humbug /
php-scoper
| 1 | <?php |
||
| 2 | |||
| 3 | declare(strict_types=1); |
||
| 4 | |||
| 5 | /* |
||
| 6 | * This file is part of the humbug/php-scoper package. |
||
| 7 | * |
||
| 8 | * Copyright (c) 2017 Théo FIDRY <[email protected]>, |
||
| 9 | * Pádraic Brady <[email protected]> |
||
| 10 | * |
||
| 11 | * For the full copyright and license information, please view the LICENSE |
||
| 12 | * file that was distributed with this source code. |
||
| 13 | */ |
||
| 14 | |||
| 15 | namespace Humbug\PhpScoper\Scoper; |
||
| 16 | |||
| 17 | use Humbug\PhpScoper\PhpParser\Printer\Printer; |
||
| 18 | use Humbug\PhpScoper\PhpParser\TraverserFactory; |
||
| 19 | use PhpParser\Error as PhpParserError; |
||
| 20 | use PhpParser\Lexer; |
||
| 21 | use PhpParser\Parser; |
||
| 22 | use function basename; |
||
| 23 | use function func_get_args; |
||
| 24 | use function ltrim; |
||
| 25 | use function preg_match as native_preg_match; |
||
| 26 | |||
| 27 | final class PhpScoper implements Scoper |
||
| 28 | { |
||
| 29 | private const FILE_PATH_PATTERN = '/\.php$/'; |
||
| 30 | private const NOT_FILE_BINARY = '/\..+?$/'; |
||
| 31 | private const PHP_TAG = '/^<\?php/'; |
||
| 32 | private const PHP_BINARY = '/^#!.+?php.*\n{1,}<\?php/'; |
||
| 33 | |||
| 34 | private Parser $parser; |
||
| 35 | private Scoper $decoratedScoper; |
||
| 36 | 554 | private TraverserFactory $traverserFactory; |
|
| 37 | private Printer $printer; |
||
| 38 | 554 | private Lexer $lexer; |
|
| 39 | 554 | ||
| 40 | 554 | public function __construct( |
|
| 41 | Parser $parser, |
||
| 42 | Scoper $decoratedScoper, |
||
| 43 | TraverserFactory $traverserFactory, |
||
| 44 | Printer $printer, |
||
| 45 | Lexer $lexer |
||
| 46 | ) { |
||
| 47 | $this->parser = $parser; |
||
| 48 | $this->decoratedScoper = $decoratedScoper; |
||
| 49 | $this->traverserFactory = $traverserFactory; |
||
| 50 | 553 | $this->printer = $printer; |
|
| 51 | $this->lexer = $lexer; |
||
| 52 | 553 | } |
|
| 53 | 2 | ||
| 54 | /** |
||
| 55 | * Scopes PHP files. |
||
| 56 | 551 | * |
|
| 57 | * @throws PhpParserError |
||
| 58 | */ |
||
| 59 | 551 | public function scope(string $filePath, string $contents): string |
|
| 60 | { |
||
| 61 | 551 | if (!self::isPhpFile($filePath, $contents)) { |
|
| 62 | return $this->decoratedScoper->scope(...func_get_args()); |
||
| 63 | 550 | } |
|
| 64 | |||
| 65 | 550 | return $this->scopePhp($contents); |
|
| 66 | } |
||
| 67 | 549 | ||
| 68 | public function scopePhp(string $php): string |
||
| 69 | 549 | { |
|
| 70 | $statements = $this->parser->parse($php); |
||
| 71 | $oldTokens = $this->lexer->getTokens(); |
||
| 72 | 553 | ||
| 73 | $scopedStatements = $this->traverserFactory |
||
| 74 | 553 | ->create($this) |
|
| 75 | 549 | ->traverse($statements); |
|
|
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||
| 76 | |||
| 77 | return $this->printer->print( |
||
| 78 | 4 | $scopedStatements, |
|
| 79 | 1 | $scopedStatements, |
|
| 80 | $oldTokens, |
||
| 81 | ); |
||
| 82 | 3 | } |
|
| 83 | 1 | ||
| 84 | private static function isPhpFile(string $filePath, string $contents): bool |
||
| 85 | { |
||
| 86 | 2 | if (1 === native_preg_match(self::FILE_PATH_PATTERN, $filePath)) { |
|
| 87 | return true; |
||
| 88 | } |
||
| 89 | |||
| 90 | if (1 === native_preg_match(self::NOT_FILE_BINARY, basename($filePath))) { |
||
| 91 | return false; |
||
| 92 | } |
||
| 93 | |||
| 94 | if (1 === native_preg_match(self::PHP_TAG, ltrim($contents))) { |
||
| 95 | return true; |
||
| 96 | } |
||
| 97 | |||
| 98 | return 1 === native_preg_match(self::PHP_BINARY, $contents); |
||
| 99 | } |
||
| 100 | } |
||
| 101 |