/** * @param string $class * @return string */ protected function createPhpDocs($class) { $reflection = new \ReflectionClass($class); $namespace = $reflection->getNamespaceName(); $classname = $reflection->getShortName(); $originalDoc = $reflection->getDocComment(); if ($this->reset) { $phpdoc = new DocBlock('', new Context($namespace)); } else { $phpdoc = new DocBlock($reflection, new Context($namespace)); } if (!$phpdoc->getText()) { $phpdoc->setText($class); } $properties = array(); $methods = array(); foreach ($phpdoc->getTags() as $tag) { $name = $tag->getName(); if ($name == "property" || $name == "property-read" || $name == "property-write") { $properties[] = $tag->getVariableName(); } elseif ($name == "method") { $methods[] = $tag->getMethodName(); } } foreach ($this->properties as $name => $property) { $name = "\${$name}"; if (in_array($name, $properties)) { continue; } if ($property['read'] && $property['write']) { $attr = 'property'; } elseif ($property['write']) { $attr = 'property-write'; } else { $attr = 'property-read'; } $tag = Tag::createInstance("@{$attr} {$property['type']} {$name} {$property['comment']}", $phpdoc); $phpdoc->appendTag($tag); } foreach ($this->methods as $name => $method) { if (in_array($name, $methods)) { continue; } $arguments = implode(', ', $method['arguments']); $tag = Tag::createInstance("@method static {$method['type']} {$name}({$arguments})", $phpdoc); $phpdoc->appendTag($tag); } $serializer = new DocBlockSerializer(); $serializer->getDocComment($phpdoc); $docComment = $serializer->getDocComment($phpdoc); if ($this->write) { $filename = $reflection->getFileName(); $contents = \File::get($filename); if ($originalDoc) { $contents = str_replace($originalDoc, $docComment, $contents); } else { $needle = "class {$classname}"; $replace = "{$docComment}\nclass {$classname}"; $pos = strpos($contents, $needle); if ($pos !== false) { $contents = substr_replace($contents, $replace, $pos, strlen($needle)); } } if (\File::put($filename, $contents)) { $this->info('Written new phpDocBlock to ' . $filename); } } $output = "namespace {$namespace}{\n{$docComment}\n\tclass {$classname} {}\n}\n\n"; return $output; }
/** * @return DocBlock\Tag[] */ public function getExistingTags() { $existing = $this->getExistingDocBlock(); $docBlock = $this->removeOldStyleDocBlock($existing); $docBlock = new DocBlock($docBlock); return $docBlock->getTags(); }
/** * Parses doc comment and populates comment entity * * @param string $text */ protected function parseDoc(Comment $comment, $text) { $context = $this->getContext(); try { $block = new DocBlock($text, $context); foreach ($block->getTags() as $tag) { switch ($tag->getName()) { case "param": $comment->addVar($this->createMethodParam($tag)); break; case "var": $comment->addVar($this->createVar($tag)); break; case "return": $comment->setReturn($this->getFQCN($tag->getType())); break; case "property": $comment->addProperty($this->createProperty($tag)); break; case "inheritdoc": $comment->markInheritDoc(); break; } } } catch (\Exception $e) { } }
/** * Extracts tags from docBlock and adds it to document. * * @param DocBlock $docBlock */ public function populateTags(DocBlock $docBlock) { $tags = $docBlock->getTags(); $offset = strlen(self::TAG_PREFIX); foreach ($tags as $tag) { $name = $tag->getName(); if (strpos($name, self::TAG_PREFIX) === 0) { $key = substr($name, $offset); if (!isset($this->_tags)) { $this->_tags[$key] = []; } $this->_tags[$key][] = $tag; } } }
public function enterNode(Node $node) { parent::enterNode($node); try { if ($doc = $node->getDocComment()) { $docBlock = new DocBlock($doc->getText()); if ($tagNames = $this->collectTagNamesBy($docBlock->getTags())) { $node->setAttribute(self::TAG_NAMES_ATTRIBUTE, $tagNames); } } } catch (\Exception $e) { $parseError = new Error($e->getMessage(), $node->getLine()); $this->logger->warning($parseError->getMessage(), array($this->file)); } }
/** * Assemble DocBlock. * * @param DocBlock|null $docBlock * @param DescriptorAbstract $target * * @return void */ protected function assembleDocBlock($docBlock, $target) { if (!$docBlock) { return; } $target->setSummary($docBlock->getShortDescription()); $target->setDescription($docBlock->getLongDescription()->getContents()); /** @var DocBlock\Tag $tag */ foreach ($docBlock->getTags() as $tag) { $tagDescriptor = $this->builder->buildDescriptor($tag); // allow filtering of tags if (!$tagDescriptor) { continue; } $target->getTags()->get($tag->getName(), new Collection())->add($tagDescriptor); } }
/** * Create arguments from your executeCommand method parameters * * @param \ReflectionClass $class * * @return bool|null */ protected function createFromActionableMethod(\ReflectionClass $class) { if ($class->hasMethod('executeCommand')) { $methodName = 'executeCommand'; } else { if ($class->hasMethod('process')) { $methodName = 'process'; } else { return null; } } $method = $class->getMethod($methodName); $addedArguments = false; $propBlock = new DocBlock($method); $descriptions = []; foreach ($propBlock->getTags() as $tag) { if ($tag instanceof ParamTag) { $tagName = substr($tag->getVariableName(), 1); $descriptions[$tagName] = $tag->getDescription(); } } foreach ($method->getParameters() as $paramNum => $parameter) { //Skip over the input and output args for executeCommand if ($paramNum < 2 && $methodName == 'executeCommand') { continue; } $mode = InputArgument::REQUIRED; $default = null; if ($parameter->isDefaultValueAvailable()) { $mode = InputArgument::OPTIONAL; $default = $parameter->getDefaultValue(); } $description = ''; if (isset($descriptions[$parameter->getName()])) { $description = $descriptions[$parameter->getName()]; } $this->addArgument($parameter->getName(), $parameter->isArray() ? $mode | InputArgument::IS_ARRAY : $mode, $description, $default); $addedArguments = true; } return $addedArguments; }
public function parse($comment, ParserContext $context) { $docBlock = null; $errorMessage = ''; try { $docBlockContext = new DocBlock\Context($context->getNamespace(), $context->getAliases() ?: array()); $docBlock = new DocBlock((string) $comment, $docBlockContext); } catch (\Exception $e) { $errorMessage = $e->getMessage(); } $result = new DocBlockNode(); if ($errorMessage) { $result->addError($errorMessage); return $result; } $result->setShortDesc($docBlock->getShortDescription()); $result->setLongDesc((string) $docBlock->getLongDescription()); foreach ($docBlock->getTags() as $tag) { $result->addTag($tag->getName(), $this->parseTag($tag)); } return $result; }
public function fetchMethod($className, $method) { $phpdoc = new DocBlock($method->getDocComment()); $call = array(); $params = array(); $return = null; // build the call example string foreach ($method->getParameters() as $param) { if ($param->isOptional()) { try { $value = var_export($param->getDefaultValue(), true); $value = str_replace(PHP_EOL, '', $value); $value = str_replace('NULL', 'null', $value); $value = str_replace('array ()', 'array()', $value); $call[] = '$' . $param->getName() . ' = ' . $value; } catch (Exception $e) { $call[] = '$' . $param->getName(); } } else { $call[] = '$' . $param->getName(); } } // get all parameter docs foreach ($phpdoc->getTags() as $tag) { switch ($tag->getName()) { case 'param': $params[] = array('name' => $tag->getVariableName(), 'type' => $tag->getType(), 'text' => $tag->getDescription()); break; case 'return': $return = array('type' => $tag->getType(), 'text' => $tag->getDescription()); break; } } // a::first $methodName = strtolower($className) . '::' . $method->getName(); $methodSlug = str::slug($method->getName()); // build the full method array return array('name' => $methodName, 'slug' => $methodSlug, 'excerpt' => str_replace(PHP_EOL, ' ', $phpdoc->getShortDescription()), 'call' => $methodName . '(' . implode(', ', $call) . ')', 'return' => $return, 'params' => $params); }
/** * @param array $options * @param array $method * @param string $className * @param string $file * * @return Result */ private function processMethod(array $options, array $method, $className, $file) { $result = new Result(); if ($method['docblock'] === null) { if ($options['missing_docblock'] !== null) { $result->addIssue($this->issueFactory->createIssueForMissingDocblock($options, $method, $className, $file)); } return $result; } $docBlock = new DocBlock($method['docblock']); $tagsInDocblock = $docBlock->getTags(); $signature = new FunctionSignature($method['signature']); if ($options['type_missmatch'] !== null) { foreach ($this->differ->inDocBlockAndSignature($tagsInDocblock, $signature) as $params) { /** @var DocBlock\Tag\ParamTag $docBlockParam */ $docBlockParam = $params[0]; /** @var FunctionParameter $functionParameter */ $functionParameter = $params[1]; if (!$this->differ->equalTypes($functionParameter, $docBlockParam)) { if (!$functionParameter->type) { $result->addIssue($this->issueFactory->createIssueForMissingTypeInSignature($options, $method, $className, $file, $functionParameter)); } elseif (!$docBlockParam->getType()) { $result->addIssue($this->issueFactory->createIssueForMissingTypeInDocBlock($options, $method, $className, $file, $docBlockParam)); } else { $result->addIssue($this->issueFactory->createIssueForMismatchingTypes($options, $method, $className, $file, $functionParameter, $docBlockParam)); } } } } if ($options['obsolete_variable'] !== null) { foreach ($this->differ->inDocblockOnly($tagsInDocblock, $signature) as $param) { $result->addIssue($this->issueFactory->createIssueForObsoleteVariable($options, $method, $className, $file, $param->getContent())); } } if ($options['missing_variable'] !== null) { foreach ($this->differ->inSignatureOnly($tagsInDocblock, $signature) as $param) { $result->addIssue($this->issueFactory->createIssueForMissingVariable($options, $method, $className, $file, $param)); } } return $result; }
/** * Builds the Input Definition based upon Api Method Parameters. * * @param \ReflectionMethod $method * @param string $token * * @return InputDefinition */ private function buildDefinition(\ReflectionMethod $method, DocBlock $docBlock, $token = null) { $definition = new InputDefinition(); foreach ($docBlock->getTags() as $tag) { if ($tag instanceof DocBlock\Tags\Param) { $tagsDescription[$tag->getVariableName()] = $tag->getDescription()->render(); } } foreach ($method->getParameters() as $parameter) { if ($parameter->isDefaultValueAvailable()) { //option $definition->addOption(new InputOption($parameter->getName(), null, InputOption::VALUE_REQUIRED, $tagsDescription[$parameter->getName()], $parameter->isDefaultValueAvailable() ? $parameter->getDefaultValue() : null)); } else { //argument $definition->addArgument(new InputArgument($parameter->getName(), InputArgument::REQUIRED, $tagsDescription[$parameter->getName()], null)); } } $definition->addOption(new InputOption('token', null, InputOption::VALUE_REQUIRED, 'Auth token to use', $token)); $definition->addOption(new InputOption('debug', null, InputOption::VALUE_NONE, 'Display raw response')); return $definition; }
/** * @depends testConstructWithTagsOnly * @covers \phpDocumentor\Reflection\DocBlock::parseTags * * @return void */ public function testParseMultilineTagWithLineBreaks() { $fixture = <<<DOCBLOCK /** * @return void Content on * multiple lines. * * One more, after the break. */ DOCBLOCK; $object = new DocBlock($fixture); $this->assertCount(1, $object->getTags()); }
/** * Gets all Tag Annotations in a DocBlock. * @param Reflector $reflector Supporting the getDocComment method. * @return Tag[] * @todo Perhaps try to recognize a Tag as an Annotation and ignore it? */ protected function getTagAnnotations(Reflector $reflector) { $context = $this->getContextFromReflector($reflector); $docBlock = new DocBlock($reflector, $context); $tags = $docBlock->getTags(); $tagAnnotations = array(); foreach ($tags as $tag) { /* @var $tag Tag */ $tagAnnotation = $this->createTagAnnotation($tag); if ($tagAnnotation) { $tagAnnotations[] = $tagAnnotation; } } return $tagAnnotations; }
/** * Process an individual file * * @param string $file File path * @return array Processed endpoints */ private function processFile($file) { // var to hold output $output = array(); require_once $file; $className = $this->parseClassFromFile($file); $component = $this->parseClassFromFile($file, true)['component']; $version = $this->parseClassFromFile($file, true)['version']; // Push file to files array $this->output['files'][] = $file; // Push version to versions array $this->output['versions']['available'][] = $version; if (!class_exists($className)) { return $output; } $classReflector = new ReflectionClass($className); foreach ($classReflector->getMethods() as $method) { // Create docblock object & make sure we have something $phpdoc = new DocBlock($method); // Skip methods we don't want processed if (substr($method->getName(), -4) != 'Task' || in_array($method->getName(), array('registerTask', 'unregisterTask', 'indexTask'))) { continue; } // Skip method in the parent class (already processed), if ($className != $method->getDeclaringClass()->getName()) { //continue; } // Skip if we dont have a short desc // but put in error if (!$phpdoc->getShortDescription()) { $this->output['errors'][] = sprintf('Missing docblock for method "%s" in "%s"', $method->getName(), $file); continue; } // Create endpoint data array $endpoint = array('name' => $phpdoc->getShortDescription(), 'description' => $phpdoc->getLongDescription()->getContents(), 'method' => '', 'uri' => '', 'parameters' => array(), '_metadata' => array('component' => $component, 'version' => $version, 'method' => $method->getName())); // Loop through each tag foreach ($phpdoc->getTags() as $tag) { $name = strtolower(str_replace('api', '', $tag->getName())); $content = $tag->getContent(); // Handle parameters separately // json decode param input if ($name == 'parameter') { $parameter = json_decode($content); if (json_last_error() != JSON_ERROR_NONE) { $this->output['errors'][] = sprintf('Unable to parse parameter info for method "%s" in "%s"', $method->getName(), $file); continue; } $endpoint['parameters'][] = (array) $parameter; continue; } if ($name == 'uri' && $method->getName() == 'indexTask') { $content .= $component; } // Add data to endpoint data $endpoint[$name] = $content; } // Add endpoint to output // We always want indexTask to be first in the list if ($method->getName() == 'indexTask') { array_unshift($output, $endpoint); } else { $output[] = $endpoint; } } return $output; }
/** * Generate a DocBlock comment. * * @param DocBlock The DocBlock to serialize. * * @return string The serialized doc block. */ public function getDocComment(DocBlock $docblock) { $indent = str_repeat($this->indentString, $this->indent); $firstIndent = $this->isFirstLineIndented ? $indent : ''; $text = $docblock->getText(); if ($this->lineLength) { //3 === strlen(' * ') $wrapLength = $this->lineLength - strlen($indent) - 3; $text = wordwrap($text, $wrapLength); } $text = str_replace("\n", "\n{$indent} * ", $text); $comment = "{$firstIndent}/**\n{$indent} * {$text}\n{$indent} *\n"; /** @var Tag $tag */ foreach ($docblock->getTags() as $tag) { $tagText = (string) $tag; if ($this->lineLength) { $tagText = wordwrap($tagText, $wrapLength); } $tagText = str_replace("\n", "\n{$indent} * ", $tagText); $comment .= "{$indent} * {$tagText}\n"; } $comment .= $indent . ' */'; return $comment; }
/** * @param DocBlock $phpdoc * @param Param $param * @param string $actualNamespace * @param array $use * @param array $classes * * @return null|array */ private function foundTypeInCommentForVar(DocBlock $phpdoc, Param $param, ClassMetadata $classMetadata) { foreach ($phpdoc->getTags() as $tag) { if ($tag instanceof \phpDocumentor\Reflection\DocBlock\Tag\ParamTag) { if ($param->name === substr($tag->getVariableName(), 1)) { return $this->findType($tag); } } } return; }
/** * @param DocBlock $docblock * @param $wrapLength * @param $indent * @param $comment * @return string */ private function addTagBlock(DocBlock $docblock, $wrapLength, $indent, $comment) { foreach ($docblock->getTags() as $tag) { $formatter = new DocBlock\Tags\Formatter\PassthroughFormatter(); $tagText = $formatter->format($tag); if ($wrapLength !== null) { $tagText = wordwrap($tagText, $wrapLength); } $tagText = str_replace("\n", "\n{$indent} * ", $tagText); $comment .= "{$indent} * {$tagText}\n"; } return $comment; }
/** * Retrieve all examples from a class Doc Block. * * Example: * ``` * $examples = $parser->examplesFromClass($parser); * ``` * * @param object|ReflectionClass $class An instance or reflector of the * class to parse examples from. * @return array */ public function examplesFromClass($class) { if (!$class instanceof ReflectionClass) { $class = new ReflectionClass($class); } $doc = new DocBlock($class); $magic = []; if ($doc->getTags()) { $magicMethods = array_filter($doc->getTags(), function ($tag) { return $tag->getName() === 'method'; }); $methods = $this->buildMagicMethods($magicMethods, $class->getName()); foreach ($methods as $method) { $res = current($this->examples($method['doc'], $class->getName() . '::' . $method['name'], $class->getFileName(), $class->getStartLine())); $magic[$res->identifier()] = $res; } } return $this->examples($doc, $class->getName(), $class->getFileName(), $class->getStartLine(), $magic); }
/** * @param string $actualNamespace * @param array $definition * @param array $use * @param array $classes * @param DocBlock $phpdoc * * @return array */ private function findReturnTag($phpdoc, $actualNamespace, array $definition, array $use, array $classes) { foreach ($phpdoc->getTags() as $tag) { if ($this->isReturnTag($tag) === true) { $definition['return'] = array('type' => $this->findType($tag, $actualNamespace, $use, $classes)); break; } } return $definition; }
/** * @covers ::__construct * @covers ::getTags * * @uses \phpDocumentor\Reflection\DocBlock\Description * @uses \phpDocumentor\Reflection\DocBlock\Tag */ public function testDocBlockCanHaveTags() { $tags = [m::mock(DocBlock\Tag::class)]; $fixture = new DocBlock('', null, $tags); $this->assertSame($tags, $fixture->getTags()); }
protected function buildNodeData(DocBlock $node) { $data = ['group' => null, 'method' => null, 'uri' => null, 'title' => null, 'scope' => [], 'description' => null, 'version' => ['major' => 0, 'minor' => 0, 'patch' => 0], 'params' => ['Default' => []], 'headers' => [], 'returns' => [], 'throws' => []]; $tags = []; foreach ($node->getTags() as $tag) { if ($tag->getName() === 'api-include') { $tags = array_merge($tags, $this->templates[$tag->getKey()]->getTags()); } else { $tags[] = $tag; } } foreach ($tags as $tag) { switch ($tag->getName()) { case 'api-group': $data['group'] = $tag->getGroup(); break; case 'api-method': $data['method'] = $tag->getMethod(); break; case 'api-uri': $data['uri'] = $tag->getUri(); break; case 'api-title': $data['title'] = (string) $tag->getTitle(); break; case 'api-scope': $data['scope'] = $tag->getScope(); break; case 'api-desc': case 'api-description': $data['description'] = (string) $tag->getDescription(); break; case 'api-version': $data['version'] = $tag->getVersion(); break; case 'api-param': if (is_null($tag->getGroup())) { $data['params']['Default'][] = $tag->getParam(); } else { $data['params'][$tag->getGroup()][] = $tag->getParam(); } break; case 'api-header': $data['headers'][] = $tag->getParam(); break; case 'api-return': $data['returns'][] = $tag->getReturn(); break; case 'api-throws': $data['throws'][] = $tag->getThrows(); break; } } return $data; }
/** * Retrieve the properties for the class. * * @return array A list of properties. */ public function getMethods() { $rclass_methods = $this->class->getMethods(); // Add methods and parameters $rclass_methods = array_values(array_filter($rclass_methods, function ($rmethod) { if ($exclusions = ConfigStore::get('source.exclude.methods')) { return !preg_match($exclusions, $rmethod->getName()); } return true; })); foreach ($rclass_methods as $rmethod) { $documentThis = true; if (!isset($this->methods['count'])) { $this->methods['count'] = count($rclass_methods); } if (!isset($this->methods['method'])) { $this->methods['method'] = array(); } $rmethod = InheritdocHandler::resolve($rmethod); $_tags = new TagHandler($rmethod->getDocComment(), $this->ancestry); $method_docblock = new DocBlock($rmethod->getDocComment()); $entry = array(); $entry['name'] = $rmethod->getName(); $entry['visibility'] = $this->methodAccess($rmethod); if ($extension = $rmethod->getExtensionName()) { $entry['extension'] = $extension; DependencyCollector::add($extension); } if ($rmethod->getFileName()) { $entry['path'] = str_replace(array(VANITY_SYSTEM . '/', VANITY_PROJECT_WORKING_DIR . '/'), '', $rmethod->getFileName()); $entry['lines'] = array('start' => $rmethod->getStartLine(), 'end' => $rmethod->getEndLine()); if ($viewsource = ConfigStore::get('source.viewsource')) { $entry['viewsource'] = str_replace(array('%PATH%', '%LINE%'), array($entry['path'], $entry['lines']['start']), $viewsource); } } if ($description = $_tags->getDescription()) { $entry['description'] = $description; } // Method inheritance if (($declaring_class = $rmethod->getDeclaringClass()->getName()) !== $this->class->getName()) { if (!isset($entry['inheritance'])) { $entry['inheritance'] = array(); } if (!isset($entry['inheritance']['class'])) { $entry['inheritance']['class'] = array(); } $declaring_class = new ReflectionClass($declaring_class); $subentry = array(); $subentry['name'] = $declaring_class->getName(); if ($declaring_class->getFileName()) { $subentry['path'] = str_replace(VANITY_PROJECT_WORKING_DIR . '/', '', $declaring_class->getFileName()); } $entry['inheritance']['class'][] = $subentry; } // Method tags if (count($method_docblock->getTags())) { if (!isset($entry['metadata'])) { $entry['metadata'] = array(); } if (!isset($entry['metadata']['tag'])) { $entry['metadata']['tag'] = array(); } foreach ($method_docblock->getTags() as $rtag) { $dtag = new Tag($rtag, $this->ancestry); $tagData = $dtag->determine()->process(ConfigStore::get('source.resolve_aliases')); if ($tagData['name'] === 'alias') { SystemStore::add('alias.' . $tagData['entity'], $this->class->getName() . '::' . $rmethod->getName()); $documentThis = false; } $entry['metadata']['tag'][] = $tagData; } } // Method parameters if ($count = count($rmethod->getParameters())) { if (!isset($entry['parameters'])) { $entry['parameters'] = array(); } if (!isset($entry['parameters']['count'])) { $entry['parameters']['count'] = $count; } if (!isset($entry['parameters']['parameter'])) { $entry['parameters']['parameter'] = array(); } foreach ($rmethod->getParameters() as $rparameter) { $tag_finder = new TagFinder($entry); $param = array(); $param['name'] = $rparameter->getName(); $param['required'] = !$rparameter->isOptional(); $param['passed_by_reference'] = $rparameter->isPassedByReference(); if ($rparameter->isDefaultValueAvailable()) { $param['default'] = $rparameter->getDefaultValue(); } // Pull-in from @tags if ($_description = $tag_finder->find('description', $param['name'])) { $param['description'] = $_description; } if ($_type = $tag_finder->find('type', $param['name'])) { $param['type'] = $this->ancestry->resolveNamespace($_type); } if ($_types = $tag_finder->find('types', $param['name'])) { $param['types'] = $_types; } // Clean-up parameter metadata tags if (isset($entry['metadata']) && isset($entry['metadata']['tag'])) { foreach ($entry['metadata']['tag'] as $index => $tag) { if ($tag['name'] === 'param' && $tag['variable'] === $param['name']) { unset($entry['metadata']['tag'][$index]); } } } // Type hinting trumps docblock if ($rparameter->getClass()) { if (isset($param['type']) && $param['type'] !== $rparameter->getClass()->getName()) { // @todo: Resolve namespace of declaring class. Inconsistency::add($this->class->getName() . '::' . $rmethod->getName() . '($' . $rparameter->getName() . ') [' . $param['type'] . ' => ' . $rparameter->getClass()->getName() . ']'); } $param['type'] = $rparameter->getClass()->getName(); if (isset($param['types'])) { unset($param['types']); } } $entry['parameters']['parameter'][] = $param; } } // Return value $entry['return'] = array('type' => 'void'); if (isset($entry['metadata']) && isset($entry['metadata']['tag'])) { foreach ($entry['metadata']['tag'] as $index => $tag) { if ($tag['name'] === 'return') { $entry['return'] = $tag; unset($entry['return']['name']); // Clean-up return metadata tags unset($entry['metadata']['tag'][$index]); } } } if ($documentThis) { $this->methods['method'][] = $entry; } } return $this->methods; }
function __construct($reflector) { $phpdoc = new \phpDocumentor\Reflection\DocBlock($reflector); $this->tags = array(); $this->docblock = $reflector->getDocComment(); $this->desc = new stdClass(); $this->desc->long = $phpdoc->getLongDescription()->getFormattedContents(); $this->desc->short = $phpdoc->getShortDescription(); $this->desc->full = strip_tags($this->desc->short . "\n" . $this->desc->long); foreach ($phpdoc->getTags() as $tag) { $rslt = self::get_tag(); switch (true) { case $tag instanceof \phpDocumentor\Reflection\DocBlock\Tag\AuthorName: $rslt->name = $tag->getAuthorName(); $rslt->email = $tag->getAuthorEmail(); break; case $tag instanceof \phpDocumentor\Reflection\DocBlock\Tag\SeeTag: case $tag instanceof \phpDocumentor\Reflection\DocBlock\Tag\UsesTag: $rslt->ref = $tag->getReference(); break; case $tag instanceof \phpDocumentor\Reflection\DocBlock\Tag\ExampleTag: $rslt->file_path = $tag->getFilePath(); break; case $tag instanceof \phpDocumentor\Reflection\DocBlock\Tag\LinkTag: $rslt->link = $tag->getLink(); break; case $tag instanceof \phpDocumentor\Reflection\DocBlock\Tag\MethodTag: $rslt->name = $tag->getMethodName(); $rslt->args = $tag->getArguments(); break; case $tag instanceof \phpDocumentor\Reflection\DocBlock\Tag\VarTag: case $tag instanceof \phpDocumentor\Reflection\DocBlock\Tag\ParamTag: case $tag instanceof \phpDocumentor\Reflection\DocBlock\Tag\PropertyTag: case $tag instanceof \phpDocumentor\Reflection\DocBlock\Tag\PropertyReadTag: case $tag instanceof \phpDocumentor\Reflection\DocBlock\Tag\PropertyWriteTag: $rslt->name = $tag->getVariableName(); $rslt->type = str_replace('\\', '', $tag->getType()); break; case $tag instanceof \phpDocumentor\Reflection\DocBlock\Tag\ReturnTag: case $tag instanceof \phpDocumentor\Reflection\DocBlock\Tag\ThrowsTag: $rslt->type = str_replace('\\', '', $tag->getType()); break; case $tag instanceof \phpDocumentor\Reflection\DocBlock\Tag\SinceTag: case $tag instanceof \phpDocumentor\Reflection\DocBlock\Tag\VersionTag: case $tag instanceof \phpDocumentor\Reflection\DocBlock\Tag\DeprecatedTag: $rslt->version = $tag->getVersion(); break; case $tag instanceof \phpDocumentor\Reflection\DocBlock\Tag\SourceTag: $rslt->line = new stdClass(); $rslt->line->count = $tag->getLineCount(); $rslt->line->starting = $tag->getStartingLine(); break; default: break; } $rslt->desc = $tag->getDescription(); $name = $tag->getName(); if (@isset($rslt->name)) { $rslt->name = rtrim($rslt->name, ':'); } if ($tag instanceof \phpDocumentor\Reflection\DocBlock\Tag\ParamTag) { if (!@isset($this->tags[$name])) { $this->tags[$name] = array(); } $this->tags[$name][] = $rslt; } else { $this->tags[$name] = $rslt; } } }
/** * @depends testConstructWithTagsOnly * @covers \phpDocumentor\Reflection\DocBlock::parseTags * * @return void */ public function testParseMultilineTagWithLineBreaks() { $fixture = <<<DOCBLOCK /** * @return void Content on * multiple lines. * * One more, after the break. */ DOCBLOCK; $object = new DocBlock($fixture); $this->assertCount(1, $tags = $object->getTags()); /** @var ReturnTag $tag */ $tag = reset($tags); $this->assertEquals("Content on\n multiple lines.\n\n One more, after the break.", $tag->getDescription()); }