/** * @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; }
/** * 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; }
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; } } }
protected function getClassHeader($ReflectionEntity, &$params, $class_path, $class_name, $hlevel_extra) { $ns = $ReflectionEntity->getNamespaceName(); $name = $ReflectionEntity->getName(); if ($ns) { $name = substr($ReflectionEntity->getName(), strlen($ns) + 1); } $PHPDoc = new DocBlock($ReflectionEntity->getDocComment()); $desc = $PHPDoc->getText(); if ($desc) { $desc .= "\n\n"; } $parent = $ReflectionEntity->getParentClass(); $extra_parent = ''; if ($parent instanceof ReflectionClass) { $parent_ns = $parent->getNamespaceName(); $parent_name = '\\' . $parent->getName(); $extra_parent = ' extends ' . $parent_name; } $altname = strtolower(preg_replace('/([a-z])([A-Z])/', '$1-$2', $name)); $type = 'Class'; if ($ReflectionEntity->isTrait()) { $type = 'Trait'; } $typeLower = strtolower($type); // var_dump('level: '.$params['level']); if (!$params['level']) { // var_dump('2: '.$hlevel_extra); $params['level'] = 3; } $params['level'] += $hlevel_extra; $level = $this->getHeaderLevel($params['level'], 1); $result = <<<TPL {$level} {$altname} # {$name} {tpl-git {$class_path}} ```php namespace {$ns}; {$typeLower} {$name}{$extra_parent}; ``` {$desc} TPL; return $result; }
/** * Парсит описание свойства из phpdoc в стандартизованный вид для дальнейшей обработки * @param string $text * @return string */ protected function parseMdPropertieFromPHPDoc($text) { $lines = $this->getTextLines($text, '/\\n/', false); $phpdoc = []; while (true) { $line = array_shift($lines); if (is_null($line)) { break; } $phpdoc[] = $line; if (preg_match('/^[ \\t]*\\*\\//', $line)) { break; } } $code = implode("\n", $lines); $comment = implode("\n", $phpdoc); $PHPDoc = new DocBlock($comment); $doc_var = $PHPDoc->getTagsByName('var'); if (empty($doc_var)) { return $code . "\n" . $PHPDoc->getText(); } $tag = $doc_var[0]; $type = $tag->getType(); $deftype = $this->getDocDefaultType($type); $desc = $tag->getDescription(); if (!$desc) { $desc = $PHPDoc->getText(); } return $deftype . ' ' . $code . "\n" . $desc; }
/** * @param string $method * * @return array */ public function parseMethod($method) { $methodReflector = $this->reflector->getMethod($method); // Creating docblock for parsing the docs $docblock = new DocBlock($methodReflector); // Parsing params $params = []; foreach ($docblock->getTagsByName('apiParam') as $param) { // Removing $ sign from name $name = $param->getVariableName(); if (substr($name, 0, 1) == '$') { $name = substr($name, 1); } $params[] = ['type' => $param->getType(), 'name' => $name]; } // Parse for return value $return = []; if (!is_null($this->statements)) { $return = @$this->methodStatementsReturns[$method] ?: []; } return ['description' => $docblock->getText(), 'params' => $params, 'return' => $return]; }
/** * Parse examples from a DocBlock object. * * Example: * ``` * // Yeah, this example is pretty useless. * $examples = $parser->examples($docBlock); * ``` * * @param DocBlock $docBlock The DocBlock to parse * @param string $file The filename the docblock is in * @param int $line The line where the tested method or class is declared. * @return array */ public function examples(DocBlock $docBlock, $fullyQualifiedName, $file, $line, array $magicMethods = []) { $text = $docBlock->getText(); // $return = $docBlock->getTagsByName('return'); // if (!empty($return)) { // print_r($return[0]->getTypes());exit; // } $parts = explode('Example:', $text); if (strpos($text, 'Example:') === false) { return []; } $converter = new Parsedown(); $document = new DOMDocument(); $parsedText = $converter->text($parts[1]); $document->loadHTML($parsedText); $examples = $document->getElementsByTagName('code'); $index = 0; $res = []; foreach ($examples as $example) { $name = $this->extractSnippetName($example->textContent); $indexOrName = $name; if (!$name) { $indexOrName = $index; } $identifier = $this->createIdentifier($fullyQualifiedName, $indexOrName); $snippet = new Snippet($identifier, ['content' => $example->textContent, 'fqn' => $fullyQualifiedName, 'index' => $index, 'name' => $name, 'file' => $file, 'line' => $line]); $res[$identifier] = $snippet; $index++; } $res = array_merge($res, $magicMethods); return $res; }
/** * @param string $existingDocBlock * @return string */ protected function mergeGeneratedTagsIntoDocBlock($existingDocBlock) { $docBlock = new DocBlock($this->removeExistingSupportedTags($existingDocBlock)); if (!$docBlock->getText()) { $docBlock->setText('Class ' . $this->className); } foreach ($this->getGeneratedTags() as $tag) { $docBlock->appendTag($tag); } $serializer = new DocBlockSerializer(); $docBlock = $serializer->getDocComment($docBlock); return $docBlock; }