Update v1.0.6
This commit is contained in:
4
vendor/classpreloader/classpreloader/.styleci.yml
vendored
Normal file
4
vendor/classpreloader/classpreloader/.styleci.yml
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
preset: recommended
|
||||
|
||||
disabled:
|
||||
- short_array_syntax
|
22
vendor/classpreloader/classpreloader/LICENSE
vendored
Normal file
22
vendor/classpreloader/classpreloader/LICENSE
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013-2014 Michael Dowling <mtdowling@gmail.com>
|
||||
Copyright (c) 2014-2015 Graham Campbell <graham@cachethq.io>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
21
vendor/classpreloader/classpreloader/classpreloader.php
vendored
Normal file
21
vendor/classpreloader/classpreloader/classpreloader.php
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
#! /usr/bin/env php
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Class Preloader.
|
||||
*
|
||||
* (c) Graham Campbell <graham@cachethq.io>
|
||||
* (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.
|
||||
*/
|
||||
|
||||
if (file_exists($autoloadPath = __DIR__.'/../../autoload.php')) {
|
||||
require_once $autoloadPath;
|
||||
} else {
|
||||
require_once __DIR__.'/vendor/autoload.php';
|
||||
}
|
||||
|
||||
$application = new ClassPreloader\Application();
|
||||
$application->run();
|
40
vendor/classpreloader/classpreloader/composer.json
vendored
Normal file
40
vendor/classpreloader/classpreloader/composer.json
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"name": "classpreloader/classpreloader",
|
||||
"description": "Helps class loading performance by generating a single PHP file containing all of the autoloaded files for a specific use case",
|
||||
"keywords": ["autoload", "class", "preload"],
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Michael Dowling",
|
||||
"email": "mtdowling@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Graham Campbell",
|
||||
"email": "graham@cachethq.io"
|
||||
}
|
||||
],
|
||||
"require":{
|
||||
"php": ">=5.3.3",
|
||||
"symfony/console": "~2.1",
|
||||
"symfony/filesystem": "~2.1",
|
||||
"symfony/finder": "~2.1",
|
||||
"nikic/php-parser": "~1.3"
|
||||
},
|
||||
"require-dev":{
|
||||
"phpunit/phpunit": "~4.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"ClassPreloader\\": "src/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"classmap": ["tests/stubs/"]
|
||||
},
|
||||
"bin": ["classpreloader.php"],
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.4-dev"
|
||||
}
|
||||
}
|
||||
}
|
50
vendor/classpreloader/classpreloader/src/Application.php
vendored
Normal file
50
vendor/classpreloader/classpreloader/src/Application.php
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Class Preloader.
|
||||
*
|
||||
* (c) Graham Campbell <graham@cachethq.io>
|
||||
* (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 Symfony\Component\Console\Application as BaseApplication;
|
||||
use Symfony\Component\Finder\Finder;
|
||||
|
||||
/**
|
||||
* This is the application class.
|
||||
*
|
||||
* This is sets everything up for the CLI.
|
||||
*/
|
||||
class Application extends BaseApplication
|
||||
{
|
||||
/**
|
||||
* Create a new application.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct('Class Preloader', '1.4');
|
||||
|
||||
// Create a finder to find each non-abstract command in the filesystem
|
||||
$finder = new Finder();
|
||||
$finder->files()
|
||||
->in(__DIR__.'/Command')
|
||||
->notName('Abstract*')
|
||||
->name('*.php');
|
||||
|
||||
// Add each command to the CLI
|
||||
foreach ($finder as $file) {
|
||||
$filename = str_replace('\\', '/', $file->getRealpath());
|
||||
$pos = strripos($filename, '/ClassPreloader/') + strlen('/ClassPreloader/src/');
|
||||
$class = __NAMESPACE__.'\\'
|
||||
.substr(str_replace('/', '\\', substr($filename, $pos)), 0, -4);
|
||||
$this->add(new $class());
|
||||
}
|
||||
}
|
||||
}
|
115
vendor/classpreloader/classpreloader/src/ClassList.php
vendored
Normal file
115
vendor/classpreloader/classpreloader/src/ClassList.php
vendored
Normal file
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Class Preloader.
|
||||
*
|
||||
* (c) Graham Campbell <graham@cachethq.io>
|
||||
* (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;
|
||||
|
||||
/**
|
||||
* This is the class list class.
|
||||
*
|
||||
* This maintains a list of classes using a sort of doubly-linked list.
|
||||
*/
|
||||
class ClassList
|
||||
{
|
||||
/**
|
||||
* The head node of the list.
|
||||
*
|
||||
* @var \ClassPreloader\ClassNode
|
||||
*/
|
||||
protected $head;
|
||||
|
||||
/**
|
||||
* The current node of the list.
|
||||
*
|
||||
* @var \ClassPreloader\ClassNode
|
||||
*/
|
||||
protected $current;
|
||||
|
||||
/**
|
||||
* Create a new class list.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the contents of the list and reset the head node and current node.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
$this->head = new ClassNode();
|
||||
$this->current = $this->head;
|
||||
}
|
||||
|
||||
/**
|
||||
* Traverse to the next node in the list.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function next()
|
||||
{
|
||||
if (isset($this->current->next)) {
|
||||
$this->current = $this->current->next;
|
||||
} else {
|
||||
$this->current->next = new ClassNode(null, $this->current);
|
||||
$this->current = $this->current->next;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert a value at the current position in the list.
|
||||
*
|
||||
* Any currently set value at this position will be pushed back in the list
|
||||
* after the new value.
|
||||
*
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function push($value)
|
||||
{
|
||||
if (!$this->current->value) {
|
||||
$this->current->value = $value;
|
||||
} else {
|
||||
$temp = $this->current;
|
||||
$this->current = new ClassNode($value, $temp->prev);
|
||||
$this->current->next = $temp;
|
||||
$temp->prev = $this->current;
|
||||
if ($temp === $this->head) {
|
||||
$this->head = $this->current;
|
||||
} else {
|
||||
$this->current->prev->next = $this->current;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Traverse the ClassList and return a list of classes.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getClasses()
|
||||
{
|
||||
$classes = array();
|
||||
$current = $this->head;
|
||||
while ($current && $current->value) {
|
||||
$classes[] = $current->value;
|
||||
$current = $current->next;
|
||||
}
|
||||
|
||||
return array_filter($classes);
|
||||
}
|
||||
}
|
161
vendor/classpreloader/classpreloader/src/ClassLoader.php
vendored
Normal file
161
vendor/classpreloader/classpreloader/src/ClassLoader.php
vendored
Normal file
@@ -0,0 +1,161 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Class Preloader.
|
||||
*
|
||||
* (c) Graham Campbell <graham@cachethq.io>
|
||||
* (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;
|
||||
|
||||
require_once __DIR__.'/ClassNode.php';
|
||||
require_once __DIR__.'/ClassList.php';
|
||||
|
||||
/**
|
||||
* This is the class loader class.
|
||||
*
|
||||
* This creates an autoloader that intercepts and keeps track of each include
|
||||
* in order that files must be included. This autoloader proxies to all other
|
||||
* underlying autoloaders.
|
||||
*/
|
||||
class ClassLoader
|
||||
{
|
||||
/**
|
||||
* The list of loaded classes.
|
||||
*
|
||||
* @var \ClassPreloader\ClassList
|
||||
*/
|
||||
public $classList;
|
||||
|
||||
/**
|
||||
* Create a new class loader.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->classList = new ClassList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy the class loader.
|
||||
*
|
||||
* This makes sure we're unregistered from the autoloader.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
$this->unregister();
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap a block of code in the autoloader and get a list of loaded classes.
|
||||
*
|
||||
* @param callable $func
|
||||
*
|
||||
* @return \ClassPreloader\Config
|
||||
*/
|
||||
public static function getIncludes($func)
|
||||
{
|
||||
$loader = new static();
|
||||
call_user_func($func, $loader);
|
||||
$loader->unregister();
|
||||
|
||||
$config = new Config();
|
||||
foreach ($loader->getFilenames() as $file) {
|
||||
$config->addFile($file);
|
||||
}
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers this instance as an autoloader.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
spl_autoload_register(array($this, 'loadClass'), true, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters this instance as an autoloader.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function unregister()
|
||||
{
|
||||
spl_autoload_unregister(array($this, 'loadClass'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the given class, interface or trait.
|
||||
*
|
||||
* We'll return true if it was loaded.
|
||||
*
|
||||
* @param string $class
|
||||
*
|
||||
* @return bool|null
|
||||
*/
|
||||
public function loadClass($class)
|
||||
{
|
||||
foreach (spl_autoload_functions() as $func) {
|
||||
if (is_array($func) && $func[0] === $this) {
|
||||
continue;
|
||||
}
|
||||
$this->classList->push($class);
|
||||
if (call_user_func($func, $class)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$this->classList->next();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of loaded file names in order of loading.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getFilenames()
|
||||
{
|
||||
$files = array();
|
||||
foreach ($this->classList->getClasses() as $class) {
|
||||
// Push interfaces before classes if not already loaded
|
||||
try {
|
||||
$r = new \ReflectionClass($class);
|
||||
foreach ($r->getInterfaces() as $inf) {
|
||||
$name = $inf->getFileName();
|
||||
if ($name && !in_array($name, $files)) {
|
||||
$files[] = $name;
|
||||
}
|
||||
}
|
||||
if (!in_array($r->getFileName(), $files)) {
|
||||
$files[] = $r->getFileName();
|
||||
}
|
||||
} catch (\ReflectionException $e) {
|
||||
// We ignore all exceptions related to reflection,
|
||||
// because in some cases class can't exists. This
|
||||
// can be if you use in your code constructions like
|
||||
//
|
||||
// if (class_exists('SomeClass')) { // <-- here will trigger autoload
|
||||
// class SomeSuperClass extends SomeClass {
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// We ignore all problems with classes, interfaces and
|
||||
// traits.
|
||||
}
|
||||
}
|
||||
|
||||
return $files;
|
||||
}
|
||||
}
|
56
vendor/classpreloader/classpreloader/src/ClassNode.php
vendored
Normal file
56
vendor/classpreloader/classpreloader/src/ClassNode.php
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Class Preloader.
|
||||
*
|
||||
* (c) Graham Campbell <graham@cachethq.io>
|
||||
* (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;
|
||||
|
||||
/**
|
||||
* This is the class node class.
|
||||
*
|
||||
* This class contains a value, and the previous/next pointers.
|
||||
*/
|
||||
class ClassNode
|
||||
{
|
||||
/**
|
||||
* The next node pointer.
|
||||
*
|
||||
* @var \ClassPreloader\ClassNode|null
|
||||
*/
|
||||
public $next;
|
||||
|
||||
/**
|
||||
* The previous node pointer.
|
||||
*
|
||||
* @var \ClassPreloader\ClassNode|null
|
||||
*/
|
||||
public $prev;
|
||||
|
||||
/**
|
||||
* The value of the class node.
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
public $value;
|
||||
|
||||
/**
|
||||
* Create a new class node.
|
||||
*
|
||||
* @param mixed $value
|
||||
* @param \ClassPreloader\ClassNode|null $prev
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($value = null, $prev = null)
|
||||
{
|
||||
$this->value = $value;
|
||||
$this->prev = $prev;
|
||||
}
|
||||
}
|
330
vendor/classpreloader/classpreloader/src/Command/PreCompileCommand.php
vendored
Normal file
330
vendor/classpreloader/classpreloader/src/Command/PreCompileCommand.php
vendored
Normal file
@@ -0,0 +1,330 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Class Preloader.
|
||||
*
|
||||
* (c) Graham Campbell <graham@cachethq.io>
|
||||
* (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\Command;
|
||||
|
||||
use ClassPreloader\Config;
|
||||
use ClassPreloader\Exception\SkipFileException;
|
||||
use ClassPreloader\Parser\DirVisitor;
|
||||
use ClassPreloader\Parser\FileVisitor;
|
||||
use ClassPreloader\Parser\NodeTraverser;
|
||||
use PhpParser\Lexer;
|
||||
use PhpParser\Node\Stmt\Namespace_ as NamespaceNode;
|
||||
use PhpParser\Parser;
|
||||
use PhpParser\PrettyPrinter\Standard as PrettyPrinter;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Filesystem\Filesystem;
|
||||
|
||||
/**
|
||||
* This is the pre-compile command class.
|
||||
*
|
||||
* This allows the user to communicate with class preloader.
|
||||
*/
|
||||
class PreCompileCommand extends Command
|
||||
{
|
||||
/**
|
||||
* The printer.
|
||||
*
|
||||
* @var \PhpParser\PrettyPrinter\Standard
|
||||
*/
|
||||
protected $printer;
|
||||
|
||||
/**
|
||||
* The parser.
|
||||
*
|
||||
* @var \PhpParser\Parser
|
||||
*/
|
||||
protected $parser;
|
||||
|
||||
/**
|
||||
* The input.
|
||||
*
|
||||
* @var \Symfony\Component\Console\Input\InputInterface|null
|
||||
*/
|
||||
protected $input;
|
||||
|
||||
/**
|
||||
* The output.
|
||||
*
|
||||
* @var \Symfony\Component\Console\Output\OutputInterface|null
|
||||
*/
|
||||
protected $output;
|
||||
|
||||
/**
|
||||
* The traverser.
|
||||
*
|
||||
* @var \ClassPreloader\Parser\NodeTraverser|null
|
||||
*/
|
||||
protected $traverser;
|
||||
|
||||
/**
|
||||
* Create a new pre-compile command.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->printer = new PrettyPrinter();
|
||||
$this->parser = new Parser(new Lexer());
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the current command.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
parent::configure();
|
||||
|
||||
$this->setName('compile')
|
||||
->setDescription('Compiles classes into a single file')
|
||||
->addOption('config', null, InputOption::VALUE_REQUIRED, 'CSV of filenames to load, or the path to a PHP script that returns an array of file names')
|
||||
->addOption('output', null, InputOption::VALUE_REQUIRED)
|
||||
->addOption('skip_dir_file', null, InputOption::VALUE_NONE, 'Skip files with __DIR__ or __FILE__ to make the cache portable')
|
||||
->addOption('fix_dir', null, InputOption::VALUE_REQUIRED, 'Convert __DIR__ constants to the original directory of a file', 1)
|
||||
->addOption('fix_file', null, InputOption::VALUE_REQUIRED, 'Convert __FILE__ constants to the original path of a file', 1)
|
||||
->addOption('strip_comments', null, InputOption::VALUE_REQUIRED, 'Set to 1 to strip comments from each source file', 0)
|
||||
->setHelp(<<<EOF
|
||||
The <info>%command.name%</info> command iterates over each script, normalizes
|
||||
the file to be wrapped in namespaces, and combines each file into a single PHP
|
||||
file.
|
||||
EOF
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the node traverser used by the command.
|
||||
*
|
||||
* @return \ClassPreloader\Parser\NodeTraverser
|
||||
*/
|
||||
protected function getTraverser()
|
||||
{
|
||||
if (!$this->traverser) {
|
||||
$this->traverser = new NodeTraverser();
|
||||
if ($this->input->getOption('fix_dir')) {
|
||||
$this->traverser->addVisitor(new DirVisitor($this->input->getOption('skip_dir_file')));
|
||||
}
|
||||
if ($this->input->getOption('fix_file')) {
|
||||
$this->traverser->addVisitor(new FileVisitor($this->input->getOption('skip_dir_file')));
|
||||
}
|
||||
}
|
||||
|
||||
return $this->traverser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a pretty printed string of code from a file while applying visitors.
|
||||
*
|
||||
* @param string $file
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getCode($file)
|
||||
{
|
||||
if (!is_readable($file)) {
|
||||
throw new \RuntimeException("Cannot open {$file} for reading");
|
||||
}
|
||||
|
||||
if ($this->input->getOption('strip_comments')) {
|
||||
$content = php_strip_whitespace($file);
|
||||
} else {
|
||||
$content = file_get_contents($file);
|
||||
}
|
||||
|
||||
$parsed = $this->parser->parse($content);
|
||||
$stmts = $this->getTraverser()->traverseFile($parsed, $file);
|
||||
$pretty = $this->printer->prettyPrint($stmts);
|
||||
|
||||
// Remove the open PHP tag
|
||||
if (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.*);/i', '${1} {', $pretty, 1)."\n}\n";
|
||||
} else {
|
||||
$pretty = sprintf("namespace {\n%s\n}\n", $pretty);
|
||||
}
|
||||
|
||||
return preg_replace('/(?<!.)[\r\n]+/', '', $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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the command options.
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function validateCommand()
|
||||
{
|
||||
if (!$this->input->getOption('output')) {
|
||||
throw new \InvalidArgumentException('An output option is required');
|
||||
}
|
||||
|
||||
if (!$this->input->getOption('config')) {
|
||||
throw new \InvalidArgumentException('A config option is required');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of files in order.
|
||||
*
|
||||
* @param mixed $config Configuration option
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getFileList($config)
|
||||
{
|
||||
$this->output->writeln('> Loading configuration file');
|
||||
$filesystem = new Filesystem();
|
||||
|
||||
if (strpos($config, ',')) {
|
||||
return array_filter(explode(',', $config));
|
||||
}
|
||||
|
||||
// Ensure absolute paths are resolved
|
||||
if (!$filesystem->isAbsolutePath($config)) {
|
||||
$config = getcwd().'/'.$config;
|
||||
}
|
||||
|
||||
// Ensure that the config file exists
|
||||
if (!file_exists($config)) {
|
||||
throw new \InvalidArgumentException(sprintf('Configuration file "%s" does not exist.', $config));
|
||||
}
|
||||
|
||||
$result = require $config;
|
||||
|
||||
if ($result instanceof Config) {
|
||||
foreach ($result->getVisitors() as $visitor) {
|
||||
$this->getTraverser()->addVisitor($visitor);
|
||||
}
|
||||
|
||||
return $result;
|
||||
} elseif (is_array($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
throw new \InvalidArgumentException('Config must return an array of filenames or a Config object');
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the output file and directory.
|
||||
*
|
||||
* @param string $outputFile
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function prepareOutput($outputFile)
|
||||
{
|
||||
$dir = dirname($outputFile);
|
||||
if (!is_dir($dir) && !mkdir($dir, 0777, true)) {
|
||||
throw new \RuntimeException('Unable to create directory '.$dir);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the pre-compile command.
|
||||
*
|
||||
* @param \Symfony\Component\Console\Input\InputInterface $input
|
||||
* @param \Symfony\Component\Console\Output\OutputInterface $output
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*
|
||||
* @return null|int
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$this->input = $input;
|
||||
$this->output = $output;
|
||||
$this->validateCommand();
|
||||
$outputFile = $this->input->getOption('output');
|
||||
$config = $this->input->getOption('config');
|
||||
$files = $this->getFileList($config);
|
||||
$output->writeLn('- Found '.count($files).' files');
|
||||
|
||||
// Make sure that the output dir can be used or create it
|
||||
$this->prepareOutput($outputFile);
|
||||
|
||||
if (!$handle = fopen($input->getOption('output'), 'w')) {
|
||||
throw new \RuntimeException("Unable to open {$outputFile} for writing");
|
||||
}
|
||||
|
||||
// Write the first line of the output
|
||||
fwrite($handle, "<?php\n");
|
||||
$output->writeln('> Compiling classes');
|
||||
|
||||
$count = 0;
|
||||
$countSkipped = 0;
|
||||
foreach ($files as $file) {
|
||||
$count++;
|
||||
try {
|
||||
$code = $this->getCode($file);
|
||||
$this->output->writeln('- Writing '.$file);
|
||||
fwrite($handle, $code."\n");
|
||||
} catch (SkipFileException $ex) {
|
||||
$countSkipped++;
|
||||
$this->output->writeln('- Skipping '.$file);
|
||||
}
|
||||
}
|
||||
fclose($handle);
|
||||
|
||||
$output->writeln("> Compiled loader written to {$outputFile}");
|
||||
$output->writeln('- Files: '.($count - $countSkipped).'/'.$count.' (skipped: '.$countSkipped.')');
|
||||
$output->writeln('- Filesize: '.(round(filesize($outputFile) / 1024)).' kb');
|
||||
}
|
||||
}
|
159
vendor/classpreloader/classpreloader/src/Config.php
vendored
Normal file
159
vendor/classpreloader/classpreloader/src/Config.php
vendored
Normal file
@@ -0,0 +1,159 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Class Preloader.
|
||||
*
|
||||
* (c) Graham Campbell <graham@cachethq.io>
|
||||
* (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 ClassPreloader\Parser\AbstractNodeVisitor;
|
||||
use IteratorAggregate;
|
||||
|
||||
/**
|
||||
* This is the config class.
|
||||
*
|
||||
* This contains all the class preloader configuration.
|
||||
*/
|
||||
class Config implements IteratorAggregate
|
||||
{
|
||||
/**
|
||||
* The array of AbstractNodeVisitor objects that visit nodes.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $visitors = array();
|
||||
|
||||
/**
|
||||
* The array of file names.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $filenames = array();
|
||||
|
||||
/**
|
||||
* The array of exclusive filters.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $exclusiveFilters = array();
|
||||
|
||||
/**
|
||||
* The array of inclusive filters.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $inclusiveFilters = array();
|
||||
|
||||
/**
|
||||
* Add the filename owned by the config.
|
||||
*
|
||||
* @param string $filename
|
||||
*
|
||||
* @return \ClassPreloader\Config
|
||||
*/
|
||||
public function addFile($filename)
|
||||
{
|
||||
$this->filenames[] = $filename;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of file names that satisfy any added filters.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getFilenames()
|
||||
{
|
||||
$filenames = array();
|
||||
foreach ($this->filenames as $f) {
|
||||
foreach ($this->inclusiveFilters as $filter) {
|
||||
if (!preg_match($filter, $f)) {
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
foreach ($this->exclusiveFilters as $filter) {
|
||||
if (preg_match($filter, $f)) {
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
$filenames[] = $f;
|
||||
}
|
||||
|
||||
return $filenames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an iterator for the filenames.
|
||||
*
|
||||
* @return \ArrayIterator
|
||||
*/
|
||||
public function getIterator()
|
||||
{
|
||||
return new \ArrayIterator($this->getFilenames());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a filter used to filter out file names matching the pattern.
|
||||
*
|
||||
* We're filtering the classes using a regular expression.
|
||||
*
|
||||
* @param string $pattern
|
||||
*
|
||||
* @return \ClassPreloader\Config
|
||||
*/
|
||||
public function addExclusiveFilter($pattern)
|
||||
{
|
||||
$this->exclusiveFilters[] = $pattern;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a filter used to grab only file names matching the pattern.
|
||||
*
|
||||
* We're filtering the classes using a regular expression.
|
||||
*
|
||||
* @param string $pattern Regular expression pattern
|
||||
*
|
||||
* @return \ClassPreloader\Config
|
||||
*/
|
||||
public function addInclusiveFilter($pattern)
|
||||
{
|
||||
$this->inclusiveFilters[] = $pattern;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a visitor.
|
||||
*
|
||||
* It will visit each node when traversing the node list of each file.
|
||||
*
|
||||
* @param \ClassPreloader\Parser\AbstractNodeVisitor $visitor
|
||||
*
|
||||
* @return \ClassPreloader\Config
|
||||
*/
|
||||
public function addVisitor(AbstractNodeVisitor $visitor)
|
||||
{
|
||||
$this->visitors[] = $visitor;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of node visitors.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getVisitors()
|
||||
{
|
||||
return $this->visitors;
|
||||
}
|
||||
}
|
23
vendor/classpreloader/classpreloader/src/Exception/SkipFileException.php
vendored
Normal file
23
vendor/classpreloader/classpreloader/src/Exception/SkipFileException.php
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Class Preloader.
|
||||
*
|
||||
* (c) Graham Campbell <graham@cachethq.io>
|
||||
* (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\Exception;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* This is the skip file exception class.
|
||||
*/
|
||||
class SkipFileException extends Exception
|
||||
{
|
||||
//
|
||||
}
|
64
vendor/classpreloader/classpreloader/src/Parser/AbstractNodeVisitor.php
vendored
Normal file
64
vendor/classpreloader/classpreloader/src/Parser/AbstractNodeVisitor.php
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Class Preloader.
|
||||
*
|
||||
* (c) Graham Campbell <graham@cachethq.io>
|
||||
* (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\Parser;
|
||||
|
||||
use PhpParser\NodeVisitorAbstract;
|
||||
|
||||
/**
|
||||
* This is the abstract node visitor class.
|
||||
*
|
||||
* This is used to track the filename.
|
||||
*/
|
||||
abstract class AbstractNodeVisitor extends NodeVisitorAbstract
|
||||
{
|
||||
/**
|
||||
* The current file being parsed.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $filename = '';
|
||||
|
||||
/**
|
||||
* Set the full path to the current file being parsed.
|
||||
*
|
||||
* @param string $filename
|
||||
*
|
||||
* @return \ClassPreloader\Parser\AbstractNodeVisitor
|
||||
*/
|
||||
public function setFilename($filename)
|
||||
{
|
||||
$this->filename = $filename;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the full path to the current file being parsed.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFilename()
|
||||
{
|
||||
return $this->filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the directory of the current file being parsed.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDir()
|
||||
{
|
||||
return dirname($this->getFilename());
|
||||
}
|
||||
}
|
63
vendor/classpreloader/classpreloader/src/Parser/DirVisitor.php
vendored
Normal file
63
vendor/classpreloader/classpreloader/src/Parser/DirVisitor.php
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Class Preloader.
|
||||
*
|
||||
* (c) Graham Campbell <graham@cachethq.io>
|
||||
* (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\Parser;
|
||||
|
||||
use ClassPreloader\Exception\SkipFileException;
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Scalar\MagicConst\Dir as DirNode;
|
||||
use PhpParser\Node\Scalar\String_ as StringNode;
|
||||
|
||||
/**
|
||||
* This is the directory node visitor class.
|
||||
*
|
||||
* This is used to replace all references to __DIR__ with the actual directory.
|
||||
*/
|
||||
class DirVisitor extends AbstractNodeVisitor
|
||||
{
|
||||
/**
|
||||
* Should we skip the file if it contains a dir constant?
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $skip = false;
|
||||
|
||||
/**
|
||||
* Create a new directory visitor.
|
||||
*
|
||||
* @param bool $skip
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($skip = false)
|
||||
{
|
||||
$this->skip = $skip;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enter and modify the node.
|
||||
*
|
||||
* @param \PhpParser\Node $node
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function enterNode(Node $node)
|
||||
{
|
||||
if ($node instanceof DirNode) {
|
||||
if ($this->skip) {
|
||||
throw new SkipFileException('__DIR__ constant found, skipping...');
|
||||
}
|
||||
|
||||
return new StringNode($this->getDir());
|
||||
}
|
||||
}
|
||||
}
|
63
vendor/classpreloader/classpreloader/src/Parser/FileVisitor.php
vendored
Normal file
63
vendor/classpreloader/classpreloader/src/Parser/FileVisitor.php
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Class Preloader.
|
||||
*
|
||||
* (c) Graham Campbell <graham@cachethq.io>
|
||||
* (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\Parser;
|
||||
|
||||
use ClassPreloader\Exception\SkipFileException;
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Scalar\MagicConst\File as FileNode;
|
||||
use PhpParser\Node\Scalar\String_ as StringNode;
|
||||
|
||||
/**
|
||||
* This is the file node visitor class.
|
||||
*
|
||||
* This is used to replace all references to __FILE__ with the actual file.
|
||||
*/
|
||||
class FileVisitor extends AbstractNodeVisitor
|
||||
{
|
||||
/**
|
||||
* Should we skip the file if it contains a file constant?
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $skip = false;
|
||||
|
||||
/**
|
||||
* Create a new file visitor.
|
||||
*
|
||||
* @param bool $skip
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($skip = false)
|
||||
{
|
||||
$this->skip = $skip;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enter and modify the node.
|
||||
*
|
||||
* @param \PhpParser\Node $node
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function enterNode(Node $node)
|
||||
{
|
||||
if ($node instanceof FileNode) {
|
||||
if ($this->skip) {
|
||||
throw new SkipFileException('__FILE__ constant found, skipping...');
|
||||
}
|
||||
|
||||
return new StringNode($this->getFilename());
|
||||
}
|
||||
}
|
||||
}
|
43
vendor/classpreloader/classpreloader/src/Parser/NodeTraverser.php
vendored
Normal file
43
vendor/classpreloader/classpreloader/src/Parser/NodeTraverser.php
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Class Preloader.
|
||||
*
|
||||
* (c) Graham Campbell <graham@cachethq.io>
|
||||
* (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\Parser;
|
||||
|
||||
use PhpParser\NodeTraverser as BaseTraverser;
|
||||
|
||||
/**
|
||||
* This is the file node visitor class.
|
||||
*
|
||||
* This allows a filename to be set when visiting.
|
||||
*/
|
||||
class NodeTraverser extends BaseTraverser
|
||||
{
|
||||
/**
|
||||
* Transverse the file.
|
||||
*
|
||||
* @param array $nodes
|
||||
* @param string $filename
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function traverseFile(array $nodes, $filename)
|
||||
{
|
||||
// Set the correct state on each visitor
|
||||
foreach ($this->visitors as $visitor) {
|
||||
if ($visitor instanceof AbstractNodeVisitor) {
|
||||
$visitor->setFilename($filename);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->traverse($nodes);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user