Skip to content

Commit

Permalink
Merge pull request #275 from dunglas/dockbloc-3
Browse files Browse the repository at this point in the history
Compatibility with phpDocumentor Reflection Dockbloc 3
  • Loading branch information
stof committed Jun 6, 2016
2 parents f9a8140 + 9a81b72 commit eec64c9
Show file tree
Hide file tree
Showing 7 changed files with 215 additions and 16 deletions.
12 changes: 11 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,16 @@ branches:
- /^feature\/.*$/
- /^optimization\/.*$/

before_script: travis_retry composer install --no-interaction
matrix:
fast_finish: true
include:
- php: '7.0'
env: PHPDOCUMENTOR_REFLECTION_DOCBLOCK="^2.0"

before_script:
- if [ -n "$PHPDOCUMENTOR_REFLECTION_DOCBLOCK" ]; then
composer require "phpdocumentor/reflection-docblock:${PHPDOCUMENTOR_REFLECTION_DOCBLOCK}" --no-update;
fi;
- travis_retry composer update --no-interaction

script: vendor/bin/phpspec run -fpretty -v
9 changes: 5 additions & 4 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,17 @@
"email": "[email protected]"
}
],

"require": {
"php": "^5.3|^7.0",
"phpdocumentor/reflection-docblock": "~2.0",
"sebastian/comparator": "~1.1",
"phpdocumentor/reflection-docblock": "^2.0|^3.0.2",
"sebastian/comparator": "^1.1",
"doctrine/instantiator": "^1.0.2",
"sebastian/recursion-context": "~1.0"
"sebastian/recursion-context": "^1.0"
},

"require-dev": {
"phpspec/phpspec": "~2.0"
"phpspec/phpspec": "^2.0"
},

