Skip to content

Commit

Permalink
fix bug where blade ->get() functions would ruin traverse parser, and…
Browse files Browse the repository at this point in the history
… make tests for it
  • Loading branch information
Bottelet committed Sep 15, 2024
1 parent bb00e8c commit 9235c20
Show file tree
Hide file tree
Showing 5 changed files with 491 additions and 21 deletions.
7 changes: 6 additions & 1 deletion src/Extractor/PhpBaseClassExtractor.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Bottelet\TranslationChecker\Extractor;

use Bottelet\TranslationChecker\Node\ChainedGetNodeRemover;
use Exception;
use PhpParser\Node;
use PhpParser\NodeTraverser;
Expand Down Expand Up @@ -47,18 +48,23 @@ public function extractFromFile(SplFileInfo $file): array
}

$code = $this->getCode($file);

if (is_null($code)) {
return [];
}

$traverser = new NodeTraverser;
$visitor = new ChainedGetNodeRemover;
$traverser->addVisitor($this);
$traverser->addVisitor($visitor);
try {
$ast = $parser->parse($code);

if ($ast === null) {
return [];
}
$traverser->traverse($ast);

} catch (Exception $error) {
throw new RuntimeException("Error parsing file {$file->getRealPath()}: {$error->getMessage()}");
}
Expand All @@ -73,7 +79,6 @@ protected function getCode(SplFileInfo $file): ?string
return null;
}


return file_get_contents($filePath) ?: null;
}
}
79 changes: 79 additions & 0 deletions src/Node/ChainedGetNodeRemover.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<?php

namespace Bottelet\TranslationChecker\Node;

use PhpParser\Node;
use PhpParser\Node\Expr\Closure;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Stmt\Expression;
use PhpParser\NodeVisitorAbstract;

class ChainedGetNodeRemover extends NodeVisitorAbstract
{
public function enterNode(Node $node): Node
{
if ($node instanceof Expression) {
$this->processExpression($node->expr);
} elseif ($node instanceof Node\Expr\FuncCall) {
foreach ($node->getArgs() as $arg) {
/** @var Node\Expr $value */
$value = $this->processNode($arg->value);
$arg->value = $value;
}
} elseif ($node instanceof MethodCall) {
return $this->processMethodCall($node);
} elseif ($node instanceof Closure) {
$this->processClosure($node);
}
return $node;
}

private function processExpression(Node $expr): void
{
if ($expr instanceof Node\Expr\Assign) {
/** @var Node\Expr $value */
$value = $this->processNode($expr->expr);
$expr->expr = $value;
}
}

private function processNode(Node $node): Node|Node\Expr
{
if ($node instanceof MethodCall) {
return $this->processMethodCall($node);
}

if ($node instanceof Closure) {
$this->processClosure($node);
}

return $node;
}

private function processMethodCall(MethodCall $node): Node
{
if ($node->name instanceof Node\Identifier && $node->name->name === 'get') {
return $node->var;
}

/** @var Node\Expr $value */
$value = $this->processNode($node->var);
$node->var = $value;
foreach ($node->getArgs() as $arg) {
/** @var Node\Expr $value */
$value = $this->processNode($arg->value);
$arg->value =$value;
}

return $node;
}

private function processClosure(Closure $closure): void
{
foreach ($closure->stmts as $stmt) {
if ($stmt instanceof Node) {
$this->processNode($stmt);
}
}
}
}
Loading

0 comments on commit 9235c20

Please sign in to comment.