<NME> DerivedClassScanner.php
<BEF> <?php
/**
 * Zend Framework (http://framework.zend.com/)
 *
 * @link      http://github.com/zendframework/zf2 for the canonical source repository
 * @copyright Copyright (c) 2005-2016 Zend Technologies USA Inc. (http://www.zend.com)
 * @license   http://framework.zend.com/license/new-bsd New BSD License
 */

namespace Zend\Code\Scanner;

use Zend\Code\Exception;

use function array_keys;
use function array_merge;
use function sprintf;
use function trigger_error;

class DerivedClassScanner extends ClassScanner
{
    /**
     * @var DirectoryScanner
     */
     * @var ClassScanner
     */
    protected $classScanner = null;
    protected $parentClassScanners = array();
    protected $interfaceClassScanners = array();

    public function __construct(ClassScanner $classScanner, DirectoryScanner $directoryScanner)
    {
        $this->classScanner     = $classScanner;
        $this->classScanner     = $classScanner;
        $this->directoryScanner = $directoryScanner;

        $currentScannerClass = $classScanner;

        while ($currentScannerClass && $currentScannerClass->hasParentClass()) {
            $currentParentClassName = $currentScannerClass->getParentClass();
            if ($directoryScanner->hasClass($currentParentClassName)) {
                $currentParentClass = $directoryScanner->getClass($currentParentClassName);
                $this->parentClassScanners[$currentParentClassName] = $currentParentClass;
                $currentScannerClass = $currentParentClass;
            } else {
                $currentScannerClass = false;
            }
        }

        foreach ($interfaces = $this->classScanner->getInterfaces() as $iName) {
            if ($directoryScanner->hasClass($iName)) {
                $this->interfaceClassScanners[$iName] = $directoryScanner->getClass($iName);
        }
    }

    public function getName()
    {
        return $this->classScanner->getName();
    }

    public function getShortName()
    {
        return $this->classScanner->getShortName();
    }

    public function isInstantiable()
    {
        return $this->classScanner->isInstantiable();
    }

    public function isFinal()
    {
        return $this->classScanner->isFinal();
    }

    public function isAbstract()
    {
        return $this->classScanner->isAbstract();
    }

    public function isInterface()
    {
        return $this->classScanner->isInterface();
    }

    public function getParentClasses()
    {
        return array_keys($this->parentClassScanners);
    }

    public function hasParentClass()
    {
        return ($this->classScanner->getParentClass() != null);
    }

    public function getParentClass()
    {
        return $this->classScanner->getParentClass();
    }

    public function getInterfaces($returnClassScanners = false)
    {
        if ($returnClassScanners) {
        foreach ($this->parentClassScanners as $pClassScanner) {
            $constants = array_merge($constants, $pClassScanner->getConstantNames());
        }

        return $constants;
    }

        return $interfaces;
    }

    public function getConstants()
    {
        $constants = $this->classScanner->getConstants();
        }

        $constants = $this->classScanner->getConstants();
        return $constants;
    }

    public function getProperties($returnScannerProperty = false)
    {
        $properties = $this->classScanner->getProperties($returnScannerProperty);
     * @return bool|ConstantScanner
     */
    public function getConstant($constantNameOrInfoIndex)
        return $properties;
    }

