Add readme
This commit is contained in:
parent
8dda97c514
commit
546c6dbaca
56
README.md
Normal file
56
README.md
Normal file
|
@ -0,0 +1,56 @@
|
|||
# Phabel
|
||||
|
||||
**Write and deploy modern PHP 8 code, today.**
|
||||
|
||||
Created by [Daniil Gentili](https://daniil.it)
|
||||
|
||||
## WIP :)
|
||||
|
||||
This is a transpiler that will allow native usage of php8 features and especially syntax in projects and libraries, while allowing maintainers to publish a version targeting 7.0 or even lower versions of php.
|
||||
|
||||
The transpiler will seamlessly hook into composer to transpile the package (and all dependencies down the current branch of the dependency tree!) on installation, on the user's machine, targeting the user's specific php version (or another one specified in the config).
|
||||
|
||||
This project is mostly ready, but I would love some feedback on design and APIs.
|
||||
|
||||
## Design
|
||||
|
||||
After [hooking into composer](https://github.com/danog/phabel/tree/master/src/Composer) by specifying a custom repository, the transpilation process begins.
|
||||
|
||||
### 1. Composer dependency graph
|
||||
|
||||
All dependencies of a package with a phabel configuration are processed with phabel with the same configuration, to allow transpiling towards an arbitrary version of PHP; composer takes care of choosing the best package, according to the current version of PHP.
|
||||
|
||||
### 2. Phabel plugin graph
|
||||
|
||||
All plugins specified in the configuration of each package are added to the [phabel plugin graph](https://github.com/danog/phabel/blob/master/src/PluginGraph/GraphInternal.php).
|
||||
The [plugin graph](https://github.com/danog/phabel/blob/master/src/PluginGraph/GraphInternal.php) takes care of properly trickling configuration values and plugins down the dependency graph, as well as plugin graph optimization by merging multiple transforms (if allowed) in a single AST traversal.
|
||||
|
||||
It will also detect circular references in [plugin dependencies](#3-2-plugin-dependencies).
|
||||
|
||||
### 3. Plugins
|
||||
|
||||
#### 3.1 AST traversal
|
||||
|
||||
Each [phabel plugin](https://github.com/danog/phabel/blob/master/src/PluginInterface.php) can specify multiple `leave*` and `enter*` methods, called when traversing down or up the dependency graph.
|
||||
These methods will be called only for nodes matching the typehint of the parameter.
|
||||
|
||||
A second, optional parameter can be provided, to allow the [Traverser](https://github.com/danog/phabel/blob/master/src/Traverser.php) to pass a [Context](https://github.com/danog/phabel/blob/master/src/Context.php) object with helper methods for replacing nodes in arbitrary positions of the AST stack.
|
||||
|
||||
#### 3.2 Plugin dependencies
|
||||
|
||||
Plugins can also specify other plugins as "dependencies" or "reverse dependencies", with the `runBefore` , `runAfter` , `runWithBefore` , `runWithAfter` methods, to force some transforms to run before others.
|
||||
By using the `*with*` methods, additional plugin graph optimization is allowed by merging multiple transforms in a single AST traversal.
|
||||
|
||||
Each [phabel plugin](https://github.com/danog/phabel/blob/master/src/PluginInterface.php) can also accept a configuration: this a simple way to reuse code, by specifying a single plugin for a class of transforms, and then requiring it from other plugins, specifying a specific configuration to trigger only certain transforms.
|
||||
|
||||
#### 3.3 Plugin configuration
|
||||
|
||||
Configuration arrays are coupled with plugins when resolving the plugin graph.
|
||||
When possible, the plugin graph will try to merge a plugin with multiple configs into a single (or fewer) plugins using the [ `mergeConfigs` method](https://github.com/danog/phabel/blob/master/src/PluginInterface.php) of the plugin.
|
||||
|
||||
This merge method will be called automatically during plugin graph flattening, if requirement links allow it.
|
||||
|
||||
### 4. Transforms
|
||||
|
||||
[Multiple transforms are available](https://github.com/danog/phabel/tree/master/src/Target), covering all PHP 7 features.
|
||||
More complex and generic transforms like typehint and nested expression polyfilling can be found in the [plugin folder](https://github.com/danog/phabel/tree/master/src/Plugin).
|
|
@ -26,8 +26,8 @@ use PhpParser\Node\Stmt\If_;
|
|||
use SplStack;
|
||||
|
||||
/**
|
||||
* AST Context
|
||||
*
|
||||
* AST Context.
|
||||
*
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @license MIT
|
||||
*/
|
||||
|
@ -261,8 +261,7 @@ class Context
|
|||
]
|
||||
);
|
||||
$curNode = $result;
|
||||
} else if ($subNode instanceof FuncCall) {
|
||||
|
||||
} elseif ($subNode instanceof FuncCall) {
|
||||
}
|
||||
$this->insertBefore($parent, $nodes);
|
||||
}
|
||||
|
|
|
@ -17,9 +17,10 @@ use PhpParser\ParserFactory;
|
|||
use ReflectionClass;
|
||||
|
||||
/**
|
||||
* Plugin
|
||||
*
|
||||
* Plugin.
|
||||
*
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @license MIT
|
||||
*/
|
||||
abstract class Plugin implements PluginInterface
|
||||
{
|
||||
|
|
|
@ -6,7 +6,6 @@ use Phabel\Plugin;
|
|||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Expr\ArrayDimFetch;
|
||||
use PhpParser\Node\Expr\BinaryOp\Concat;
|
||||
use PhpParser\Node\Expr\ClassConstFetch;
|
||||
use PhpParser\Node\Expr\Isset_;
|
||||
use PhpParser\Node\Expr\PropertyFetch;
|
||||
|
@ -18,12 +17,17 @@ use PhpParser\Node\VarLikeIdentifier;
|
|||
use ReflectionClass;
|
||||
use ReflectionClassConstant;
|
||||
use ReflectionException;
|
||||
use ReflectionProperty;
|
||||
|
||||
/**
|
||||
* Replace nested expressions in isset.
|
||||
*
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @license MIT
|
||||
*/
|
||||
class IssetExpressionFixer extends Plugin
|
||||
{
|
||||
/**
|
||||
* Recursively extract bottom ArrayDimFetch
|
||||
* Recursively extract bottom ArrayDimFetch.
|
||||
*
|
||||
* @param Node $var
|
||||
* @return Node
|
||||
|
@ -134,41 +138,41 @@ class IssetExpressionFixer extends Plugin
|
|||
}
|
||||
|
||||
/**
|
||||
* Check if static property is set
|
||||
* Check if static property is set.
|
||||
*
|
||||
* @param class-string|object $class Class
|
||||
* @param string $property Property name
|
||||
* @param boolean $propertyOrConstant Whether to fetch the property or the constant
|
||||
*
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function staticExists($class, string $property, bool $propertyOrConstant): bool
|
||||
{
|
||||
$reflectionClass = new ReflectionClass($class);
|
||||
$class = new self::getClass($class);
|
||||
$class = self::getClass($class);
|
||||
if ($propertyOrConstant) {
|
||||
try {
|
||||
$reflection = $reflectionClass->getProperty($property);
|
||||
} catch (ReflectionException $e) {
|
||||
return false;
|
||||
}
|
||||
} else if (PHP_VERSION_ID >= 70100) {
|
||||
} elseif (PHP_VERSION_ID >= 70100) {
|
||||
try {
|
||||
$reflection = new ReflectionClassConstant($class, $property);
|
||||
} catch (ReflectionException $e) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return isset($reflectionClass->getConstants()[$property];
|
||||
return isset($reflectionClass->getConstants()[$property]);
|
||||
}
|
||||
|
||||
$classCaller = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2)[1]['class'] ?? '';
|
||||
$classCaller = \debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2)[1]['class'] ?? '';
|
||||
$allowProtected = false;
|
||||
$allowPrivate = false;
|
||||
if ($classCaller) {
|
||||
if ($class === $classCaller) {
|
||||
$allowProtected = $allowPrivate = true;
|
||||
} else if ($reflectionClass->isSubclassOf($classCaller) || (new ReflectionClass($classCaller))->isSubclassOf($class)) {
|
||||
} elseif ($reflectionClass->isSubclassOf($classCaller) || (new ReflectionClass($classCaller))->isSubclassOf($class)) {
|
||||
$allowProtected = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ use SplStack;
|
|||
* Enable memoization of results based on a parameter.
|
||||
*
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @license MIT
|
||||
*/
|
||||
class Memoization
|
||||
{
|
||||
|
|
|
@ -8,7 +8,6 @@ use Phabel\Traverser;
|
|||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Expr\ArrayDimFetch;
|
||||
use PhpParser\Node\Expr\ArrowFunction;
|
||||
use PhpParser\Node\Expr\Assign;
|
||||
use PhpParser\Node\Expr\BinaryOp\BooleanOr;
|
||||
use PhpParser\Node\Expr\ClassConstFetch;
|
||||
|
@ -25,6 +24,12 @@ use PhpParser\Node\Expr\Ternary;
|
|||
use PhpParser\Node\Scalar\LNumber;
|
||||
use PhpParser\Node\Stmt\Return_;
|
||||
|
||||
/**
|
||||
* Fix nested expressions.
|
||||
*
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @license MIT
|
||||
*/
|
||||
class NestedExpressionFixer extends Plugin
|
||||
{
|
||||
/**
|
||||
|
@ -108,7 +113,7 @@ class NestedExpressionFixer extends Plugin
|
|||
"returnMe",
|
||||
new Closure([
|
||||
'byRef' => true,
|
||||
'uses' => array_keys($this->finderPlugin->getFound()),
|
||||
'uses' => \array_keys($this->finderPlugin->getFound()),
|
||||
'stmts' => [
|
||||
new Assign($value = $context->getVariable(), $valueCopy),
|
||||
new Return_($expr)
|
||||
|
|
|
@ -6,6 +6,12 @@ use Phabel\Plugin;
|
|||
use Phabel\Traverser;
|
||||
use PhpParser\Builder\FunctionLike;
|
||||
|
||||
/**
|
||||
* Regenerator transformer.
|
||||
*
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @license MIT
|
||||
*/
|
||||
class ReGenerator extends Plugin
|
||||
{
|
||||
const SHOULD_ATTRIBUTE = 'shouldRegenerate';
|
||||
|
@ -25,7 +31,7 @@ class ReGenerator extends Plugin
|
|||
}
|
||||
$this->traverser->traverseAst($function);
|
||||
}
|
||||
public function runAfter(): array
|
||||
public static function runAfter(): array
|
||||
{
|
||||
return [ArrowClosure::class];
|
||||
}
|
||||
|
|
|
@ -4,6 +4,9 @@ namespace Phabel\Plugin\ReGenerator;
|
|||
|
||||
/**
|
||||
* Regenerator class.
|
||||
*
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @license MIT
|
||||
*/
|
||||
class ReGenerator implements \Iterator
|
||||
{
|
||||
|
|
|
@ -9,6 +9,9 @@ use SplQueue;
|
|||
|
||||
/**
|
||||
* Internal regenerator traversor.
|
||||
*
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @license MIT
|
||||
*/
|
||||
class ReGeneratorInternal extends Plugin
|
||||
{
|
||||
|
|
|
@ -11,6 +11,9 @@ use SplQueue;
|
|||
|
||||
/**
|
||||
* Optimizes concatenation of multiple strings.
|
||||
*
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @license MIT
|
||||
*/
|
||||
class StringConcatOptimizer extends Plugin
|
||||
{
|
||||
|
|
|
@ -43,6 +43,7 @@ use SplStack;
|
|||
* Replace all usages of a certain type in typehints.
|
||||
*
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @license MIT
|
||||
*/
|
||||
class TypeHintStripper extends Plugin
|
||||
{
|
||||
|
|
|
@ -8,6 +8,7 @@ use ReflectionMethod;
|
|||
* Caches plugin information.
|
||||
*
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @license MIT
|
||||
*/
|
||||
class PluginCache
|
||||
{
|
||||
|
|
|
@ -5,7 +5,10 @@ namespace Phabel\PluginGraph;
|
|||
use Phabel\PluginInterface;
|
||||
|
||||
/**
|
||||
* Circular reference in plugin graph.
|
||||
*
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @license MIT
|
||||
*/
|
||||
class CircularException extends \Exception
|
||||
{
|
||||
|
|
|
@ -2,10 +2,14 @@
|
|||
|
||||
namespace Phabel\PluginGraph;
|
||||
|
||||
use Phabel\Plugin;
|
||||
use Phabel\PluginInterface;
|
||||
|
||||
/**
|
||||
* Graph API wrapper.
|
||||
*
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @license MIT
|
||||
*/
|
||||
class Graph
|
||||
{
|
||||
|
|
|
@ -7,7 +7,10 @@ use SplObjectStorage;
|
|||
use SplQueue;
|
||||
|
||||
/**
|
||||
* Internal graph class.
|
||||
*
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @license MIT
|
||||
*/
|
||||
class GraphInternal
|
||||
{
|
||||
|
|
|
@ -11,6 +11,7 @@ use SplQueue;
|
|||
* Represents a plugin with a certain configuration.
|
||||
*
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @license MIT
|
||||
*/
|
||||
class Node
|
||||
{
|
||||
|
|
|
@ -6,6 +6,7 @@ namespace Phabel\PluginGraph;
|
|||
* List of packages associated with plugin.
|
||||
*
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @license MIT
|
||||
*/
|
||||
class PackageContext
|
||||
{
|
||||
|
|
|
@ -9,6 +9,7 @@ use SplQueue;
|
|||
* Representation of multiple plugins+configs.
|
||||
*
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @license MIT
|
||||
*/
|
||||
class Plugins
|
||||
{
|
||||
|
|
|
@ -5,9 +5,10 @@ namespace Phabel;
|
|||
use Phabel\PluginGraph\PackageContext;
|
||||
|
||||
/**
|
||||
* Plugin interface
|
||||
*
|
||||
* Plugin interface.
|
||||
*
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @license MIT
|
||||
*/
|
||||
interface PluginInterface
|
||||
{
|
||||
|
|
|
@ -7,8 +7,9 @@ use PhpParser\NodeAbstract;
|
|||
|
||||
/**
|
||||
* Root node.
|
||||
*
|
||||
* @author Daniil Gentili <email@email.com>
|
||||
*
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @license MIT
|
||||
*/
|
||||
class RootNode extends NodeAbstract
|
||||
{
|
||||
|
|
|
@ -8,6 +8,11 @@ use Phabel\Plugin\ReGenerator;
|
|||
use PhpParser\Node\Expr\Yield_;
|
||||
use PhpParser\Node\FunctionLike;
|
||||
|
||||
/**
|
||||
* Detect usages of yield.
|
||||
*
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
*/
|
||||
class YieldDetector extends Plugin
|
||||
{
|
||||
public function enterYield(Yield_ $node, Context $ctx): void
|
||||
|
@ -19,11 +24,11 @@ class YieldDetector extends Plugin
|
|||
}
|
||||
}
|
||||
}
|
||||
public function runBefore(): array
|
||||
public static function runBefore(): array
|
||||
{
|
||||
return [ReGenerator::class];
|
||||
}
|
||||
public function runAfter(): array
|
||||
public static function runAfter(): array
|
||||
{
|
||||
return [ArrowClosure::class];
|
||||
}
|
||||
|
|
|
@ -10,6 +10,10 @@ use PhpParser\Node\Expr\New_;
|
|||
use PhpParser\Node\Identifier;
|
||||
use PhpParser\Node\Stmt\Namespace_;
|
||||
|
||||
/**
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @license MIT
|
||||
*/
|
||||
class AnonymousClassReplacer extends Plugin
|
||||
{
|
||||
/**
|
||||
|
|
|
@ -9,6 +9,10 @@ use PhpParser\Node\Expr\StaticCall;
|
|||
use PhpParser\Node\Expr\Variable;
|
||||
use PhpParser\Node\Name;
|
||||
|
||||
/**
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @license MIT
|
||||
*/
|
||||
class ClosureCallReplacer extends Plugin
|
||||
{
|
||||
/**
|
||||
|
|
|
@ -8,8 +8,8 @@ use PhpParser\Node\Expr\FuncCall;
|
|||
use PhpParser\Node\Name;
|
||||
use PhpParser\Node\Stmt\Const_;
|
||||
|
||||
/*
|
||||
* Converts define() arrays into const arrays
|
||||
/**
|
||||
* Converts define() arrays into const arrays.
|
||||
*/
|
||||
class DefineArrayReplacer extends Plugin
|
||||
{
|
||||
|
|
|
@ -8,6 +8,10 @@ use PhpParser\Node\Stmt\GroupUse;
|
|||
use PhpParser\Node\Stmt\Use_;
|
||||
use PhpParser\Node\Stmt\UseUse;
|
||||
|
||||
/**
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @license MIT
|
||||
*/
|
||||
class GroupUseReplacer extends Plugin
|
||||
{
|
||||
/**
|
||||
|
|
|
@ -5,6 +5,10 @@ namespace Phabel\Target\Php70;
|
|||
use Phabel\Plugin;
|
||||
use Phabel\Plugin\IssetExpressionFixer as fixer;
|
||||
|
||||
/**
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @license MIT
|
||||
*/
|
||||
class IssetExpressionFixer extends Plugin
|
||||
{
|
||||
/**
|
||||
|
|
|
@ -5,6 +5,10 @@ namespace Phabel\Target\Php70;
|
|||
use Phabel\Plugin;
|
||||
use Phabel\Plugin\NestedExpressionFixer as fixer;
|
||||
|
||||
/**
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @license MIT
|
||||
*/
|
||||
class NestedExpressionFixer extends Plugin
|
||||
{
|
||||
/**
|
||||
|
|
|
@ -7,6 +7,10 @@ use PhpParser\Node;
|
|||
use PhpParser\Node\Expr\BinaryOp\Coalesce;
|
||||
use PhpParser\Node\Expr\StaticCall;
|
||||
|
||||
/**
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @license MIT
|
||||
*/
|
||||
class NullCoalesceReplacer extends Plugin
|
||||
{
|
||||
/**
|
||||
|
|
|
@ -5,6 +5,10 @@ namespace Phabel\Target\Php70;
|
|||
use Phabel\Plugin;
|
||||
use PhpParser\Node;
|
||||
|
||||
/**
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @license MIT
|
||||
*/
|
||||
class ReservedNameReplacer extends Plugin
|
||||
{
|
||||
/**
|
||||
|
|
|
@ -5,6 +5,10 @@ namespace Phabel\Target\Php70;
|
|||
use Phabel\Plugin;
|
||||
use Phabel\Plugin\TypeHintStripper;
|
||||
|
||||
/**
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @license MIT
|
||||
*/
|
||||
class ScalarTypeHintsRemover extends Plugin
|
||||
{
|
||||
/**
|
||||
|
|
|
@ -7,6 +7,10 @@ use PhpParser\Node\Stmt\DeclareDeclare;
|
|||
use PhpParser\NodeTraverser;
|
||||
use PhpParser\NodeVisitorAbstract;
|
||||
|
||||
/**
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @license MIT
|
||||
*/
|
||||
class StrictTypesDeclareStatementRemover extends NodeVisitorAbstract
|
||||
{
|
||||
/**
|
||||
|
|
|
@ -10,6 +10,10 @@ use PhpParser\Node\Expr\YieldFrom;
|
|||
use PhpParser\Node\FunctionLike;
|
||||
use PhpParser\Node\Stmt\Return_;
|
||||
|
||||
/**
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @license MIT
|
||||
*/
|
||||
class YieldFromReturnDetector extends Plugin
|
||||
{
|
||||
public function enterYieldFrom(YieldFrom $node, Context $ctx): void
|
||||
|
@ -48,11 +52,11 @@ class YieldFromReturnDetector extends Plugin
|
|||
}
|
||||
}
|
||||
}
|
||||
public function runBefore(): array
|
||||
public static function runBefore(): array
|
||||
{
|
||||
return [ReGenerator::class];
|
||||
}
|
||||
public function runAfter(): array
|
||||
public static function runAfter(): array
|
||||
{
|
||||
return [ArrowClosure::class];
|
||||
}
|
||||
|
|
|
@ -4,6 +4,10 @@ namespace Phabel\Target\Php71;
|
|||
|
||||
use Phabel\Plugin;
|
||||
|
||||
/**
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @license MIT
|
||||
*/
|
||||
class IssetExpressionFixer extends Plugin
|
||||
{
|
||||
}
|
||||
|
|
|
@ -4,6 +4,10 @@ namespace Phabel\Target\Php71;
|
|||
|
||||
use Phabel\Plugin;
|
||||
|
||||
/**
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @license MIT
|
||||
*/
|
||||
class NestedExpressionFixer extends Plugin
|
||||
{
|
||||
}
|
||||
|
|
|
@ -5,6 +5,10 @@ namespace Phabel\Target\Php71;
|
|||
use Phabel\Plugin;
|
||||
use Phabel\Plugin\TypeHintStripper;
|
||||
|
||||
/**
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @license MIT
|
||||
*/
|
||||
class NullableType extends Plugin
|
||||
{
|
||||
/**
|
||||
|
|
|
@ -5,6 +5,10 @@ namespace Phabel\Target\Php71;
|
|||
use Phabel\Plugin;
|
||||
use Phabel\Plugin\TypeHintStripper;
|
||||
|
||||
/**
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @license MIT
|
||||
*/
|
||||
class VoidReturnType extends Plugin
|
||||
{
|
||||
/**
|
||||
|
|
|
@ -4,6 +4,10 @@ namespace Phabel\Target\Php72;
|
|||
|
||||
use Phabel\Plugin;
|
||||
|
||||
/**
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @license MIT
|
||||
*/
|
||||
class IssetExpressionFixer extends Plugin
|
||||
{
|
||||
}
|
||||
|
|
|
@ -4,6 +4,10 @@ namespace Phabel\Target\Php72;
|
|||
|
||||
use Phabel\Plugin;
|
||||
|
||||
/**
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @license MIT
|
||||
*/
|
||||
class NestedExpressionFixer extends Plugin
|
||||
{
|
||||
}
|
||||
|
|
|
@ -5,6 +5,10 @@ namespace Phabel\Target\Php72;
|
|||
use Phabel\Plugin;
|
||||
use Phabel\Plugin\TypeHintStripper;
|
||||
|
||||
/**
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @license MIT
|
||||
*/
|
||||
class ObjectTypeHintReplacer extends Plugin
|
||||
{
|
||||
/**
|
||||
|
|
|
@ -4,6 +4,10 @@ namespace Phabel\Target\Php73;
|
|||
|
||||
use Phabel\Plugin;
|
||||
|
||||
/**
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @license MIT
|
||||
*/
|
||||
class IssetExpressionFixer extends Plugin
|
||||
{
|
||||
}
|
||||
|
|
|
@ -5,6 +5,10 @@ namespace Phabel\Target\Php73;
|
|||
use Phabel\Plugin;
|
||||
use Phabel\Plugin\NestedExpressionFixer as fixer;
|
||||
|
||||
/**
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @license MIT
|
||||
*/
|
||||
class NestedExpressionFixer extends Plugin
|
||||
{
|
||||
/**
|
||||
|
|
|
@ -7,6 +7,10 @@ use PhpParser\Node\Arg;
|
|||
use PhpParser\Node\Expr\Array_;
|
||||
use PhpParser\Node\Expr\FuncCall;
|
||||
|
||||
/**
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @license MIT
|
||||
*/
|
||||
class ArrayUnpack extends Plugin
|
||||
{
|
||||
public function enter(Array_ $array): ?FuncCall
|
||||
|
|
|
@ -8,8 +8,6 @@ use Phabel\Plugin\ArrowClosureVariableFinder;
|
|||
use Phabel\Traverser;
|
||||
use PhpParser\Node\Expr\ArrowFunction;
|
||||
use PhpParser\Node\Expr\Closure;
|
||||
use PhpParser\Node\Expr\ClosureUse;
|
||||
use PhpParser\Node\Expr\Variable;
|
||||
use PhpParser\Node\Param;
|
||||
|
||||
/**
|
||||
|
|
|
@ -6,6 +6,10 @@ use Phabel\Plugin;
|
|||
use PhpParser\Node\Expr\ClosureUse;
|
||||
use PhpParser\Node\Expr\Variable;
|
||||
|
||||
/**
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @license MIT
|
||||
*/
|
||||
class ArrowClosureVariableFinder extends Plugin
|
||||
{
|
||||
private array $found = [];
|
||||
|
|
|
@ -4,6 +4,10 @@ namespace Phabel\Target\Php74;
|
|||
|
||||
use Phabel\Plugin;
|
||||
|
||||
/**
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @license MIT
|
||||
*/
|
||||
class IssetExpressionFixer extends Plugin
|
||||
{
|
||||
}
|
||||
|
|
|
@ -4,6 +4,10 @@ namespace Phabel\Target\Php74;
|
|||
|
||||
use Phabel\Plugin;
|
||||
|
||||
/**
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @license MIT
|
||||
*/
|
||||
class NestedExpressionFixer extends Plugin
|
||||
{
|
||||
}
|
||||
|
|
|
@ -7,6 +7,10 @@ use PhpParser\Node\Expr\Assign;
|
|||
use PhpParser\Node\Expr\AssignOp\Coalesce;
|
||||
use PhpParser\Node\Expr\BinaryOp\Coalesce as BinaryOpCoalesce;
|
||||
|
||||
/**
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @license MIT
|
||||
*/
|
||||
class NullCoalesceAssignment extends Plugin
|
||||
{
|
||||
public function enter(Coalesce $coalesce): Assign
|
||||
|
|
|
@ -5,6 +5,10 @@ namespace Phabel\Target\Php80;
|
|||
use Phabel\Plugin;
|
||||
use Phabel\Plugin\IssetExpressionFixer as fixer;
|
||||
|
||||
/**
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @license MIT
|
||||
*/
|
||||
class IssetExpressionFixer extends Plugin
|
||||
{
|
||||
/**
|
||||
|
|
|
@ -5,6 +5,10 @@ namespace Phabel\Target\Php80;
|
|||
use Phabel\Plugin;
|
||||
use Phabel\Plugin\NestedExpressionFixer as fixer;
|
||||
|
||||
/**
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @license MIT
|
||||
*/
|
||||
class NestedExpressionFixer extends Plugin
|
||||
{
|
||||
/**
|
||||
|
|
|
@ -8,9 +8,10 @@ use PhpParser\ParserFactory;
|
|||
use SplQueue;
|
||||
|
||||
/**
|
||||
* AST traverser
|
||||
*
|
||||
* AST traverser.
|
||||
*
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @license MIT
|
||||
*/
|
||||
class Traverser
|
||||
{
|
||||
|
|
|
@ -4,8 +4,9 @@ namespace Phabel;
|
|||
|
||||
/**
|
||||
* Represent variables currently in scope.
|
||||
*
|
||||
*
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @license MIT
|
||||
*/
|
||||
class VariableContext
|
||||
{
|
||||
|
@ -75,13 +76,13 @@ class VariableContext
|
|||
public function getVar(): string
|
||||
{
|
||||
do {
|
||||
$var = 'phabel'.bin2hex(random_bytes(8));
|
||||
$var = 'phabel'.\bin2hex(\random_bytes(8));
|
||||
} while (isset($this->variables[$var]));
|
||||
$this->variables[$var] = true;
|
||||
return $var;
|
||||
}
|
||||
/**
|
||||
* Get all variables currently defined
|
||||
* Get all variables currently defined.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue
Block a user