From 463a168fef1e73b056eb0f5ba5d9e43f02ec3e6b Mon Sep 17 00:00:00 2001 From: Anders Jurisoo Date: Sun, 5 Apr 2020 18:39:33 +0200 Subject: [PATCH] PHPParser class and property traversing is managed by PHPParserClassMap :rocket: :explosion: --- sketches/notes2.php | 101 ++++++++++++++++++ src/Support/AST/ASTQueryBuilder.php | 38 +++---- ...{HasClassMap.php => PHPParserClassMap.php} | 4 +- tests/Unit/ASTQueryBuilderTest.php | 6 +- tests/samples/ast_data.php | 12 +-- 5 files changed, 127 insertions(+), 34 deletions(-) create mode 100644 sketches/notes2.php rename src/Traits/{HasClassMap.php => PHPParserClassMap.php} (99%) diff --git a/sketches/notes2.php b/sketches/notes2.php new file mode 100644 index 00000000..8b7376e6 --- /dev/null +++ b/sketches/notes2.php @@ -0,0 +1,101 @@ +LaravelFile::load('app/User.php')->astQuery()->arrayDimFetch(); +LaravelFile::load('app/User.php')->astQuery()->arrayItem(); +LaravelFile::load('app/User.php')->astQuery()->array(); +LaravelFile::load('app/User.php')->astQuery()->arrowFunction(); +LaravelFile::load('app/User.php')->astQuery()->assign(); +LaravelFile::load('app/User.php')->astQuery()->assignOp(); +LaravelFile::load('app/User.php')->astQuery()->assignOp(); +LaravelFile::load('app/User.php')->astQuery()->assignRef(); +LaravelFile::load('app/User.php')->astQuery()->binaryOp(); +LaravelFile::load('app/User.php')->astQuery()->binaryOp(); +LaravelFile::load('app/User.php')->astQuery()->bitwiseNot(); +LaravelFile::load('app/User.php')->astQuery()->booleanNot(); +LaravelFile::load('app/User.php')->astQuery()->cast(); +LaravelFile::load('app/User.php')->astQuery()->cast(); +LaravelFile::load('app/User.php')->astQuery()->classConstFetch(); +LaravelFile::load('app/User.php')->astQuery()->clone(); +LaravelFile::load('app/User.php')->astQuery()->closure(); +LaravelFile::load('app/User.php')->astQuery()->closureUse(); +LaravelFile::load('app/User.php')->astQuery()->constFetch(); +LaravelFile::load('app/User.php')->astQuery()->empty(); +LaravelFile::load('app/User.php')->astQuery()->error(); +LaravelFile::load('app/User.php')->astQuery()->errorSuppress(); +LaravelFile::load('app/User.php')->astQuery()->eval(); +LaravelFile::load('app/User.php')->astQuery()->exit(); +LaravelFile::load('app/User.php')->astQuery()->funcCall(); +LaravelFile::load('app/User.php')->astQuery()->include(); +LaravelFile::load('app/User.php')->astQuery()->instanceof(); +LaravelFile::load('app/User.php')->astQuery()->isset(); +LaravelFile::load('app/User.php')->astQuery()->list(); +LaravelFile::load('app/User.php')->astQuery()->methodCall(); +LaravelFile::load('app/User.php')->astQuery()->new(); +LaravelFile::load('app/User.php')->astQuery()->postDec(); +LaravelFile::load('app/User.php')->astQuery()->postInc(); +LaravelFile::load('app/User.php')->astQuery()->preDec(); +LaravelFile::load('app/User.php')->astQuery()->preInc(); +LaravelFile::load('app/User.php')->astQuery()->print(); +LaravelFile::load('app/User.php')->astQuery()->propertyFetch(); +LaravelFile::load('app/User.php')->astQuery()->shellExec(); +LaravelFile::load('app/User.php')->astQuery()->staticCall(); +LaravelFile::load('app/User.php')->astQuery()->staticPropertyFetch(); +LaravelFile::load('app/User.php')->astQuery()->ternary(); +LaravelFile::load('app/User.php')->astQuery()->unaryMinus(); +LaravelFile::load('app/User.php')->astQuery()->unaryPlus(); +LaravelFile::load('app/User.php')->astQuery()->variable(); +LaravelFile::load('app/User.php')->astQuery()->yieldFrom(); +LaravelFile::load('app/User.php')->astQuery()->yield(); +LaravelFile::load('app/User.php')->astQuery()->fullyQualified(); +LaravelFile::load('app/User.php')->astQuery()->relative(); +LaravelFile::load('app/User.php')->astQuery()->dNumber(); +LaravelFile::load('app/User.php')->astQuery()->encapsed(); +LaravelFile::load('app/User.php')->astQuery()->encapsedStringPart(); +LaravelFile::load('app/User.php')->astQuery()->lNumber(); +LaravelFile::load('app/User.php')->astQuery()->magicConst(); +LaravelFile::load('app/User.php')->astQuery()->magicConst(); +LaravelFile::load('app/User.php')->astQuery()->string(); +LaravelFile::load('app/User.php')->astQuery()->break(); +LaravelFile::load('app/User.php')->astQuery()->case(); +LaravelFile::load('app/User.php')->astQuery()->catch(); +LaravelFile::load('app/User.php')->astQuery()->classConst(); +LaravelFile::load('app/User.php')->astQuery()->classLike(); +LaravelFile::load('app/User.php')->astQuery()->classMethod(); +LaravelFile::load('app/User.php')->astQuery()->class(); +LaravelFile::load('app/User.php')->astQuery()->const(); +LaravelFile::load('app/User.php')->astQuery()->continue(); +LaravelFile::load('app/User.php')->astQuery()->declareDeclare(); +LaravelFile::load('app/User.php')->astQuery()->declare(); +LaravelFile::load('app/User.php')->astQuery()->do(); +LaravelFile::load('app/User.php')->astQuery()->echo(); +LaravelFile::load('app/User.php')->astQuery()->elseIf(); +LaravelFile::load('app/User.php')->astQuery()->else(); +LaravelFile::load('app/User.php')->astQuery()->expression(); +LaravelFile::load('app/User.php')->astQuery()->finally(); +LaravelFile::load('app/User.php')->astQuery()->for(); +LaravelFile::load('app/User.php')->astQuery()->foreach(); +LaravelFile::load('app/User.php')->astQuery()->function(); +LaravelFile::load('app/User.php')->astQuery()->global(); +LaravelFile::load('app/User.php')->astQuery()->goto(); +LaravelFile::load('app/User.php')->astQuery()->groupUse(); +LaravelFile::load('app/User.php')->astQuery()->haltCompiler(); +LaravelFile::load('app/User.php')->astQuery()->if(); +LaravelFile::load('app/User.php')->astQuery()->inlineHTML(); +LaravelFile::load('app/User.php')->astQuery()->interface(); +LaravelFile::load('app/User.php')->astQuery()->label(); +LaravelFile::load('app/User.php')->astQuery()->namespace(); +LaravelFile::load('app/User.php')->astQuery()->nop(); +LaravelFile::load('app/User.php')->astQuery()->property(); +LaravelFile::load('app/User.php')->astQuery()->propertyProperty(); +LaravelFile::load('app/User.php')->astQuery()->return(); +LaravelFile::load('app/User.php')->astQuery()->staticVar(); +LaravelFile::load('app/User.php')->astQuery()->static(); +LaravelFile::load('app/User.php')->astQuery()->switch(); +LaravelFile::load('app/User.php')->astQuery()->throw(); +LaravelFile::load('app/User.php')->astQuery()->traitUse(); +LaravelFile::load('app/User.php')->astQuery()->traitUseAdaptation(); +LaravelFile::load('app/User.php')->astQuery()->traitUseAdaptation(); +LaravelFile::load('app/User.php')->astQuery()->trait(); +LaravelFile::load('app/User.php')->astQuery()->tryCatch(); +LaravelFile::load('app/User.php')->astQuery()->unset(); +LaravelFile::load('app/User.php')->astQuery()->useUse(); +LaravelFile::load('app/User.php')->astQuery()->use(); +LaravelFile::load('app/User.php')->astQuery()->while(); \ No newline at end of file diff --git a/src/Support/AST/ASTQueryBuilder.php b/src/Support/AST/ASTQueryBuilder.php index 6af92a29..52b83e24 100644 --- a/src/Support/AST/ASTQueryBuilder.php +++ b/src/Support/AST/ASTQueryBuilder.php @@ -10,7 +10,7 @@ use PhpParser\NodeFinder; use PHPFileManipulator\Support\AST\ShallowNodeFinder; use PHPFileManipulator\Traits\HasOperators; -use PHPFileManipulator\Traits\HasClassMap; +use PHPFileManipulator\Traits\PHPParserClassMap; use PHPFileManipulator\Support\AST\Killable; use PHPFileManipulator\Support\AST\RemovedNode; use PHPFileManipulator\Support\AST\NodeReplacer; @@ -22,7 +22,7 @@ class ASTQueryBuilder { use HasOperators; - use HasClassMap; + use PHPParserClassMap; public $allowDeepQueries = true; @@ -39,12 +39,20 @@ public function __construct($ast) public function __call($method, $args) { - // exists in classMap + // exists in classMap? if($this->classMap($method)) return $this->traverse($this->classMap($method)); throw new Exception("Could not find a method $method in the ASTQueryBuilder!"); } + public function __get($property) + { + // exists in propertyMap? + if($this->propertyMap($property)) return $this->traverseInto($this->propertyMap($property)); + + throw new Exception("Could not find a property $property in the ASTQueryBuilder!"); + } + public function traverse($expectedClass, $finderMethod = 'findInstanceOf') { $next = collect($this->tree[$this->currentDepth])->map(function($queryNode) use($expectedClass, $finderMethod) { @@ -136,6 +144,8 @@ public function remember($key, $callback) return $this; } + + /** OUTSIDE CONVENTION */ public function expression() { return $this->traverse( @@ -143,35 +153,17 @@ public function expression() )->traverseInto('expr'); } + /** OUTSIDE CONVENTION */ public function named($string) { return $this->where('name->name', $string); } + /** OUTSIDE CONVENTION */ public function arg($index) { return $this->traverseIntoArrayIndex('args', $index); } - - public function args() - { - return $this->traverseInto('args'); - } - - public function stmts() - { - return $this->traverseInto('stmts'); - } - - public function value() - { - return $this->traverseInto('value'); - } - - public function name() - { - return $this->traverseInto('name'); - } public function first() { diff --git a/src/Traits/HasClassMap.php b/src/Traits/PHPParserClassMap.php similarity index 99% rename from src/Traits/HasClassMap.php rename to src/Traits/PHPParserClassMap.php index bb60ce59..3c0521c9 100644 --- a/src/Traits/HasClassMap.php +++ b/src/Traits/PHPParserClassMap.php @@ -2,7 +2,7 @@ namespace PHPFileManipulator\Traits; -trait HasClassMap +trait PHPParserClassMap { public function classMap($class = null) { @@ -132,7 +132,7 @@ public function propertyMap($property) // 86 => "static", // 91 => "trait", - // TEMPORARY FIX WITH NAMESPACING ___ + // TEMPORARY FIX WITH NAMESPACING $1___ // CONSIDER USING A MAGIC GETTER TO ALLOW SAME NAME AS METHOD? $map = [ diff --git a/tests/Unit/ASTQueryBuilderTest.php b/tests/Unit/ASTQueryBuilderTest.php index 8d2f9ece..d69ba9be 100644 --- a/tests/Unit/ASTQueryBuilderTest.php +++ b/tests/Unit/ASTQueryBuilderTest.php @@ -53,9 +53,9 @@ public function it_can_query_deep() ->staticCall() ->where('class', 'Schema') ->named('create') - ->args() - ->value() - ->value() + ->args + ->value + ->value ->get() // exit ASTQueryBuilder, get a Collection ->first(); diff --git a/tests/samples/ast_data.php b/tests/samples/ast_data.php index 74ea796d..640834da 100644 --- a/tests/samples/ast_data.php +++ b/tests/samples/ast_data.php @@ -38,13 +38,13 @@ function second() { ->remember('table_name', function ($node) { return $node ->arg(0) - ->value() - ->value() + ->value + ->value ->get() ->first(); }) ->arg(1) - ->value() + ->value ->stmts() ->methodCall() ->where('var->name', 'table') @@ -55,9 +55,9 @@ function second() { ->get() ->first(); }) - ->args() - ->value() - ->value() + ->args + ->value + ->value ->remember('column_name', function ($node) { return $node->get(); })