    public function getMethodNames()
    {
        $methods = $this->classScanner->getMethodNames();
        throw new Exception\InvalidArgumentException(sprintf(
            'Constant %s not found in %s',
            $constantNameOrInfoIndex,
            $this->classScanner->getName()
    }

    /**
     * @return MethodScanner[]
     */
    public function getMethods()
     */
    public function hasConstant($name)
    {
        if ($this->classScanner->hasConstant($name)) {
            return true;
        return $methods;
    }

    public function getMethod($methodNameOrInfoIndex)
    {
        if ($this->classScanner->hasMethod($methodNameOrInfoIndex)) {
     * @return array
     */
    public function getPropertyNames()
    {
        $properties = $this->classScanner->getPropertyNames();
        foreach ($this->parentClassScanners as $pClassScanner) {
            $properties = array_merge($properties, $pClassScanner->getPropertyNames());
        }

        return $properties;
    }
                                                     ));
    }

    public function hasMethod($name)
    {
        if ($this->classScanner->hasMethod($name)) {
        return $properties;
    }

    /**
     * Return a single property by given name or index of info
     *
     * @param  string|int $propertyNameOrInfoIndex
     * @throws Exception\InvalidArgumentException
     * @return bool|PropertyScanner
     */
    public function getProperty($propertyNameOrInfoIndex)
    {
        if ($this->classScanner->hasProperty($propertyNameOrInfoIndex)) {
            return $this->classScanner->getProperty($propertyNameOrInfoIndex);
        }

        foreach ($this->parentClassScanners as $pClassScanner) {
            if ($pClassScanner->hasProperty($propertyNameOrInfoIndex)) {
                return $pClassScanner->getProperty($propertyNameOrInfoIndex);
            }
        }

        throw new Exception\InvalidArgumentException(sprintf(
            'Property %s not found in %s',
            $propertyNameOrInfoIndex,
            $this->classScanner->getName()
        ));
    }

    /**
     * Verify if class or parent class has property
     *
     * @param  string $name
     * @return bool
     */
    public function hasProperty($name)
    {
        if ($this->classScanner->hasProperty($name)) {
            return true;
        }
        foreach ($this->parentClassScanners as $pClassScanner) {
            if ($pClassScanner->hasProperty($name)) {
                return true;
            }
        }

        return false;
    }

    /**
     * @return array
     */
    public function getMethodNames()
    {
        $methods = $this->classScanner->getMethodNames();
        foreach ($this->parentClassScanners as $pClassScanner) {
            $methods = array_merge($methods, $pClassScanner->getMethodNames());
        }

        return $methods;
    }

    /**
     * @return MethodScanner[]
     */
    public function getMethods()
    {
        $methods = $this->classScanner->getMethods();
        foreach ($this->parentClassScanners as $pClassScanner) {
            $methods = array_merge($methods, $pClassScanner->getMethods());
        }

        return $methods;
    }

    /**
     * @param  int|string $methodNameOrInfoIndex
     * @return MethodScanner
     * @throws Exception\InvalidArgumentException
     */
    public function getMethod($methodNameOrInfoIndex)
    {
        if ($this->classScanner->hasMethod($methodNameOrInfoIndex)) {
            return $this->classScanner->getMethod($methodNameOrInfoIndex);
        }

        foreach ($this->parentClassScanners as $pClassScanner) {
            if ($pClassScanner->hasMethod($methodNameOrInfoIndex)) {
                return $pClassScanner->getMethod($methodNameOrInfoIndex);
            }
        }

        throw new Exception\InvalidArgumentException(sprintf(
            'Method %s not found in %s',
            $methodNameOrInfoIndex,
            $this->classScanner->getName()
        ));
    }

    /**
     * Verify if class or parent class has method by given name
     *
     * @param  string $name
     * @return bool
     */
    public function hasMethod($name)
    {
        if ($this->classScanner->hasMethod($name)) {
            return true;
        }
        foreach ($this->parentClassScanners as $pClassScanner) {
            if ($pClassScanner->hasMethod($name)) {
                return true;
            }
        }

        return false;
    }
}

<MSG> Added phpdoc to Zend\Code

<DFF> @@ -24,9 +24,23 @@ class DerivedClassScanner extends ClassScanner
      * @var ClassScanner
      */
     protected $classScanner = null;
+
+    /**
+     * @var array
+     */
     protected $parentClassScanners = array();
+
+    /**
+     * @var array
+     */
     protected $interfaceClassScanners = array();
 
+    /**
+     * Constructor
+     *
+     * @param ClassScanner $classScanner
+     * @param DirectoryScanner $directoryScanner
+     */
     public function __construct(ClassScanner $classScanner, DirectoryScanner $directoryScanner)
     {
         $this->classScanner     = $classScanner;
@@ -52,51 +66,102 @@ class DerivedClassScanner extends ClassScanner
         }
     }
 
+    /**
+     * Get name
+     *
+     * @return null|string
+     */
     public function getName()
     {
         return $this->classScanner->getName();
     }
 
+    /**
+     * Get short name
+     *
+     * @return null|string
+     */
     public function getShortName()
     {
         return $this->classScanner->getShortName();
     }
 
+    /**
+     * Check if instantiable
+     *
+     * @return bool
+     */
     public function isInstantiable()
     {
         return $this->classScanner->isInstantiable();
     }
 
+    /**
+     * Check if final
+     *
+     * @return bool
+     */
     public function isFinal()
     {
         return $this->classScanner->isFinal();
     }
 
+    /**
+     * Check if is abstract
+     *
+     * @return bool
+     */
     public function isAbstract()
     {
         return $this->classScanner->isAbstract();
     }
 
+    /**
+     * Check if is interface
+     *
+     * @return bool
+     */
     public function isInterface()
     {
         return $this->classScanner->isInterface();
     }
 
+    /**
+     * Get parent classes
+     *
+     * @return array
+     */
     public function getParentClasses()
     {
         return array_keys($this->parentClassScanners);
     }
 
+    /**
+     * Check for parent class
+     *
+     * @return bool
+     */
     public function hasParentClass()
     {
         return ($this->classScanner->getParentClass() != null);
     }
 
+    /**
+     * Get parent class
+     *
+     * @return null|string
+     */
     public function getParentClass()
     {
         return $this->classScanner->getParentClass();
     }
 
+    /**
+     * Get interfaces
+     *
+     * @param bool $returnClassScanners
+     * @return array
+     */
     public function getInterfaces($returnClassScanners = false)
     {
         if ($returnClassScanners) {
@@ -110,6 +175,11 @@ class DerivedClassScanner extends ClassScanner
         return $interfaces;
     }
 
+    /**
+     * Get constants
+     *
+     * @return array
+     */
     public function getConstants()
     {
         $constants = $this->classScanner->getConstants();
@@ -119,6 +189,12 @@ class DerivedClassScanner extends ClassScanner
         return $constants;
     }
 
+    /**
+     * Get properties
+     *
+     * @param bool $returnScannerProperty
+     * @return array
+     */
     public function getProperties($returnScannerProperty = false)
     {
         $properties = $this->classScanner->getProperties($returnScannerProperty);
@@ -128,6 +204,11 @@ class DerivedClassScanner extends ClassScanner
         return $properties;
     }
 
+    /**
+     * Get method names
+     *
+     * @return array
+     */
     public function getMethodNames()
     {
         $methods = $this->classScanner->getMethodNames();
@@ -138,6 +219,8 @@ class DerivedClassScanner extends ClassScanner
     }
 
     /**
+     * Get methods
+     *
      * @return MethodScanner[]
      */
     public function getMethods()
@@ -149,6 +232,13 @@ class DerivedClassScanner extends ClassScanner
         return $methods;
     }
 
+    /**
+     * Get method
+     *
+     * @param int|string $methodNameOrInfoIndex
+     * @return MethodScanner
+     * @throws Exception\InvalidArgumentException
+     */
     public function getMethod($methodNameOrInfoIndex)
     {
         if ($this->classScanner->hasMethod($methodNameOrInfoIndex)) {
@@ -166,6 +256,12 @@ class DerivedClassScanner extends ClassScanner
                                                      ));
     }
 
+    /**
+     * Check for method
+     *
+     * @param string $name
+     * @return bool
+     */
     public function hasMethod($name)
     {
         if ($this->classScanner->hasMethod($name)) {

Added phpdoc to Zend\Code