@ 2017-07-06T13:49:55Z <?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
Enable javascript to submit You have javascript disabled. You will not be able to edit any code.
Here you find the average performance (time & memory) of each version. A grayed out version indicates it didn't complete successfully (based on exit-code).
Version System time (s) User time (s) Memory (MiB) 7.1.7 0.003 0.013 15.21 7.1.6 0.023 0.013 33.31 7.1.5 0.017 0.023 33.08 7.1.4 0.443 0.017 32.69 7.1.3 0.017 0.020 32.50 7.1.2 0.027 0.017 32.72 7.1.1 0.003 0.013 14.47 7.1.0 0.027 0.020 14.55 7.0.20 0.007 0.017 14.79 7.0.19 0.003 0.017 14.52 7.0.18 0.023 0.007 14.16 7.0.17 0.000 0.017 14.20 7.0.16 0.400 0.010 14.28 7.0.15 0.013 0.007 14.43 7.0.14 0.297 0.007 14.21 7.0.13 0.010 0.010 14.45 7.0.12 0.010 0.007 14.47 7.0.11 0.343 0.013 14.51 7.0.10 0.240 0.017 14.45 7.0.9 0.027 0.007 14.30 7.0.8 0.313 0.007 14.25 7.0.7 0.067 0.017 14.21 7.0.6 0.303 0.007 14.02 7.0.5 0.007 0.013 14.29 7.0.4 0.013 0.010 14.37 7.0.3 0.003 0.013 14.45 7.0.2 0.003 0.013 14.32 7.0.1 0.023 0.003 14.38 7.0.0 0.003 0.013 14.32
preferences:dark mode live preview
138.98 ms | 1446 KiB | 7 Q