123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300 |
- <?php
- /**
- * Laravel IDE Helper Generator
- *
- * @author Barry vd. Heuvel <barryvdh@gmail.com>
- * @copyright 2014 Barry vd. Heuvel / Fruitcake Studio (http://www.fruitcakestudio.nl)
- * @license http://www.opensource.org/licenses/mit-license.php MIT
- * @link https://github.com/barryvdh/laravel-ide-helper
- */
-
- namespace Barryvdh\LaravelIdeHelper;
-
- use phpDocumentor\Reflection\DocBlock;
- use phpDocumentor\Reflection\DocBlock\Context;
- use phpDocumentor\Reflection\DocBlock\Tag;
- use phpDocumentor\Reflection\DocBlock\Tag\ReturnTag;
- use phpDocumentor\Reflection\DocBlock\Tag\ParamTag;
- use phpDocumentor\Reflection\DocBlock\Serializer as DocBlockSerializer;
-
- class Method
- {
- /** @var \phpDocumentor\Reflection\DocBlock */
- protected $phpdoc;
-
- /** @var \ReflectionMethod */
- protected $method;
-
- protected $output = '';
- protected $name;
- protected $namespace;
- protected $params = array();
- protected $params_with_default = array();
- protected $interfaces = array();
- protected $return = null;
-
- /**
- * @param \ReflectionMethod $method
- * @param string $alias
- * @param string $class
- * @param string|null $methodName
- * @param array $interfaces
- */
- public function __construct(\ReflectionMethod $method, $alias, $class, $methodName = null, $interfaces = array())
- {
- $this->method = $method;
- $this->interfaces = $interfaces;
- $this->name = $methodName ?: $method->name;
- $this->namespace = $method->getDeclaringClass()->getNamespaceName();
-
- //Create a DocBlock and serializer instance
- $this->phpdoc = new DocBlock($method, new Context($this->namespace));
-
- //Normalize the description and inherit the docs from parents/interfaces
- try {
- $this->normalizeDescription();
- $this->normalizeParams();
- $this->normalizeReturn();
- } catch (\Exception $e) {}
-
- //Get the parameters, including formatted default values
- $this->getParameters($method);
-
- //Make the method static
- $this->phpdoc->appendTag(Tag::createInstance('@static', $this->phpdoc));
-
- //Reference the 'real' function in the declaringclass
- $declaringClass = $method->getDeclaringClass();
- $this->declaringClassName = '\\' . ltrim($declaringClass->name, '\\');
- $this->root = '\\' . ltrim($class->getName(), '\\');
- }
-
- /**
- * Get the class wherein the function resides
- *
- * @return string
- */
- public function getDeclaringClass()
- {
- return $this->declaringClassName;
- }
-
- /**
- * Return the class from which this function would be called
- *
- * @return string
- */
- public function getRoot()
- {
- return $this->root;
- }
-
- /**
- * Get the docblock for this method
- *
- * @param string $prefix
- * @return mixed
- */
- public function getDocComment($prefix = "\t\t")
- {
- $serializer = new DocBlockSerializer(1, $prefix);
- return $serializer->getDocComment($this->phpdoc);
- }
-
- /**
- * Get the method name
- *
- * @return string
- */
- public function getName()
- {
- return $this->name;
- }
-
- /**
- * Get the parameters for this method
- *
- * @param bool $implode Wether to implode the array or not
- * @return string
- */
- public function getParams($implode = true)
- {
- return $implode ? implode(', ', $this->params) : $this->params;
- }
-
- /**
- * Get the parameters for this method including default values
- *
- * @param bool $implode Wether to implode the array or not
- * @return string
- */
- public function getParamsWithDefault($implode = true)
- {
- return $implode ? implode(', ', $this->params_with_default) : $this->params_with_default;
- }
-
- /**
- * Get the description and get the inherited docs.
- *
- */
- protected function normalizeDescription()
- {
- //Get the short + long description from the DocBlock
- $description = $this->phpdoc->getText();
-
- //Loop through parents/interfaces, to fill in {@inheritdoc}
- if (strpos($description, '{@inheritdoc}') !== false) {
- $inheritdoc = $this->getInheritDoc($this->method);
- $inheritDescription = $inheritdoc->getText();
-
- $description = str_replace('{@inheritdoc}', $inheritDescription, $description);
- $this->phpdoc->setText($description);
-
- //Add the tags that are inherited
- $inheritTags = $inheritdoc->getTags();
- if ($inheritTags) {
- foreach ($inheritTags as $tag) {
- $tag->setDocBlock();
- $this->phpdoc->appendTag($tag);
- }
- }
- }
- }
-
- /**
- * Normalize the parameters
- */
- protected function normalizeParams()
- {
- //Get the return type and adjust them for beter autocomplete
- $paramTags = $this->phpdoc->getTagsByName('param');
- if ($paramTags) {
- /** @var ParamTag $tag */
- foreach($paramTags as $tag){
- // Convert the keywords
- $content = $this->convertKeywords($tag->getContent());
- $tag->setContent($content);
-
- // Get the expanded type and re-set the content
- $content = $tag->getType() . ' ' . $tag->getVariableName() . ' ' . $tag->getDescription();
- $tag->setContent(trim($content));
- }
- }
- }
-
- /**
- * Normalize the return tag (make full namespace, replace interfaces)
- */
- protected function normalizeReturn()
- {
- //Get the return type and adjust them for beter autocomplete
- $returnTags = $this->phpdoc->getTagsByName('return');
- if ($returnTags) {
- /** @var ReturnTag $tag */
- $tag = reset($returnTags);
- // Get the expanded type
- $returnValue = $tag->getType();
-
- // Replace the interfaces
- foreach($this->interfaces as $interface => $real){
- $returnValue = str_replace($interface, $real, $returnValue);
- }
-
- // Set the changed content
- $tag->setContent($returnValue . ' ' . $tag->getDescription());
- $this->return = $returnValue;
- }else{
- $this->return = null;
- }
- }
-
- /**
- * Convert keywwords that are incorrect.
- *
- * @param string $string
- * @return string
- */
- protected function convertKeywords($string)
- {
- $string = str_replace('\Closure', 'Closure', $string);
- $string = str_replace('Closure', '\Closure', $string);
- $string = str_replace('dynamic', 'mixed', $string);
-
- return $string;
- }
-
- /**
- * Should the function return a value?
- *
- * @return bool
- */
- public function shouldReturn()
- {
- if($this->return !== "void" && $this->method->name !== "__construct"){
- return true;
- }
-
- return false;
- }
-
- /**
- * Get the parameters and format them correctly
- *
- * @param $method
- * @return array
- */
- public function getParameters($method)
- {
- //Loop through the default values for paremeters, and make the correct output string
- $params = array();
- $paramsWithDefault = array();
- foreach ($method->getParameters() as $param) {
- $paramStr = '$' . $param->getName();
- $params[] = $paramStr;
- if ($param->isOptional()) {
- $default = $param->getDefaultValue();
- if (is_bool($default)) {
- $default = $default ? 'true' : 'false';
- } elseif (is_array($default)) {
- $default = 'array()';
- } elseif (is_null($default)) {
- $default = 'null';
- } elseif (is_int($default)) {
- //$default = $default;
- } else {
- $default = "'" . trim($default) . "'";
- }
- $paramStr .= " = $default";
- }
- $paramsWithDefault[] = $paramStr;
- }
-
- $this->params = $params;
- $this->params_with_default = $paramsWithDefault;
- }
-
- /**
- * @param \ReflectionMethod $reflectionMethod
- * @return string
- */
- protected function getInheritDoc($reflectionMethod)
- {
- $parentClass = $reflectionMethod->getDeclaringClass()->getParentClass();
-
- //Get either a parent or the interface
- if ($parentClass) {
- $method = $parentClass->getMethod($reflectionMethod->getName());
- } else {
- $method = $reflectionMethod->getPrototype();
- }
- if ($method) {
- $phpdoc = new DocBlock($method);
- if (strpos($phpdoc->getText(), '{@inheritdoc}') !== false) {
- //Not at the end yet, try another parent/interface..
- return $this->getInheritDoc($method);
- } else {
- return $phpdoc;
- }
- }
- }
- }
|