Skip to content
This repository has been archived by the owner on Jan 8, 2020. It is now read-only.

Commit

Permalink
Merge branch 'feature/5262' into develop
Browse files Browse the repository at this point in the history
Close #5262
  • Loading branch information
weierophinney committed Oct 23, 2013
2 parents a88c4e7 + 74b677b commit 56c9c8c
Show file tree
Hide file tree
Showing 6 changed files with 267 additions and 4 deletions.
65 changes: 64 additions & 1 deletion library/Zend/Code/Reflection/FunctionReflection.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,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
*
Expand Down Expand Up @@ -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)
Expand All @@ -69,6 +79,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
*
Expand Down Expand Up @@ -104,6 +166,7 @@ public function getReturn()
}

$tag = $docBlock->getTag('return');

return new DocBlockReflection('@return ' . $tag->getDescription());
}

Expand Down
67 changes: 66 additions & 1 deletion library/Zend/Code/Reflection/MethodReflection.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,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
*/
Expand Down Expand Up @@ -88,6 +98,61 @@ public function getDeclaringClass()
return $zendReflection;
}

/**
* 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
*
Expand All @@ -114,7 +179,7 @@ public function getParameters()
/**
* Get method contents
*
* @param bool $includeDocBlock
* @param bool $includeDocBlock
* @return string
*/
public function getContents($includeDocBlock = true)
Expand Down
28 changes: 28 additions & 0 deletions tests/ZendTest/Code/Reflection/FunctionReflectionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,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));
}
}
83 changes: 83 additions & 0 deletions tests/ZendTest/Code/Reflection/MethodReflectionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,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));
}
}
24 changes: 24 additions & 0 deletions tests/ZendTest/Code/Reflection/TestAsset/TestSampleClass12.php
Original file line number Diff line number Diff line change
@@ -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';
}
}
4 changes: 2 additions & 2 deletions tests/ZendTest/Code/Reflection/TestAsset/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,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')
Expand Down

0 comments on commit 56c9c8c

Please sign in to comment.