"autoload": {
Expand Down
24 changes: 13 additions & 11 deletions src/Prophecy/Doubler/ClassPatch/MagicCallPatch.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,27 @@

namespace Prophecy\Doubler\ClassPatch;

use phpDocumentor\Reflection\DocBlock;
use Prophecy\Doubler\Generator\Node\ClassNode;
use Prophecy\Doubler\Generator\Node\MethodNode;
use Prophecy\PhpDocumentor\ClassAndInterfaceTagRetriever;
use Prophecy\PhpDocumentor\MethodTagRetrieverInterface;

/**
* Discover Magical API using "@method" PHPDoc format.
*
* @author Thomas Tourlourat <[email protected]>
* @author Kévin Dunglas <[email protected]>
* @author Théo FIDRY <[email protected]>
*/
class MagicCallPatch implements ClassPatchInterface
{
private $tagRetriever;

public function __construct(MethodTagRetrieverInterface $tagRetriever = null)
{
$this->tagRetriever = null === $tagRetriever ? new ClassAndInterfaceTagRetriever() : $tagRetriever;
}

/**
* Support any class
*
Expand All @@ -44,15 +54,7 @@ public function apply(ClassNode $node)
$parentClass = $node->getParentClass();
$reflectionClass = new \ReflectionClass($parentClass);

$phpdoc = new DocBlock($reflectionClass->getDocComment());

$tagList = $phpdoc->getTagsByName('method');

$interfaces = $reflectionClass->getInterfaces();
foreach($interfaces as $interface) {
$phpdoc = new DocBlock($interface);
$tagList = array_merge($tagList, $phpdoc->getTagsByName('method'));
}
$tagList = $this->tagRetriever->getTagList($reflectionClass);

foreach($tagList as $tag) {
$methodName = $tag->getMethodName();
Expand All @@ -62,7 +64,7 @@ public function apply(ClassNode $node)
}

if (!$reflectionClass->hasMethod($methodName)) {
$methodNode = new MethodNode($tag->getMethodName());
$methodNode = new MethodNode($methodName);
$methodNode->setStatic($tag->isStatic());

$node->addMethod($methodNode);
Expand Down
69 changes: 69 additions & 0 deletions src/Prophecy/PhpDocumentor/ClassAndInterfaceTagRetriever.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php

/*
* This file is part of the Prophecy.
* (c) Konstantin Kudryashov <[email protected]>
* Marcello Duarte <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Prophecy\PhpDocumentor;

use phpDocumentor\Reflection\DocBlock\Tag\MethodTag as LegacyMethodTag;
use phpDocumentor\Reflection\DocBlock\Tags\Method;

/**
* @author Théo FIDRY <[email protected]>
*
* @internal
*/
final class ClassAndInterfaceTagRetriever implements MethodTagRetrieverInterface
{
private $classRetriever;

public function __construct(MethodTagRetrieverInterface $classRetriever = null)
{
if (null !== $classRetriever) {
$this->classRetriever = $classRetriever;

return;
}

$this->classRetriever = class_exists('phpDocumentor\Reflection\DocBlockFactory') && class_exists('phpDocumentor\Reflection\Types\ContextFactory')
? new ClassTagRetriever()
: new LegacyClassTagRetriever()
;
}

/**
* @param \ReflectionClass $reflectionClass
*
* @return LegacyMethodTag[]|Method[]
*/
public function getTagList(\ReflectionClass $reflectionClass)
{
return array_merge(
$this->classRetriever->getTagList($reflectionClass),
$this->getInterfacesTagList($reflectionClass)
);
}

/**
* @param \ReflectionClass $reflectionClass
*
* @return LegacyMethodTag[]|Method[]
*/
private function getInterfacesTagList(\ReflectionClass $reflectionClass)
{
$interfaces = $reflectionClass->getInterfaces();
$tagList = array();

foreach($interfaces as $interface) {
$tagList = array_merge($tagList, $this->classRetriever->getTagList($interface));
}

return $tagList;
}
}
52 changes: 52 additions & 0 deletions src/Prophecy/PhpDocumentor/ClassTagRetriever.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

/*
* This file is part of the Prophecy.
* (c) Konstantin Kudryashov <[email protected]>
* Marcello Duarte <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Prophecy\PhpDocumentor;

use phpDocumentor\Reflection\DocBlock\Tags\Method;
use phpDocumentor\Reflection\DocBlockFactory;
use phpDocumentor\Reflection\Types\ContextFactory;

/**
* @author Théo FIDRY <[email protected]>
*
* @internal
*/
final class ClassTagRetriever implements MethodTagRetrieverInterface
{
private $docBlockFactory;
private $contextFactory;

public function __construct()
{
$this->docBlockFactory = DocBlockFactory::createInstance();
$this->contextFactory = new ContextFactory();
}

/**
* @param \ReflectionClass $reflectionClass
*
* @return Method[]
*/
public function getTagList(\ReflectionClass $reflectionClass)
{
try {
$phpdoc = $this->docBlockFactory->create(
$reflectionClass,
$this->contextFactory->createFromReflector($reflectionClass)
);

return $phpdoc->getTagsByName('method');
} catch (\InvalidArgumentException $e) {
return array();
}
}
}
35 changes: 35 additions & 0 deletions src/Prophecy/PhpDocumentor/LegacyClassTagRetriever.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

/*
* This file is part of the Prophecy.
* (c) Konstantin Kudryashov <[email protected]>
* Marcello Duarte <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Prophecy\PhpDocumentor;

use phpDocumentor\Reflection\DocBlock;
use phpDocumentor\Reflection\DocBlock\Tag\MethodTag as LegacyMethodTag;

/**
* @author Théo FIDRY <[email protected]>
*
* @internal
*/
final class LegacyClassTagRetriever implements MethodTagRetrieverInterface
{
/**
* @param \ReflectionClass $reflectionClass
*
* @return LegacyMethodTag[]
*/
public function getTagList(\ReflectionClass $reflectionClass)
{
$phpdoc = new DocBlock($reflectionClass->getDocComment());

return $phpdoc->getTagsByName('method');
}
}
30 changes: 30 additions & 0 deletions src/Prophecy/PhpDocumentor/MethodTagRetrieverInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

/*
* This file is part of the Prophecy.
* (c) Konstantin Kudryashov <[email protected]>
* Marcello Duarte <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Prophecy\PhpDocumentor;

use phpDocumentor\Reflection\DocBlock\Tag\MethodTag as LegacyMethodTag;
use phpDocumentor\Reflection\DocBlock\Tags\Method;

/**
* @author Théo FIDRY <[email protected]>
*
* @internal
*/
interface MethodTagRetrieverInterface
{
/**
* @param \ReflectionClass $reflectionClass
*
* @return LegacyMethodTag[]|Method[]
*/
public function getTagList(\ReflectionClass $reflectionClass);
}

0 comments on commit eec64c9

Please sign in to comment.