update v 1.0.7.5

This commit is contained in:
Sujit Prasad
2016-06-13 20:41:55 +05:30
parent aa9786d829
commit 283d97e3ea
5078 changed files with 339851 additions and 175995 deletions

View File

@@ -1,4 +0,0 @@
preset: recommended
disabled:
- short_array_syntax

View File

@@ -1,7 +1,7 @@
The MIT License (MIT)
Copyright (c) 2013-2014 Michael Dowling <mtdowling@gmail.com>
Copyright (c) 2014-2015 Graham Campbell <graham@cachethq.io>
Copyright (c) 2014-2015 Graham Campbell <graham@alt-three.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@@ -1,21 +0,0 @@
#! /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();

View File

@@ -10,18 +10,15 @@
},
{
"name": "Graham Campbell",
"email": "graham@cachethq.io"
"email": "graham@alt-three.com"
}
],
"require":{
"php": ">=5.3.3",
"symfony/console": "~2.1",
"symfony/filesystem": "~2.1",
"symfony/finder": "~2.1",
"nikic/php-parser": "~1.3"
"php": ">=5.5.9",
"nikic/php-parser": "^1.0|^2.0"
},
"require-dev":{
"phpunit/phpunit": "~4.0"
"phpunit/phpunit": "^4.8|^5.0"
},
"autoload": {
"psr-4": {
@@ -31,10 +28,12 @@
"autoload-dev": {
"classmap": ["tests/stubs/"]
},
"bin": ["classpreloader.php"],
"config": {
"preferred-install": "dist"
},
"extra": {
"branch-alias": {
"dev-master": "1.4-dev"
"dev-master": "3.0-dev"
}
}
}

View File

@@ -1,50 +0,0 @@
<?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());
}
}
}

View File

