Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Zend code method prototype #5262

Closed
wants to merge 6 commits into from

2 participants

@blanchonvincent

$reflectionMethod->getPrototype() will return an array :

'namespace' => 'ZendTest\Code\Reflection\TestAsset',
'class' => 'TestSampleClass12',
'name' => 'doSomething',
'visibility' => 'public',
'return' => 'string',
'arguments' => array(
    'one' => array(
        'type'     => 'int',
        'required' => true,
        'by_ref'   => true,
        'default'  => null,
    ),
    'two' => array(
        'type'     => 'int',
        'required' => true,
        'by_ref'   => false,
        'default'  => null,
    ),
),

$reflectionMethod->getPrototype(MethodReflection::PROTOTYPE_AS_STRING) will return an string :

public string doSomething(int &$one, int $two)
@blanchonvincent

@Ocramius Please, have a look

@blanchonvincent blanchonvincent referenced this pull request in Ocramius/ProxyManager
Open

[TO BE MOVED] Parametric polymorphism proxy / Object method extensions #103

7 of 7 tasks complete
@weierophinney

Awesome -- this will allow us to deprecate/remove much if not most of the Zend\Server\Reflection functionality!

@weierophinney

Merged to develop for release with 2.3.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
View
65 library/Zend/Code/Reflection/FunctionReflection.php
@@ -15,6 +15,16 @@
class FunctionReflection extends ReflectionFunction implements ReflectionInterface
{
/**
+ * Constant use in @MethodReflection to display prototype as an array
+ */
+ const PROTOTYPE_AS_ARRAY = 'prototype_as_array';
+
+ /**
+ * Constant use in @MethodReflection to display prototype as a string
+ */
+ const PROTOTYPE_AS_STRING = 'prototype_as_string';
+
+ /**
* Get function DocBlock
*
* @throws Exception\InvalidArgumentException
@@ -54,7 +64,7 @@ public function getStartLine($includeDocComment = false)
/**
* Get contents of function
*
- * @param bool $includeDocBlock
+ * @param bool $includeDocBlock
* @return string
*/
public function getContents($includeDocBlock = true)
@@ -70,6 +80,58 @@ public function getContents($includeDocBlock = true)
}
/**
+ * Get method prototype
+ *
+ * @return array
+ */
+ public function getPrototype($format = FunctionReflection::PROTOTYPE_AS_ARRAY)
+ {
+ $returnType = 'mixed';
+ $docBlock = $this->getDocBlock();
+ if ($docBlock) {
+ /** @var Zend\Code\Reflection\DocBlock\Tag\ReturnTag $return */
+ $return = $docBlock->getTag('return');
+ $returnTypes = $return->getTypes();
+ $returnType = count($returnTypes) > 1 ? implode('|', $returnTypes) : $returnTypes[0];
+ }
+
+ $prototype = array(
+ 'namespace' => $this->getNamespaceName(),
+ 'name' => substr($this->getName(), strlen($this->getNamespaceName()) + 1),
+ 'return' => $returnType,
+ 'arguments' => array(),
+ );
+
+ $parameters = $this->getParameters();
+ foreach ($parameters as $parameter) {
+ $prototype['arguments'][$parameter->getName()] = array(
+ 'type' => $parameter->getType(),
+ 'required' => !$parameter->isOptional(),
+ 'by_ref' => $parameter->isPassedByReference(),
+ 'default' => $parameter->isDefaultValueAvailable() ? $parameter->getDefaultValue() : null,
+ );
+ }
+
+ if ($format == FunctionReflection::PROTOTYPE_AS_STRING) {
+ $line = $prototype['return'] . ' ' . $prototype['name'] . '(';
+ $args = array();
+ foreach ($prototype['arguments'] as $name => $argument) {
+ $argsLine = ($argument['type'] ? $argument['type'] . ' ' : '') . ($argument['by_ref'] ? '&' : '') . '$' . $name;
+ if (!$argument['required']) {
+ $argsLine .= ' = ' . var_export($argument['default'], true);
+ }
+ $args[] = $argsLine;
+ }
+ $line .= implode(', ', $args);
+ $line .= ')';
+
+ return $line;
+ }
+
+ return $prototype;
+ }
+
+ /**
* Get function parameters
*
* @return ParameterReflection[]
@@ -104,6 +166,7 @@ public function getReturn()
}
$tag = $docBlock->getTag('return');
+
return new DocBlockReflection('@return ' . $tag->getDescription());
}
View
68 library/Zend/Code/Reflection/MethodReflection.php
@@ -10,7 +10,6 @@
namespace Zend\Code\Reflection;
use ReflectionMethod as PhpReflectionMethod;
-use Zend\Code\Annotation\AnnotationCollection;
use Zend\Code\Annotation\AnnotationManager;
use Zend\Code\Scanner\AnnotationScanner;
use Zend\Code\Scanner\CachingFileScanner;
@@ -18,6 +17,16 @@
class MethodReflection extends PhpReflectionMethod implements ReflectionInterface
{
/**
+ * Constant use in @MethodReflection to display prototype as an array
+ */
+ const PROTOTYPE_AS_ARRAY = 'prototype_as_array';
+
+ /**
+ * Constant use in @MethodReflection to display prototype as a string
+ */
+ const PROTOTYPE_AS_STRING = 'prototype_as_string';
+
+ /**
* @var AnnotationScanner
*/
protected $annotations = null;
@@ -90,6 +99,61 @@ public function getDeclaringClass()
}
/**
+ * Get method prototype
+ *
+ * @return array
+ */
+ public function getPrototype($format = MethodReflection::PROTOTYPE_AS_ARRAY)
+ {
+ $returnType = 'mixed';
+ $docBlock = $this->getDocBlock();
+ if ($docBlock) {
+ /** @var Zend\Code\Reflection\DocBlock\Tag\ReturnTag $return */
+ $return = $docBlock->getTag('return');
+ $returnTypes = $return->getTypes();
+ $returnType = count($returnTypes) > 1 ? implode('|', $returnTypes) : $returnTypes[0];
+ }
+
+ $declaringClass = $this->getDeclaringClass();
+ $prototype = array(
+ 'namespace' => $declaringClass->getNamespaceName(),
+ 'class' => substr($declaringClass->getName(), strlen($declaringClass->getNamespaceName()) + 1),
+ 'name' => $this->getName(),
+ 'visibility' => ($this->isPublic() ? 'public' : ($this->isPrivate() ? 'private' : 'protected')),
+ 'return' => $returnType,
+ 'arguments' => array(),
+ );
+
+ $parameters = $this->getParameters();
+ foreach ($parameters as $parameter) {
+ $prototype['arguments'][$parameter->getName()] = array(
+ 'type' => $parameter->getType(),
+ 'required' => !$parameter->isOptional(),
+ 'by_ref' => $parameter->isPassedByReference(),
+ 'default' => $parameter->isDefaultValueAvailable() ? $parameter->getDefaultValue() : null,
+ );
+ }
+
+ if ($format == MethodReflection::PROTOTYPE_AS_STRING) {
+ $line = $prototype['visibility'] . ' ' . $prototype['return'] . ' ' . $prototype['name'] . '(';
+ $args = array();
+ foreach ($prototype['arguments'] as $name => $argument) {
+ $argsLine = ($argument['type'] ? $argument['type'] . ' ' : '') . ($argument['by_ref'] ? '&' : '') . '$' . $name;
+ if (!$argument['required']) {
+ $argsLine .= ' = ' . var_export($argument['default'], true);
+ }
+ $args[] = $argsLine;
+ }
+ $line .= implode(', ', $args);
+ $line .= ')';
+
+ return $line;
+ }
+
+ return $prototype;
+ }
+
+ /**
* Get all method parameter reflection objects
*
* @return ParameterReflection[]
@@ -115,7 +179,7 @@ public function getParameters()
/**
* Get method contents
*
- * @param bool $includeDocBlock
+ * @param bool $includeDocBlock
* @return string
*/
public function getContents($includeDocBlock = true)
View
28 tests/ZendTest/Code/Reflection/FunctionReflectionTest.php
@@ -35,4 +35,32 @@ public function testFunctionDocBlockReturn()
$function = new FunctionReflection('ZendTest\Code\Reflection\TestAsset\function6');
$this->assertInstanceOf('Zend\Code\Reflection\DocBlockReflection', $function->getDocBlock());
}
+
+ public function testGetPrototypeMethod()
+ {
+ require_once __DIR__ . '/TestAsset/functions.php';
+
+ $function = new FunctionReflection('ZendTest\Code\Reflection\TestAsset\function2');
+ $prototype = array(
+ 'namespace' => 'ZendTest\Code\Reflection\TestAsset',
+ 'name' => 'function2',
+ 'return' => 'string',
+ 'arguments' => array(
+ 'one' => array(
+ 'type' => 'string',
+ 'required' => true,
+ 'by_ref' => false,
+ 'default' => null,
+ ),
+ 'two' => array(
+ 'type' => 'string',
+ 'required' => false,
+ 'by_ref' => false,
+ 'default' => 'two',
+ ),
+ ),
+ );
+ $this->assertEquals($prototype, $function->getPrototype());
+ $this->assertEquals('string function2(string $one, string $two = \'two\')', $function->getPrototype(FunctionReflection::PROTOTYPE_AS_STRING));
+ }
}
View
83 tests/ZendTest/Code/Reflection/MethodReflectionTest.php
@@ -59,4 +59,87 @@ public function testGetContentsReturnsCorrectContent()
$this->assertEquals(" {\n\n return 'mixedValue';\n\n }\n", $reflectionMethod->getContents(false));
}
+ public function testGetPrototypeMethod()
+ {
+ $reflectionMethod = new MethodReflection('ZendTest\Code\Reflection\TestAsset\TestSampleClass10', 'doSomethingElse');
+ $prototype = array(
+ 'namespace' => 'ZendTest\Code\Reflection\TestAsset',
+ 'class' => 'TestSampleClass10',
+ 'name' => 'doSomethingElse',
+ 'visibility' => 'public',
+ 'return' => 'int',
+ 'arguments' => array(
+ 'one' => array(
+ 'type' => 'int',
+ 'required' => true,
+ 'by_ref' => false,
+ 'default' => null,
+ ),
+ 'two' => array(
+ 'type' => 'int',
+ 'required' => false,
+ 'by_ref' => false,
+ 'default' => 2,
+ ),
+ 'three' => array(
+ 'type' => 'string',
+ 'required' => false,
+ 'by_ref' => false,
+ 'default' => 'three',
+ ),
+ ),
+ );
+ $this->assertEquals($prototype, $reflectionMethod->getPrototype());
+ $this->assertEquals('public int doSomethingElse(int $one, int $two = 2, string $three = \'three\')', $reflectionMethod->getPrototype(MethodReflection::PROTOTYPE_AS_STRING));
+
+ $reflectionMethod = new MethodReflection('ZendTest\Code\Reflection\TestAsset\TestSampleClass2', 'getProp2');
+ $prototype = array(
+ 'namespace' => 'ZendTest\Code\Reflection\TestAsset',
+ 'class' => 'TestSampleClass2',
+ 'name' => 'getProp2',
+ 'visibility' => 'public',
+ 'return' => 'mixed',
+ 'arguments' => array(
+ 'param1' => array(
+ 'type' => '',
+ 'required' => true,
+ 'by_ref' => false,
+ 'default' => null,
+ ),
+ 'param2' => array(
+ 'type' => 'ZendTest\Code\Reflection\TestAsset\TestSampleClass',
+ 'required' => true,
+ 'by_ref' => false,
+ 'default' => null,
+ ),
+ ),
+ );
+ $this->assertEquals($prototype, $reflectionMethod->getPrototype());
+ $this->assertEquals('public mixed getProp2($param1, ZendTest\Code\Reflection\TestAsset\TestSampleClass $param2)', $reflectionMethod->getPrototype(MethodReflection::PROTOTYPE_AS_STRING));
+
+ $reflectionMethod = new MethodReflection('ZendTest\Code\Reflection\TestAsset\TestSampleClass12', 'doSomething');
+ $prototype = array(
+ 'namespace' => 'ZendTest\Code\Reflection\TestAsset',
+ 'class' => 'TestSampleClass12',
+ 'name' => 'doSomething',
+ 'visibility' => 'protected',
+ 'return' => 'string',
+ 'arguments' => array(
+ 'one' => array(
+ 'type' => 'int',
+ 'required' => true,
+ 'by_ref' => true,
+ 'default' => null,
+ ),
+ 'two' => array(
+ 'type' => 'int',
+ 'required' => true,
+ 'by_ref' => false,
+ 'default' => null,
+ ),
+ ),
+ );
+ $this->assertEquals($prototype, $reflectionMethod->getPrototype());
+ $this->assertEquals('protected string doSomething(int &$one, int $two)', $reflectionMethod->getPrototype(MethodReflection::PROTOTYPE_AS_STRING));
+ }
}
View
24 tests/ZendTest/Code/Reflection/TestAsset/TestSampleClass12.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace ZendTest\Code\Reflection\TestAsset;
+
+class TestSampleClass12
+{
+ /**
+ *
+ * @param int $one
+ * @param int $two
+ * @return string
+ */
+ protected function doSomething(&$one, $two)
+ {
+ return 'mixedValue';
+ }
+}
View
4 tests/ZendTest/Code/Reflection/TestAsset/functions.php
@@ -21,8 +21,8 @@ function function1()
*
* This is the long description for funciton two
*
- * @param unknown_type $one
- * @param unknown_type $two
+ * @param string $one
+ * @param string $two
* @return string
*/
function function2($one, $two = 'two')
Something went wrong with that request. Please try again.