<?php
exit;
namespace Foobar;
use Foobar\Packer\Internal;
use PhpParser\ParserFactory;
use PhpParser\Node\Stmt;
class Packer {
private $compactSourceFormat;
function __construct($a = false) {
$this->compactSourceFormat = $a; }
function pack(string ...$a): string {
$b = (new ParserFactory())->create(ParserFactory::ONLY_PHP7);
$c = $this->compactSourceFormat ? new Internal\PrintCompact() : new Internal\PrintStandard();
$d = new Internal\Pruner();
$e = [];
foreach ($a as $f) {
$g = $b->parse($f);
if (!$g)
continue;
if (!$g[0] instanceof Stmt\Namespace_)
$g = [new Stmt\Namespace_(null, $g)];
array_push($e, ...$g); }
$d->process($e);
return $c->prettyPrint($e); } }
namespace Foobar\Packer\Internal;
class Utils {
static function getSymbolGen($a, $b) {
$c = 0;
$d = strlen($a);
return
function () use (&$c, $a, $d, $b) {
do {
$e = '';
$f = $c;
do {
$e .= $a[$f % $d];
$f = (int) ($f / $d); }
while ($f);
$c++; }
while (isset($b[$e]));
return $e; }; } }
namespace Foobar\Packer\Internal;
use PhpParser\Node;
class Traverser {
const SKIP_CHILDREN = 1;
const ABORT = 2;
const REMOVE = 3;
protected $before, $after;
function __construct(?\Closure $a, ?\Closure $b = null) {
$this->before = $a;
$this->after = $b; }
function traverse(&$a): void {
$b = $this->before;
$c = $this->after;
$d = static
function (&$e, $f) use ($b, $c, &$d, &$g) {
$h = [];
foreach ($e as $i => &$j)
if (is_array($j))
$d($j, $f);
elseif ($j instanceof Node) {
$k = $g($j, $f);
if ($k === self::REMOVE)
$h[] = [$i, null];
elseif ($k)
$h[] = [$i, $k]; }
if ($h)
do {
[$i, $l] = array_pop($h);
if ($l === null)
\array_splice($e, $i, 1);
elseif ($l instanceof Node)
\array_splice($e, $i, 1, [$l]);
else
\array_splice($e, $i, 1, $l); }
while ($h); };
$g = static
function (Node &$m, $f) use ($b, $c, &$d, &$g) {
$n = null;
if ($b)
$n = $b($m, $f);
if ($n === self::ABORT)
throw new TraverserAbort();
if ($n === null)
foreach ($m->getSubNodeNames() as $o) {
$p = &$m->{$o};
if (is_array($p))
$d($p, $m);
elseif ($p instanceof Node) {
$k = $g($p, $m);
if ($k === self::ABORT)
$p = null;
elseif ($k instanceof Node)
$p = $k;
else
if ($k)
throw new \Exception('The node can\'t be replaced with a list of nodes, as it\'s not located in a list context.'); } }
$q = null;
if ($c)
$q = $c($m, $f);
if ($q === self::ABORT)
throw new TraverserAbort();
if ($n || $q) {
if ($q === self::REMOVE || $n === self::REMOVE)
return self::REMOVE;
if ($q instanceof Node || \is_array($q))
return $q;
if ($n instanceof Node || \is_array($n))
return $n;
if ($n !== self::SKIP_CHILDREN)
throw new \Exception('Invalid return value from $before callback.');
if ($q !== self::SKIP_CHILDREN)
throw new \Exception('Invalid return value from $after callback.'); } };
try {
if (is_array($a))
$d($a, null);
elseif ($a instanceof Node)
$g($a, null);
else
throw new \TypeError('Unexpected format for $nodeOrNodes. Array or Node instance expected.'); }
catch (TraverserAbort $e) {} } }
namespace Foobar\Packer\Internal;
use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Stmt;
use PhpParser\Comment;
class Pruner {
private const VAR_RESERVED = ['this' => true, '_ENV' => true, '_GET' => true, '_POST' => true, '_FILES' => true, '_SERVER' => true, '_COOKIE' => true, '_REQUEST' => true, '_SESSION' => true, 'GLOBALS' => true];
private const VAR_DICTIONARY = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
private $varGenMap, $varGenClosure;
function process(&$a): void {
$b = $this->getTraverser();
$b->traverse($a); }
private function getTraverser() {
$a = 0;
$this->varGenReset();
$b = new Traverser(
function (Node &$c) use (&$a) {
if ($c instanceof Node\FunctionLike)
$a++; },
function (Node &$c) use (&$a) {
if ($c instanceof Node\FunctionLike) {
$a--;
if ($a == 0)
$this->varGenReset(); }
if ($a > 0 && $c instanceof Expr\Variable || $c instanceof Node\Param)
if (is_string($c->name))
$c->name = $this->varGen($c->name);
if ($a > 0 && $c instanceof Expr\ClosureUse)
$c->var = $this->varGen($c->var);
if ($c instanceof Stmt\Interface_)
$c->stmts = [];
if ($c instanceof Stmt\ClassMethod && $c->flags & Stmt\Class_::MODIFIER_ABSTRACT)
return NodeTraverser::REMOVE_NODE;
if ($c->getAttribute('comments'))
$c->setAttribute('comments', null);
if ($c instanceof Expr\FuncCall)
if ($c->name instanceof Node\Name && $c->name->toString() === 'assert')
return Traverser::REMOVE;
if ($c instanceof Stmt\If_ && !$c->else && !$c->elseifs) {
$d = $c->cond;
if ($d instanceof Expr\BinaryOp\BooleanAnd)
$d = $d->left;
if ($d instanceof Expr\ConstFetch && $d->name->toString() === 'DEBUG')
return Traverser::REMOVE; }
if ($c instanceof Stmt\Class_)
$c->flags &= ~(Stmt\Class_::MODIFIER_ABSTRACT | Stmt\Class_::MODIFIER_FINAL);
if ($c instanceof Stmt\ClassMethod)
$c->flags &= ~Stmt\Class_::MODIFIER_PUBLIC; });
return $b; }
protected function varGenReset() {
$this->varGenMap = [];
$this->varGenClosure = Utils::getSymbolGen(self::VAR_DICTIONARY, self::VAR_RESERVED); }
protected function varGen($a) {
if (isset(self::VAR_RESERVED[$a]))
return $a;
if (!isset($this->varGenMap[$a])) {
$b = ($this->varGenClosure)();
$this->varGenMap[$a] = $b; }
return $this->varGenMap[$a]; } }
namespace Foobar\Packer\Internal;
use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Stmt;
class Compactor {
private const CONST_USE = Stmt\Use_::TYPE_CONSTANT;
private const FUNC_USE = Stmt\Use_::TYPE_FUNCTION;
private const NORM_USE = Stmt\Use_::TYPE_NORMAL;
function __construct($a) {
$b = [];
$c = [];
foreach ($a as $d) {
$e = $d->name === null ? 'global' : $d->name->toString();
$f = $this->getAliased($d);
$g = $this->getMentioned($d);
$h = [];
$i = [];
$j = [];
foreach ([self::CONST_USE, self::FUNC_USE, self::NORM_USE] as $k) {
$h[$k] = \array_diff_key($g[$k], $f[$k]);
$f[$k] = \array_intersect_key($f[$k], $g[$k]); }
$l = ['node' => &$d, 'aliased' => $f, 'original' => $h, 'mentioned' => $g];
$b[] = $l;
$c[$e]['nodes'][] = &$d;
$c[$e]['original'][Stmt\Use_::TYPE_NORMAL] += $h[Stmt\Use_::TYPE_NORMAL];
$c[$e]['original'][Stmt\Use_::TYPE_FUNCTION] += $h[Stmt\Use_::TYPE_FUNCTION];
$c[$e]['original'][Stmt\Use_::TYPE_CONSTANT] += $h[Stmt\Use_::TYPE_CONSTANT];
$c[$e]['mentioned'][Stmt\Use_::TYPE_NORMAL] += $g[Stmt\Use_::TYPE_NORMAL];
$c[$e]['mentioned'][Stmt\Use_::TYPE_FUNCTION] += $g[Stmt\Use_::TYPE_FUNCTION];
$c[$e]['mentioned'][Stmt\Use_::TYPE_CONSTANT] += $g[Stmt\Use_::TYPE_CONSTANT]; } }
private function getAliased(Stmt\Namespace_ $a) {
$b = [];
foreach ($a->stmts as $c) {
if (!$c instanceof Stmt\Use_ && !$c instanceof Stmt\GroupUse)
break;
$d = $c instanceof Stmt\GroupUse;
$e = $d ? $c->prefix->toString() . '\\' : '';
foreach ($c->uses as $f) {
$g = $e . $f->name->toString();
$h = $f->alias;
$i = $d ? $f->type : $c->type;
$j = $i !== Stmt\Use_::TYPE_CONSTANT;
$k[$i][$j ? \strtolower($h) : $h] = $g; } }
return $b; }
private function getMentioned(Stmt\Namespace_ $a) {
$b = [];
$c = new Traverser(
function ($d, $e) use (&$b) {
if ($d instanceof Stmt\Const_)
foreach ($d->consts as $f)
$b[self::CONST_USE][$f->name] = true;
if ($d instanceof Stmt\Function_)
$b[self::FUNC_USE][\strtolower($d->name)] = true;
if ($d instanceof Stmt\ClassLike)
if ($d->name !== null)
$b[self::NORM_USE][\strtolower($d->name)] = true;
if ($d instanceof Node\Name) {
$g = $d->toString();
if ($e instanceof Stmt\UseUse) ;
elseif ($e instanceof Expr\ConstFetch)
$b[self::CONST_USE][$g] = true;
elseif ($e instanceof Expr\FuncCall)
$b[self::FUNC_USE][\strtolower($g)] = true;
else
$b[self::NORM_USE][\strtolower($g)] = true; } });
$c->traverse($a);
return $b; } }
135.6968879699707
Before: 21364 bytes; After: 8523 bytes
Before: 566 lines; After: 244 lines
// 135.6968879699707 ms
// Before: 21364 bytes; After: 8523 bytes
// Before: 566 lines; After: 244 lines
- Output for 7.1.0 - 7.1.7
- Parse error: syntax error, unexpected 'Before' (T_STRING) in /in/hd2hd on line 252
Process exited with code 255. - Output for 7.0.0 - 7.0.20
- Parse error: syntax error, unexpected '?', expecting variable (T_VARIABLE) in /in/hd2hd on line 50
Process exited with code 255.
preferences:
160.77 ms | 1448 KiB | 8 Q