|
<?php |
|
|
|
// https://github.com/nikic/PHP-Parser/blob/master/lib/PhpParser/NodeVisitor.php |
|
use PhpParser\Node; |
|
use PhpParser\Node\Stmt; |
|
|
|
class MyNodeVisitor extends PHPParser_NodeVisitorAbstract { |
|
|
|
public $internal = array(); |
|
public $replacements = array(); |
|
public $blocks = array(); |
|
|
|
public $types = array( |
|
'class' => '\PhpParser\Node\Stmt\Class_', |
|
'interface' => '\PhpParser\Node\Stmt\Interface_', |
|
'function' => '\PhpParser\Node\Stmt\Function_', |
|
'const' => '\PhpParser\Node\Stmt\Const_', |
|
'trait' => '\PhpParser\Node\Stmt\Trait_', |
|
//'namespace' => 'PhpParser\Node\Stmt\Namespace_' |
|
); |
|
|
|
public $inside_block = false; |
|
|
|
/** |
|
* We want to compare the user-defined functions to internal functions later |
|
*/ |
|
public function __construct() |
|
{ |
|
$functions = get_defined_functions(); |
|
$this->internal = array_flip($functions['internal']); |
|
} |
|
|
|
/** |
|
* We need to catch raw PHP code not inside a function/class |
|
*/ |
|
public function enterNode(PHPParser_Node $node) |
|
{ |
|
foreach($this->types as $type => $class) { |
|
if($node instanceof $class) { |
|
$this->inside_block = true; |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* When leaving a node we want to replace method/function names with new ones and |
|
* store whatever type of block this node is with the blocks array |
|
*/ |
|
public function leaveNode(PHPParser_Node $node) |
|
{ |
|
//var_dump(get_class($node), array_keys((array)$node)); |
|
//return; |
|
|
|
// https://github.com/nikic/PHP-Parser/blob/master/lib/PhpParser/Node/Name.php |
|
if ($node->name instanceof \PHPParser\Node\Name) { |
|
|
|
// static function name |
|
if($node->namespacedName) { |
|
$name = $node->namespacedName->toString('/'); |
|
} else { |
|
$name = (string) $node->name; |
|
} |
|
|
|
} else { |
|
// dynamic function name |
|
$name = false; |
|
} |
|
|
|
// Might need to replace function calls |
|
if ($node instanceof \PHPParser\Node\Expr\FuncCall) { |
|
|
|
// Except closures... |
|
if( ! $name) { |
|
return; |
|
} |
|
|
|
// and normal PHP functions... |
|
if(isset($this->internal[$name])) { |
|
return; |
|
} |
|
|
|
if(isset($this->replacements[$name])) { |
|
|
|
$replacement = $this->replacements[$name]; |
|
|
|
if(is_array($replacement)) { |
|
|
|
// https://github.com/nikic/PHP-Parser/blob/master/lib/PhpParser/Node/Expr/MethodCall.php |
|
return new PHPParser_Node_Expr_MethodCall( |
|
new PHPParser_Node_Name_FullyQualified($replacement[0]), |
|
$replacement[1], |
|
$node->args |
|
); |
|
|
|
} elseif(strpos($replacement, '::') !== false) { |
|
|
|
list($class, $method) = explode('::', $replacement, 2); |
|
|
|
// https://github.com/nikic/PHP-Parser/blob/master/lib/PhpParser/Node/Expr/StaticCall.php |
|
return new PHPParser_Node_Expr_StaticCall( |
|
new PHPParser_Node_Name_FullyQualified($class), |
|
$method, |
|
$node->args |
|
); |
|
|
|
} else { |
|
|
|
// https://github.com/nikic/PHP-Parser/blob/master/lib/PhpParser/Node/Expr/FuncCall.php |
|
return new PHPParser_Node_Expr_FuncCall( |
|
new PHPParser_Node_Name_FullyQualified($class), |
|
$node->args |
|
); |
|
|
|
} |
|
} |
|
} |
|
|
|
|
|
if($node instanceof \PhpParser\Node\Stmt) { |
|
|
|
// Capture each block type |
|
foreach($this->types as $type => $class) { |
|
|
|
if($node instanceof $class) { |
|
|
|
$this->inside_block = false; |
|
|
|
if(empty($this->blocks[$type])) { |
|
$this->blocks[$type] = array(); |
|
} |
|
|
|
$prettyPrinter = new PhpParser\PrettyPrinter\Standard; |
|
$code = $prettyPrinter->prettyPrint([$node]); |
|
|
|
$this->blocks[$type][$name] = $code; |
|
|
|
//print "$type $name\n"; |
|
|
|
return; |
|
|
|
} |
|
} |
|
} |
|
|
|
if( ! $this->inside_block) { |
|
|
|
$prettyPrinter = new PhpParser\PrettyPrinter\Standard; |
|
$code = $prettyPrinter->prettyPrint([$node]); |
|
|
|
$this->blocks['code']['code'] = $code; |
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
/* |
|
// Record classes |
|
if($node instanceof Stmt\Class_ OR $node instanceof Stmt\Interface_) { |
|
|
|
$prettyPrinter = new PhpParser\PrettyPrinter\Standard; |
|
$code = $prettyPrinter->prettyPrint([$node]); |
|
|
|
$this->classes[$name] = $code; |
|
print "Class $name\n"; |
|
return; |
|
} |
|
|
|
// Record functions |
|
if($node instanceof Stmt\Function_) { |
|
|
|
$prettyPrinter = new PhpParser\PrettyPrinter\Standard; |
|
$code = $prettyPrinter->prettyPrint([$node]); |
|
$this->functions[$name] = $code; |
|
|
|
print "function $name\n"; |
|
} |
|
*/ |
|
/* |
|
// https://github.com/nikic/PHP-Parser/blob/master/lib/PhpParser/Node/Name.php |
|
if ($node->name instanceof PHPParser_Node_Name) { |
|
// static function name |
|
$type = 'static'; |
|
} else { |
|
// dynamic function name |
|
$type = 'dynamic'; |
|
} |
|
|
|
if(empty($this->functions[$type][$name])) { |
|
$this->functions[$type][$name] = 0; |
|
} |
|
|
|
$this->functions[$type][$name]++; |
|
*/ |
|
|
|
/* |
|
public function leaveNode(Node $node) { |
|
if($node instanceof Stmt\Class_) { |
|
$this->class = null; |
|
} |
|
} |
|
|
|
/* Convert namespace to _ for old systems |
|
|
|
public function leaveNode(Node $node) { |
|
if ($node instanceof Node\Name) { |
|
return new Node\Name($node->toString('_')); |
|
} elseif ($node instanceof Stmt\Class_ |
|
|| $node instanceof Stmt\Interface_ |
|
|| $node instanceof Stmt\Function_) { |
|
$node->name = $node->namespacedName->toString('_'); |
|
} elseif ($node instanceof Stmt\Const_) { |
|
foreach ($node->consts as $const) { |
|
$const->name = $const->namespacedName->toString('_'); |
|
} |
|
} elseif ($node instanceof Stmt\Namespace_) { |
|
// returning an array merges is into the parent array |
|
return $node->stmts; |
|
} elseif ($node instanceof Stmt\Use_) { |
|
// returning false removed the node altogether |
|
return false; |
|
} |
|
} |
|
*/ |