jingcai-php/vendor/hanneskod/classtools/src/Iterator/ClassIterator.php

247 lines
6.2 KiB
PHP
Executable File

<?php
/**
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://www.wtfpl.net/ for more details.
*/
namespace hanneskod\classtools\Iterator;
use IteratorAggregate;
use ReflectionClass;
use ReflectionException;
use Symfony\Component\Finder\Finder;
use hanneskod\classtools\Transformer\Writer;
use hanneskod\classtools\Transformer\MinimizingWriter;
use hanneskod\classtools\Iterator\Filter\CacheFilter;
use hanneskod\classtools\Iterator\Filter\NameFilter;
use hanneskod\classtools\Iterator\Filter\NamespaceFilter;
use hanneskod\classtools\Iterator\Filter\NotFilter;
use hanneskod\classtools\Iterator\Filter\TypeFilter;
use hanneskod\classtools\Iterator\Filter\WhereFilter;
use hanneskod\classtools\Exception\LogicException;
use hanneskod\classtools\Loader\ClassLoader;
use hanneskod\classtools\Exception\ReaderException;
/**
* Iterate over classes found in filesystem
*
* @author Hannes Forsgård <hannes.forsgard@fripost.org>
*/
class ClassIterator implements IteratorAggregate
{
/**
* @var SplFileInfo[] Maps names to SplFileInfo objects
*/
private $classMap = [];
/**
* @var string[] List of reader error messages
*/
private $errors = [];
/**
* @var ClassLoader Autoloader for found classes
*/
private $loader;
/**
* Scan filesystem for classes, interfaces and traits
*
* @param Finder $finder
*/
public function __construct(Finder $finder)
{
/** @var \Symfony\Component\Finder\SplFileInfo $fileInfo */
foreach ($finder as $fileInfo) {
$fileInfo = new SplFileInfo($fileInfo);
try {
foreach ($fileInfo->getReader()->getDefinitionNames() as $name) {
$this->classMap[$name] = $fileInfo;
}
} catch (ReaderException $exception) {
$this->errors[] = $exception->getMessage();
}
}
}
/**
* Enable garbage collection of the autoloader at destruct
*/
public function __destruct()
{
$this->disableAutoloading();
}
/**
* Get syntax errors encountered in source
*
* @return string[]
*/
public function getErrors()
{
return $this->errors;
}
/**
* Get map of classnames to SplFileInfo objects
*
* @return SplFileInfo[]
*/
public function getClassMap()
{
return $this->classMap;
}
/**
* Enable autoloading for classes found in filesystem
*
* @return ClassIterator instance for chaining
*/
public function enableAutoloading()
{
$this->loader = new ClassLoader($this, true);
return $this;
}
/**
* Disable autoloading for classes found in filesystem
*
* @return ClassIterator instance for chaining
*/
public function disableAutoloading()
{
if (isset($this->loader)) {
$this->loader->unregister();
unset($this->loader);
}
return $this;
}
/**
* Iterator yields classnames as keys and ReflectionClass objects as values
*
* @return \Traversable
*/
public function getIterator()
{
/** @var SplFileInfo $fileInfo */
foreach ($this->getClassMap() as $name => $fileInfo) {
try {
yield $name => new ReflectionClass($name);
} catch (ReflectionException $e) {
$msg = "Unable to iterate, {$e->getMessage()}, is autoloading enabled?";
throw new LogicException($msg, 0, $e);
}
}
}
/**
* Bind filter to iterator
*
* @param Filter $filter
* @return Filter The bound filter
*/
public function filter(Filter $filter)
{
$filter->bindTo($this);
return $filter;
}
/**
* Create a new iterator where classes are filtered based on type
*
* @param string $typename
* @return Filter The created filter
*/
public function type($typename)
{
return $this->filter(new TypeFilter($typename));
}
/**
* Create a new iterator where classes are filtered based on name
*
* @param string $pattern Regular expression used when filtering
* @return Filter The created filter
*/
public function name($pattern)
{
return $this->filter(new NameFilter($pattern));
}
/**
* Create a new iterator where classes are filtered based on namespace
*
* @param string $namespace Namespace used when filtering
* @return Filter The created filter
*/
public function inNamespace($namespace)
{
return $this->filter(new NamespaceFilter($namespace));
}
/**
* Create iterator where classes are filtered based on method return value
*
* @param string $methodName Name of method
* @param mixed $returnValue Expected return value
* @return Filter The created filter
*/
public function where($methodName, $returnValue = true)
{
return $this->filter(new WhereFilter($methodName, $returnValue));
}
/**
* Negate a filter
*
* @param Filter $filter
* @return Filter The created filter
*/
public function not(Filter $filter)
{
return $this->filter(new NotFilter($filter));
}
/**
* Cache iterator
*
* @return Filter The created filter
*/
public function cache()
{
return $this->filter(new CacheFilter);
}
/**
* Transform found classes
*
* @param Writer $writer
* @return string
*/
public function transform(Writer $writer)
{
$code = '';
/** @var SplFileInfo $fileInfo */
foreach ($this->getClassMap() as $name => $fileInfo) {
$code .= $writer->write($fileInfo->getReader()->read($name)) . "\n";
}
return "<?php $code";
}
/**
* Minimize found classes
*
* @return string
*/
public function minimize()
{
return $this->transform(new MinimizingWriter);
}
}