@@ -3,7 +3,7 @@
/*
* This file is part of Class Preloader.
*
* (c) Graham Campbell <graham@cachethq.io>
* (c) Graham Campbell <graham@alt-three.com>
* (c) Michael Dowling <mtdowling@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
@@ -34,7 +34,7 @@ class ClassList
protected $current;
/**
* Create a new class list.
* Create a new class list instance.
*
* @return void
*/
@@ -103,7 +103,7 @@ class ClassList
*/
public function getClasses()
{
$classes = array();
$classes = [];
$current = $this->head;
while ($current && $current->value) {
$classes[] = $current->value;

View File

@@ -3,7 +3,7 @@
/*
* This file is part of Class Preloader.
*
* (c) Graham Campbell <graham@cachethq.io>
* (c) Graham Campbell <graham@alt-three.com>
* (c) Michael Dowling <mtdowling@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
@@ -12,9 +12,6 @@
namespace ClassPreloader;
require_once __DIR__.'/ClassNode.php';
require_once __DIR__.'/ClassList.php';
/**
* This is the class loader class.
*
@@ -32,7 +29,7 @@ class ClassLoader
public $classList;
/**
* Create a new class loader.
* Create a new class loader instance.
*
* @return void
*/
@@ -81,7 +78,7 @@ class ClassLoader
*/
public function register()
{
spl_autoload_register(array($this, 'loadClass'), true, true);
spl_autoload_register([$this, 'loadClass'], true, true);
}
/**
@@ -91,7 +88,7 @@ class ClassLoader
*/
public function unregister()
{
spl_autoload_unregister(array($this, 'loadClass'));
spl_autoload_unregister([$this, 'loadClass']);
}
/**
@@ -101,7 +98,7 @@ class ClassLoader
*
* @param string $class
*
* @return bool|null
* @return bool
*/
public function loadClass($class)
{
@@ -127,7 +124,7 @@ class ClassLoader
*/
public function getFilenames()
{
$files = array();
$files = [];
foreach ($this->classList->getClasses() as $class) {
// Push interfaces before classes if not already loaded
try {
@@ -142,17 +139,9 @@ class ClassLoader
$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.
// We ignore all exceptions related to reflection because in
// some cases class doesn't need to exist. We're ignoring all
// problems with classes, interfaces and traits.
}
}

View File

@@ -3,7 +3,7 @@
/*
* This file is part of Class Preloader.
*
* (c) Graham Campbell <graham@cachethq.io>
* (c) Graham Campbell <graham@alt-three.com>
* (c) Michael Dowling <mtdowling@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
@@ -41,7 +41,7 @@ class ClassNode
public $value;
/**
* Create a new class node.
* Create a new class node instance.
*
* @param mixed $value
* @param \ClassPreloader\ClassNode|null $prev

View File

@@ -0,0 +1,181 @@
<?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 ClassPreloader\Parser\NodeTraverser;
use PhpParser\Node\Stmt\Namespace_ as NamespaceNode;
use PhpParser\Parser;
use PhpParser\PrettyPrinter\Standard 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 \PhpParser\PrettyPrinter\Standard
*/
protected $printer;
/**
* The parser.
*
* @var \PhpParser\Parser
*/
protected $parser;
/**
* The traverser.
*
* @var \ClassPreloader\Parser\NodeTraverser
*/
protected $traverser;
/**
* Create a new class preloader instance.
*
* @param \PhpParser\PrettyPrinter\Standard $printer
* @param \PhpParser\Parser $parser
* @param \ClassPreloader\Parser\NodeTraverser $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, "<?php\n");
}
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) === "<?php\ndeclare(strict_types=1);") {
$pretty = substr($pretty, 32);
} elseif (substr($pretty, 31) === "<?php\r\ndeclare(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.*);/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);
}
}

View File

@@ -1,330 +0,0 @@
<?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');
}
}

View File

@@ -3,7 +3,7 @@
/*
* This file is part of Class Preloader.
*
* (c) Graham Campbell <graham@cachethq.io>
* (c) Graham Campbell <graham@alt-three.com>
* (c) Michael Dowling <mtdowling@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
@@ -12,43 +12,31 @@
namespace ClassPreloader;
use ClassPreloader\Parser\AbstractNodeVisitor;
use IteratorAggregate;
/**
* This is the config class.
*
* This contains all the class preloader configuration.
*/
class Config implements IteratorAggregate
class Config
{
/**
* The array of AbstractNodeVisitor objects that visit nodes.
*
* @var array
*/
protected $visitors = array();
/**
* The array of file names.
*
* @var array
*/
protected $filenames = array();
protected $filenames = [];
/**
* The array of exclusive filters.
*
* @var array
*/
protected $exclusiveFilters = array();
protected $exclusiveFilters = [];
/**
* The array of inclusive filters.
*
* @var array
*/
protected $inclusiveFilters = array();
protected $inclusiveFilters = [];
/**
* Add the filename owned by the config.
@@ -71,7 +59,7 @@ class Config implements IteratorAggregate
*/
public function getFilenames()
{
$filenames = array();
$filenames = [];
foreach ($this->filenames as $f) {
foreach ($this->inclusiveFilters as $filter) {
if (!preg_match($filter, $f)) {
@@ -89,16 +77,6 @@ class Config implements IteratorAggregate
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.
*
@@ -130,30 +108,4 @@ class Config implements IteratorAggregate
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;
}
}

View File

@@ -0,0 +1,23 @@
<?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\Exceptions;
use Exception;
/**
* This is the dir constant exception class.
*/
class DirConstantException extends Exception implements VisitorExceptionInterface
{
//
}

View File

@@ -0,0 +1,23 @@
<?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\Exceptions;
use Exception;
/**
* This is the file constant exception class.
*/
class FileConstantException extends Exception implements VisitorExceptionInterface
{
//
}

View File

@@ -0,0 +1,23 @@
<?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\Exceptions;
use Exception;
/**
* This is the strict types exception class.
*/
class StrictTypesException extends Exception implements VisitorExceptionInterface
{
//
}

View File

@@ -3,21 +3,19 @@
/*
* This file is part of Class Preloader.
*
* (c) Graham Campbell <graham@cachethq.io>
* (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\Exception;
use Exception;
namespace ClassPreloader\Exceptions;
/**
* This is the skip file exception class.
* This is the visitor exception interface.
*/
class SkipFileException extends Exception
interface VisitorExceptionInterface
{
//
}

View File

@@ -0,0 +1,95 @@
<?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 ClassPreloader\Parser\DirVisitor;
use ClassPreloader\Parser\FileVisitor;
use ClassPreloader\Parser\NodeTraverser;
use ClassPreloader\Parser\StrictTypesVisitor;
use PhpParser\Lexer;
use PhpParser\Parser;
use PhpParser\ParserFactory;
use PhpParser\PrettyPrinter\Standard as PrettyPrinter;
/**
* This is the class preloader factory class.
*
* This class is a simple way to create a class preloader instance.
*/
class Factory
{
/**
* Create a new class preloader instance.
*
* Any options provided determine how the node traverser is setup.
*
* @param bool[] $options
*
* @return \ClassPreloader\ClassPreloader
*/
public function create(array $options = [])
{
$printer = new PrettyPrinter();
$parser = $this->getParser();
$options = array_merge(['dir' => true, 'file' => true, 'skip' => false, 'strict' => false], $options);
$traverser = $this->getTraverser($options['dir'], $options['file'], $options['skip'], $options['strict']);
return new ClassPreloader($printer, $parser, $traverser);
}
/**
* Get the parser to use.
*
* @return \PhpParser\Parser
*/
protected function getParser()
{
if (class_exists(ParserFactory::class)) {
return (new ParserFactory())->create(ParserFactory::PREFER_PHP7);
}
return new Parser(new Lexer());
}
/**
* Get the node traverser to use.
*
* @param bool $dir
* @param bool $file
* @param bool $skip
* @param bool $strict
*
* @return \ClassPreloader\Parser\NodeTraverser
*/
protected function getTraverser($dir, $file, $skip, $strict)
{
$traverser = new NodeTraverser();
if ($dir) {
$traverser->addVisitor(new DirVisitor($skip));
}
if ($file) {
$traverser->addVisitor(new FileVisitor($skip));
}
if (!$strict) {
$traverser->addVisitor(new StrictTypesVisitor());
}
return $traverser;
}
}

View File

@@ -3,7 +3,7 @@
/*
* This file is part of Class Preloader.
*
* (c) Graham Campbell <graham@cachethq.io>
* (c) Graham Campbell <graham@alt-three.com>
* (c) Michael Dowling <mtdowling@gmail.com>
*
* For the full copyright and license information, please view the LICENSE

View File

@@ -3,7 +3,7 @@
/*
* This file is part of Class Preloader.
*
* (c) Graham Campbell <graham@cachethq.io>
* (c) Graham Campbell <graham@alt-three.com>
* (c) Michael Dowling <mtdowling@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
@@ -12,7 +12,7 @@
namespace ClassPreloader\Parser;
use ClassPreloader\Exception\SkipFileException;
use ClassPreloader\Exceptions\DirConstantException;
use PhpParser\Node;
use PhpParser\Node\Scalar\MagicConst\Dir as DirNode;
use PhpParser\Node\Scalar\String_ as StringNode;
@@ -32,7 +32,7 @@ class DirVisitor extends AbstractNodeVisitor
protected $skip = false;
/**
* Create a new directory visitor.
* Create a new directory visitor instance.
*
* @param bool $skip
*
@@ -48,13 +48,15 @@ class DirVisitor extends AbstractNodeVisitor
*
* @param \PhpParser\Node $node
*
* @return void
* @throws \ClassPreloader\Exceptions\DirConstantException
*
* @return \PhpParser\Node\Scalar\String_|null
*/
public function enterNode(Node $node)
{
if ($node instanceof DirNode) {
if ($this->skip) {
throw new SkipFileException('__DIR__ constant found, skipping...');
throw new DirConstantException();
}
return new StringNode($this->getDir());

View File

@@ -3,7 +3,7 @@
/*
* This file is part of Class Preloader.
*
* (c) Graham Campbell <graham@cachethq.io>
* (c) Graham Campbell <graham@alt-three.com>
* (c) Michael Dowling <mtdowling@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
@@ -12,7 +12,7 @@
namespace ClassPreloader\Parser;
use ClassPreloader\Exception\SkipFileException;
use ClassPreloader\Exceptions\FileConstantException;
use PhpParser\Node;
use PhpParser\Node\Scalar\MagicConst\File as FileNode;
use PhpParser\Node\Scalar\String_ as StringNode;
@@ -32,7 +32,7 @@ class FileVisitor extends AbstractNodeVisitor
protected $skip = false;
/**
* Create a new file visitor.
* Create a new file visitor instance.
*
* @param bool $skip
*
@@ -48,13 +48,15 @@ class FileVisitor extends AbstractNodeVisitor
*
* @param \PhpParser\Node $node
*
* @return void
* @throws \ClassPreloader\Exceptions\FileConstantException
*
* @return \PhpParser\Node\Scalar\String_|null
*/
public function enterNode(Node $node)
{
if ($node instanceof FileNode) {
if ($this->skip) {
throw new SkipFileException('__FILE__ constant found, skipping...');
throw new FileConstantException();
}
return new StringNode($this->getFilename());

View File

@@ -3,7 +3,7 @@
/*
* This file is part of Class Preloader.
*
* (c) Graham Campbell <graham@cachethq.io>
* (c) Graham Campbell <graham@alt-three.com>
* (c) Michael Dowling <mtdowling@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
@@ -27,7 +27,7 @@ class NodeTraverser extends BaseTraverser
* @param array $nodes
* @param string $filename
*
* @return void
* @return \PhpParser\Node[]
*/
public function traverseFile(array $nodes, $filename)
{

View File

@@ -0,0 +1,41 @@
<?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\Parser;
use ClassPreloader\Exceptions\StrictTypesException;
use PhpParser\Node;
use PhpParser\Node\Stmt\DeclareDeclare;
/**
* This is the strict types visitor class.
*
* This allows us to identify files containing stict types declorations.
*/
class StrictTypesVisitor extends AbstractNodeVisitor
{
/**
* Enter and modify the node.
*
* @param \PhpParser\Node $node
*
* @throws \ClassPreloader\Exceptions\StrictTypesException
*
* @return null
*/
public function enterNode(Node $node)
{
if ($node instanceof DeclareDeclare && ($node->getLine() === 1 || $node->getLine() === 2)) {
throw new StrictTypesException();
}
}
}