Browse Source

PHPStan class reflection extension for ORM\Association/Table mixin

Ondrej Mirtes 9 years ago
parent
commit
c75e285bf0
3 changed files with 94 additions and 0 deletions
  1. 1 0
      composer.json
  2. 7 0
      phpstan.neon
  3. 86 0
      tests/PHPStan/AssociationTableMixinClassReflectionExtension.php

+ 1 - 0
composer.json

@@ -48,6 +48,7 @@
     },
     "autoload-dev": {
         "psr-4": {
+            "Cake\\PHPStan\\": "tests/PHPStan",
             "Cake\\Test\\": "tests",
             "TestApp\\": "tests/test_app/TestApp",
             "TestPlugin\\": "tests/test_app/Plugin/TestPlugin/src",

+ 7 - 0
phpstan.neon

@@ -12,3 +12,10 @@ parameters:
 		- '#Access to undefined constant Memcached::OPT_CLIENT_MODE#'
 		- '#Access to undefined constant Memcached::DYNAMIC_CLIENT_MODE#'
 		- '#Access to undefined constant PDO::SQLSRV_ENCODING_BINARY#'
+
+services:
+    -
+        class: Cake\PHPStan\AssociationTableMixinClassReflectionExtension
+        tags:
+            - phpstan.broker.methodsClassReflectionExtension
+            - phpstan.broker.propertiesClassReflectionExtension

+ 86 - 0
tests/PHPStan/AssociationTableMixinClassReflectionExtension.php

@@ -0,0 +1,86 @@
+<?php declare(strict_types = 1);
+
+namespace Cake\PHPStan;
+
+use Cake\ORM\Association;
+use Cake\ORM\Table;
+use PHPStan\Broker\Broker;
+use PHPStan\Reflection\BrokerAwareClassReflectionExtension;
+use PHPStan\Reflection\ClassReflection;
+use PHPStan\Reflection\MethodReflection;
+use PHPStan\Reflection\MethodsClassReflectionExtension;
+use PHPStan\Reflection\PropertiesClassReflectionExtension;
+use PHPStan\Reflection\PropertyReflection;
+
+class AssociationTableMixinClassReflectionExtension implements PropertiesClassReflectionExtension, MethodsClassReflectionExtension, BrokerAwareClassReflectionExtension
+{
+    /**
+     * @var \PHPStan\Broker\Broker
+     */
+    private $broker;
+
+    /**
+     * @param Broker $broker Class reflection broker
+     * @return void
+     */
+    public function setBroker(Broker $broker)
+    {
+        $this->broker = $broker;
+    }
+
+    /**
+     * @return ClassReflection
+     */
+    protected function getTableReflection(): ClassReflection
+    {
+        return $this->broker->getClass(Table::class);
+    }
+
+    /**
+     * @param ClassReflection $classReflection Class reflection
+     * @param string $methodName Method name
+     * @return bool
+     */
+    public function hasMethod(ClassReflection $classReflection, string $methodName): bool
+    {
+        if (!$classReflection->isSubclassOf(Association::class)) {
+            return false;
+        }
+
+        return $this->getTableReflection()->hasMethod($methodName);
+    }
+
+    /**
+     * @param ClassReflection $classReflection Class reflection
+     * @param string $methodName Method name
+     * @return MethodReflection
+     */
+    public function getMethod(ClassReflection $classReflection, string $methodName): MethodReflection
+    {
+        return $this->getTableReflection()->getMethod($methodName);
+    }
+
+    /**
+     * @param ClassReflection $classReflection Class reflection
+     * @param string $propertyName Method name
+     * @return bool
+     */
+    public function hasProperty(ClassReflection $classReflection, string $propertyName): bool
+    {
+        if (!$classReflection->isSubclassOf(Association::class)) {
+            return false;
+        }
+
+        return $this->getTableReflection()->hasProperty($propertyName);
+    }
+
+    /**
+     * @param ClassReflection $classReflection Class reflection
+     * @param string $propertyName Method name
+     * @return PropertyReflection
+     */
+    public function getProperty(ClassReflection $classReflection, string $propertyName): PropertyReflection
+    {
+        return $this->getTableReflection()->getProperty($propertyName);
+    }
+}