ray-di /
Ray.Aop
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | |||
| 3 | declare(strict_types=1); |
||
| 4 | |||
| 5 | namespace Ray\Aop; |
||
| 6 | |||
| 7 | use PhpParser\BuilderFactory; |
||
| 8 | use PhpParser\Node\Identifier; |
||
| 9 | use PhpParser\Node\Stmt; |
||
| 10 | use PhpParser\Node\Stmt\Class_; |
||
| 11 | use PhpParser\Node\Stmt\ClassMethod; |
||
| 12 | use PhpParser\NodeAbstract; |
||
| 13 | use PhpParser\Parser; |
||
| 14 | use ReflectionClass; |
||
|
0 ignored issues
–
show
|
|||
| 15 | use ReflectionMethod; |
||
|
0 ignored issues
–
show
This use statement conflicts with another class in this namespace,
Ray\Aop\ReflectionMethod.
Let’s assume that you have a directory layout like this: .
|-- OtherDir
| |-- Bar.php
| `-- Foo.php
`-- SomeDir
`-- Foo.php
and let’s assume the following content of // Bar.php
namespace OtherDir;
use SomeDir\Foo; // This now conflicts the class OtherDir\Foo
If both files PHP Fatal error: Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php
However, as // Bar.php
namespace OtherDir;
use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
|
|||
| 16 | |||
| 17 | final class CodeGenMethod |
||
| 18 | { |
||
| 19 | /** |
||
| 20 | * @var \PhpParser\Parser |
||
| 21 | */ |
||
| 22 | private $parser; |
||
| 23 | |||
| 24 | /** |
||
| 25 | * @var \PhpParser\BuilderFactory |
||
| 26 | */ |
||
| 27 | private $factory; |
||
| 28 | |||
| 29 | /** |
||
| 30 | * @throws \Doctrine\Common\Annotations\AnnotationException |
||
| 31 | */ |
||
| 32 | public function __construct( |
||
| 33 | Parser $parser, |
||
| 34 | BuilderFactory $factory |
||
| 35 | ) { |
||
| 36 | $this->parser = $parser; |
||
| 37 | $this->factory = $factory; |
||
| 38 | } |
||
| 39 | |||
| 40 | /** |
||
| 41 | * @param ReflectionClass<object> $class |
||
|
0 ignored issues
–
show
The doc-type
ReflectionClass<object> could not be parsed: Expected "|" or "end of type", but got "<" at position 15. (view supported doc-types)
This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types. Loading history...
|
|||
| 42 | * |
||
| 43 | * @return ClassMethod[] |
||
| 44 | */ |
||
| 45 | public function getMethods(ReflectionClass $class, BindInterface $bind, CodeVisitor $code) : array |
||
| 46 | { |
||
| 47 | $bindingMethods = array_keys($bind->getBindings()); |
||
| 48 | $classMethods = $code->classMethod; |
||
| 49 | $methods = []; |
||
| 50 | foreach ($classMethods as $classMethod) { |
||
| 51 | $methodName = $classMethod->name->name; |
||
| 52 | $method = new ReflectionMethod($class->name, $methodName); |
||
| 53 | $isBindingMethod = in_array($methodName, $bindingMethods, true); |
||
| 54 | $isPublic = $classMethod->flags === Class_::MODIFIER_PUBLIC; |
||
| 55 | if ($isBindingMethod && $isPublic) { |
||
| 56 | 33 | $methodInsideStatements = $this->getTemplateMethodNodeStmts( |
|
| 57 | $classMethod->getReturnType() |
||
| 58 | ); |
||
| 59 | // replace statements in the method |
||
| 60 | $classMethod->stmts = $methodInsideStatements; |
||
| 61 | 33 | $methods[] = $classMethod; |
|
| 62 | 33 | } |
|
| 63 | 33 | } |
|
| 64 | 33 | ||
| 65 | 33 | return $methods; |
|
| 66 | } |
||
| 67 | |||
| 68 | /** |
||
| 69 | * @return Stmt[] |
||
| 70 | */ |
||
| 71 | private function getTemplateMethodNodeStmts(?NodeAbstract $returnType) : array |
||
| 72 | { |
||
| 73 | 17 | $code = $this->isReturnVoid($returnType) ? AopTemplate::RETURN_VOID : AopTemplate::RETURN; |
|
| 74 | $parts = $this->parser->parse($code); |
||
| 75 | 17 | assert(isset($parts[0])); |
|
| 76 | 17 | $node = $parts[0]; |
|
| 77 | 17 | assert($node instanceof Class_); |
|
| 78 | 17 | $methodNode = $node->getMethods()[0]; |
|
| 79 | 16 | assert($methodNode->stmts !== null); |
|
| 80 | 16 | ||
| 81 | return $methodNode->stmts; |
||
| 82 | 16 | } |
|
| 83 | 16 | ||
| 84 | private function isReturnVoid(?NodeAbstract $returnType) : bool |
||
| 85 | { |
||
| 86 | return $returnType instanceof Identifier && $returnType->name === 'void'; |
||
| 87 | 17 | } |
|
| 88 | } |
||
| 89 |
Let’s assume that you have a directory layout like this:
. |-- OtherDir | |-- Bar.php | `-- Foo.php `-- SomeDir `-- Foo.phpand let’s assume the following content of
Bar.php:If both files
OtherDir/Foo.phpandSomeDir/Foo.phpare loaded in the same runtime, you will see a PHP error such as the following:PHP Fatal error: Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.phpHowever, as
OtherDir/Foo.phpdoes not necessarily have to be loaded and the error is only triggered if it is loaded beforeOtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias: