Файл: gapps/vendor/classpreloader/classpreloader/src/ClassPreloader.php
Строк: 143
<?php
/*
* This file is part of Class Preloader.
*
* (c) Graham Campbell <graham@alt-three.com>
* (c) Michael Dowling <mtdowling@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace ClassPreloader;
use ClassPreloaderParserNodeTraverser;
use PhpParserNodeStmtNamespace_ as NamespaceNode;
use PhpParserParser;
use PhpParserPrettyPrinterStandard as PrettyPrinter;
use RuntimeException;
/**
* This is the class preloader class.
*
* This is the main point of entry for interacting with this package.
*/
class ClassPreloader
{
/**
* The printer.
*
* @var PhpParserPrettyPrinterStandard
*/
protected $printer;
/**
* The parser.
*
* @var PhpParserParser
*/
protected $parser;
/**
* The traverser.
*
* @var ClassPreloaderParserNodeTraverser
*/
protected $traverser;
/**
* Create a new class preloader instance.
*
* @param PhpParserPrettyPrinterStandard $printer
* @param PhpParserParser $parser
* @param ClassPreloaderParserNodeTraverser $traverser
*
* @return void
*/
public function __construct(PrettyPrinter $printer, Parser $parser, NodeTraverser $traverser)
{
$this->printer = $printer;
$this->parser = $parser;
$this->traverser = $traverser;
}
/**
* Prepare the output file and directory.
*
* @param string $output
* @param bool $strict
*
* @throws RuntimeException
*
* @return resource
*/
public function prepareOutput($output, $strict = false)
{
if ($strict && version_compare(PHP_VERSION, '7') < 1) {
throw new RuntimeException('Strict mode requires PHP 7 or greater.');
}
$dir = dirname($output);
if (!is_dir($dir) && !mkdir($dir, 0777, true)) {
throw new RuntimeException("Unable to create directory $dir.");
}
$handle = fopen($output, 'w');
if (!$handle) {
throw new RuntimeException("Unable to open $output for writing.");
}
if ($strict) {
fwrite($handle, "<?php declare(strict_types=1);n");
} else {
fwrite($handle, "<?phpn");
}
return $handle;
}
/**
* Get a pretty printed string of code from a file while applying visitors.
*
* @param string $file
*
* @throws RuntimeException
*
* @return string
*/
public function getCode($file, $comments = true)
{
if (!is_string($file) || empty($file)) {
throw new RuntimeException('Invalid filename provided.');
}
if (!is_readable($file)) {
throw new RuntimeException("Cannot open $file for reading.");
}
if ($comments) {
$content = file_get_contents($file);
} else {
$content = php_strip_whitespace($file);
}
$parsed = $this->parser->parse($content);
$stmts = $this->traverser->traverseFile($parsed, $file);
$pretty = $this->printer->prettyPrint($stmts);
if (substr($pretty, 30) === '<?php declare(strict_types=1);' || substr($pretty, 30) === "<?phpndeclare(strict_types=1);") {
$pretty = substr($pretty, 32);
} elseif (substr($pretty, 31) === "<?phprndeclare(strict_types=1);") {
$pretty = substr($pretty, 33);
} elseif (substr($pretty, 5) === '<?php') {
$pretty = substr($pretty, 7);
}
return $this->getCodeWrappedIntoNamespace($parsed, $pretty);
}
/**
* Wrap the code into a namespace.
*
* @param array $parsed
* @param string $pretty
*
* @return string
*/
protected function getCodeWrappedIntoNamespace(array $parsed, $pretty)
{
if ($this->parsedCodeHasNamespaces($parsed)) {
$pretty = preg_replace('/^s*(namespace.*);/im', '${1} {', $pretty, 1)."n}n";
} else {
$pretty = sprintf("namespace {n%sn}n", $pretty);
}
return preg_replace('/(?<!.)[rn]+/', '', $pretty);
}
/**
* Check parsed code for having namespaces.
*
* @param array $parsed
*
* @return bool
*/
protected function parsedCodeHasNamespaces(array $parsed)
{
// Namespaces can only be on first level in the code,
// so we make only check on it.
$node = array_filter(
$parsed,
function ($value) {
return $value instanceof NamespaceNode;
}
);
return !empty($node);
}
}