Get the description and get the inherited docs.

@param DocBlock $phpdoc
331547
protected function normalizeDescription(DocBlock $phpdoc)
    {
        //Get the short + long description from the DocBlock
        $description = $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);
            $phpdoc->setText($description);

            $this->normalizeParams($inheritdoc);
            $this->normalizeReturn($inheritdoc);

            //Add the tags that are inherited
            $inheritTags = $inheritdoc->getTags();
            if ($inheritTags) {
                /** @var Tag $tag */
                foreach ($inheritTags as $tag) {
                    $tag->setDocBlock();
                    $phpdoc->appendTag($tag);
                }
            }
        }
    }
1131864
public function parseBlockComment($blockComment)
    {
        $blockCommentLines = $this->parseBlockCommentLines($blockComment);

        return new Element\DocumentationBlock(
            $this->parseBlockCommentTags($blockCommentLines),
            $this->parseBlockCommentSummary($blockCommentLines),
            $this->parseBlockCommentBody($blockCommentLines)
        );
    }
701366
public function phpdocSummary()
    {
        $content = $this->phpdocContent();
        if (!$content) {
            return UNDEFINED;
        }
        $lines = preg_split('/(\n|\r\n)/', $content);
        $summary = '';
        foreach ($lines as $line) {
            $summary .= $line . "\n";
            if ($line === '' || substr($line, -1) === '.') {
                return trim($summary);
            }
        }
        $summary = trim($summary);
        if ($summary === '') {
            return UNDEFINED;
        }

        return $summary;
    }
1231398
protected function insertDocBlock(File $phpCsFile, int $docBlockStartPosition): void
    {
        $phpCsFile->fixer->addContent($docBlockStartPosition, '/**');
        $phpCsFile->fixer->addNewline($docBlockStartPosition);
        $phpCsFile->fixer->addContent($docBlockStartPosition, ' * ' . static::EXPLANATION_CONSTANTS_INTERFACE);
        $phpCsFile->fixer->addNewline($docBlockStartPosition);
        $phpCsFile->fixer->addContent($docBlockStartPosition, ' */');
    }
1062250
private function compactAnnotations($docblock)
    {
        $annotations = array();
        $index = -1;
        $inside = 0;
        $tokens = $this->tokenizer->parse($docblock);

        if (empty($tokens)) {
            return str_repeat("\n", substr_count($docblock, "\n"));
        }

        foreach ($tokens as $token) {
            if ((0 === $inside) && (DocLexer::T_AT === $token[0])) {
                $index++;
            } elseif (DocLexer::T_OPEN_PARENTHESIS === $token[0]) {
                $inside++;
            } elseif (DocLexer::T_CLOSE_PARENTHESIS === $token[0]) {
                $inside--;
            }

            if (!isset($annotations[$index])) {
                $annotations[$index] = array();
            }

            $annotations[$index][] = $token;
        }

        $breaks = substr_count($docblock, "\n");
        $docblock = "/**";

        foreach ($annotations as $annotation) {
            $annotation = new Tokens($annotation);
            $docblock .= "\n" . $this->converter->convert($annotation);
        }

        $breaks -= count($annotations);

        if ($breaks > 0) {
            $docblock .= str_repeat("\n", $breaks - 1);
            $docblock .= "\n*/";
        } else {
            $docblock .= ' */';
        }

        return $docblock;
    }
374084
protected function extractPackageFromDocBlock($docBlock)
    {
        $packageTags = $docBlock ? $docBlock->getTagsByName('package') : [];
        if (count($packageTags) === 0) {
            return null;
        }

        /** @var DocBlock\Tags\Generic $tag */
        $tag = reset($packageTags);

        return trim((string) $tag->getDescription());
    }
826868
public function rootDoc(&$phpdoctor)
    {

        // set a reference to application object
        $this->_phpdoctor =& $phpdoctor;

        $overview = $phpdoctor->getOption('overview');
        // parse overview file
        if (isset($overview)) {
            if (is_file($overview)) {
                $phpdoctor->message('Reading overview file "'.$overview.'".');
                if ($text = $this->getFileContents($overview)) {
                    $this->_data = $phpdoctor->processDocComment('/** '.$text.' */', $this);
                    $this->mergeData();
                }
            } else {
                $phpdoctor->warning('Could not find overview file "'.$overview.'".');
            }
        }

    }
628712
protected function getDocBlockExtraParameterRefTags($docBlock)
	{
		$results = [];
		$apiExtraParameterRefTags = $docBlock->getTagsByName('OpenApiExtraParameterRef');

		foreach ($apiExtraParameterRefTags as $apiExtraParameterRefTag) {
			$apiExtraParameterRef = trim(str_replace('@OpenApiExtraParameterRef', '', $apiExtraParameterRefTag->render()));
			$results[] = $apiExtraParameterRef;
		}

		return $results;
	}
893141
public function getDescription($docComment): string
    {
        $docComment  = (string) $docComment;
        $description = [];

        // split at each line
        foreach (preg_split(self::REGEX_SPLIT_BY_NEWLINE, $docComment) as $line) {
            // if line does not start with asterisk, or only contains an asterisk, do nothing
            if (!preg_match(self::REGEX_LINE_HAS_CONTENT, $line, $matches)) {
                continue;
            }

            // trim whitespace and remove leading asterisk
            $info = trim(preg_replace(self::REGEX_REMOVE_LEADING_ASTERISK, '', trim($matches[1])));

            // add to description if info not start with a tag marked for skipping (annotation, phpDoc tag)
            $addInfo = true;

            foreach (self::DESCRIPTION_SKIP_TAGS as $skipTag) {
                if (substr($info, 0, strlen($skipTag)) === $skipTag) {
                    $addInfo = false;
                }
            }

            if ($addInfo) {
                $description[] = $info;
            }
        }

        return implode("\n", $description);
    }
363649
public function getParsedDocBlock()
    {
        if (!$this->parsedDocblock) {
            if (\strlen($this->docBlock) > 0) {
                $parser = new DocblockParser('/'.$this->docBlock.'/');
                $this->parsedDocblock = $parser->parse();
            } else {
                return null;
            }
        }

        return $this->parsedDocblock;
    }
350542
public function indexWriter(&$doclet)
    {

        parent::HTMLWriter($doclet);

        //$this->_id = 'definition';

        $rootDoc =& $this->_doclet->rootDoc();

        $this->_sections[0] = array('title' => 'Overview', 'url' => 'overview-summary.html');
        $this->_sections[1] = array('title' => 'Namespace');
        $this->_sections[2] = array('title' => 'Class');
        //$this->_sections[3] = array('title' => 'Use');
        $this->_sections[4] = array('title' => 'Tree', 'url' => 'overview-tree.html');
        if ($doclet->includeSource()) $this->_sections[5] = array('title' => 'Files', 'url' => 'overview-files.html');
        $this->_sections[6] = array('title' => 'Deprecated', 'url' => 'deprecated-list.html');
        $this->_sections[7] = array('title' => 'Todo', 'url' => 'todo-list.html');
        $this->_sections[8] = array('title' => 'Index', 'selected' => TRUE);

        $classes =& $rootDoc->classes();
        if($classes == NULL) $classes = array();

        $methods = array();
        foreach ($classes as $class) {
            foreach ($class->methods(TRUE) as $name => $method) {
                $methods[$class->name().'::'.$name] = $method;
            }
        }
        if($methods == NULL) $methods = array();

        $functions =& $rootDoc->functions();
        if($functions == NULL) $functions = array();

        $globals =& $rootDoc->globals();
        if($globals == NULL) $globals = array();

        $elements = array_merge($classes, $methods, $functions, $globals);
        uasort($elements, array($this, 'compareElements'));

        ob_start();

        $letter = 64;
        foreach ($elements as $name => $element) {
            $firstChar = strtoupper(substr($element->name(), 0, 1));
            if (is_object($element) && $firstChar != chr($letter)) {
                $letter = ord($firstChar);
                echo '<a href="#letter', chr($letter), '">', chr($letter), "</a>\n";
            }
        }

        echo "<hr>\n\n";

        $first = TRUE;
        foreach ($elements as $element) {
            if (is_object($element)) {
                if (strtoupper(substr($element->name(), 0, 1)) != chr($letter)) {
                    $letter = ord(strtoupper(substr($element->name(), 0, 1)));
                    if (!$first) {
                        echo "</dl>\n";
                    }
                    $first = FALSE;
                    echo '<h1 id="letter', chr($letter), '">', chr($letter), "</h1>\n";
                    echo "<dl>\n";
                }
                $parent =& $element->containingClass();
                if ($parent && strtolower(get_class($parent)) != 'rootdoc') {
                    $in = 'class <a href="'.$parent->asPath().'">'.$parent->qualifiedName().'</a>';
                } else {
                    $package =& $element->containingPackage();
                    $in = 'namespace <a href="'.$package->asPath().'/package-summary.html">'.$package->name().'</a>';
                }
                switch (strtolower(get_class($element))) {
                case 'classdoc':
                    if ($element->isOrdinaryClass()) {
                        echo '<dt><a href="', $element->asPath(), '">', $element->name(), '()</a> - Class in ', $in, "</dt>\n";
                    } elseif ($element->isInterface()) {
                        echo '<dt><a href="', $element->asPath(), '">', $element->name(), '()</a> - Interface in ', $in, "</dt>\n";
                    } elseif ($element->isTrait()) {
                        echo '<dt><a href="', $element->asPath(), '">', $element->name(), '()</a> - Trait in ', $in, "</dt>\n";
                    } elseif ($element->isException()) {
                        echo '<dt><a href="', $element->asPath(), '">', $element->name(), '()</a> - Exception in ', $in, "</dt>\n";
                    }
                    break;
                case 'methoddoc':
                    if ($element->isMethod()) {
                        echo '<dt><a href="', $element->asPath(), '">', $element->name(), '()</a> - Method in ', $in, "</dt>\n";
                    } elseif ($element->isFunction()) {
                        echo '<dt><a href="', $element->asPath(), '">', $element->name(), '()</a> - Function in ', $in, "</dt>\n";
                    }
                    break;
                case 'fielddoc':
                    if ($element->isGlobal()) {
                        echo '<dt><a href="', $element->asPath(), '">', $element->name(), '()</a> - Global in ', $in, "</dt>\n";
                    }
                    break;
                }
                if ($textTag =& $element->tags('@text') && $firstSentenceTags =& $textTag->firstSentenceTags($this->_doclet)) {
                    echo '<dd>';
                    foreach ($firstSentenceTags as $firstSentenceTag) {
                        echo $firstSentenceTag->text($this->_doclet);
                    }
                    echo "</dd>\n";
                }
            }
        }
        echo "</dl>\n";

        $this->_output = ob_get_contents();
        ob_end_clean();

        $this->_write('index-all.html', 'Index', TRUE);

    }
267223
protected function getSiblingDocList(CollectionDoc $docObject) : array
    {
        $docArray = [];
        foreach ($docObject->getSiblingList() as $siblingDocObject) {
            $siblingDocArray = $this->normalize($siblingDocObject);
            // Use name if :
            // - parent is object
            // - parent is array and name is an integer
            if ($docObject instanceof ObjectDoc
                || (
                    $docObject instanceof ArrayDoc
                    && is_int($siblingDocObject->getName())
                )
            ) {
                $docArray[$siblingDocObject->getName()] = $siblingDocArray;
            } else {
                $docArray[] = $siblingDocArray;
            }
        }

        return $docArray;
    }
519381
protected function parseDocblocks($rawDocBlocks)
    {
        $parsedDocBlocks = array();
        $docBlockParser = new MarkdownParser();

        foreach ($rawDocBlocks as $docBlock) {
            $docBlock = preg_replace(self::REGEX_DOCBLOCK_TYPE, '$1$2 `$4` ', $docBlock);
            $docBlock = preg_replace(self::REGEX_DOCBLOCK_VAR, '$1`$2`', $docBlock);
            $docBlock = preg_replace(self::REGEX_DOCBLOCK_ARG, "\n<em class=\"docparam\">$1</em>", $docBlock);

            $parsedDocBlocks[] = $docBlockParser->transformMarkdown($docBlock);
        }

        return $parsedDocBlocks;
    }
1265307
public function phpdocDescription()
    {
        $summary = $this->phpdocSummary();
        if (!$summary) {
            return UNDEFINED;
        }
        $description = trim(substr($this->phpdocContent(), strlen($summary)));
        if ($description === '') {
            return UNDEFINED;
        }

        return $description;
    }
102787
public function getDocComment(): ?Doc
    {
        $docComment = $this->classConstants->consts[$this->index]->getDocComment();
        if ($docComment === null) {
            $docComment = $this->classConstants->getDocComment();
        }

        return $docComment;
    }
1084028
protected function appendObjectDoc(TypeDoc $doc, array $siblingsDoc, array $paramDocRequired) : array
    {
        if (!$doc instanceof ObjectDoc) {
            return [$siblingsDoc, $paramDocRequired];
        }

        if (true === $doc->isAllowExtraSibling()) {
            $siblingsDoc['additionalProperties']['description'] = "Extra property";
        }

        $self = $this;
        $siblingDocList = array_reduce(
            $doc->getSiblingList(),
            function (array $carry, TypeDoc $sibling) use ($self) {
                $carry[$sibling->getName()] = $self->normalize($sibling);

                return $carry;
            },
            []
        );
        $requiredSiblings = array_keys(// Keeps only keys
            array_filter(// Remove not required
                array_reduce(// Convert to $carray[PROPERTY_NAME] = IS_REQUIRED
                    $doc->getSiblingList(),
                    function (array $carry, TypeDoc $sibling) {
                        $carry[$sibling->getName()] = $sibling->isRequired();

                        return $carry;
                    },
                    []
                )
            )
        );

        $siblingsDoc = $this->appendIfValueHaveSiblings('properties', $siblingDocList, $siblingsDoc);
        $paramDocRequired = $this->appendIfValueHaveSiblings('required', $requiredSiblings, $paramDocRequired);

        return [$siblingsDoc, $paramDocRequired];
    }
1352143
protected function getDocBlockReturnTypes(File $phpCsFile, int $stackPointer): array
    {
        $docBlock = DocCommentHelper::getDocComment($phpCsFile, $stackPointer);

        if ($docBlock === null) {
            return [];
        }

        preg_match('/(@return\s+)(\S+)/', $docBlock, $matches);

        if (!$matches) {
            return [];
        }

        $returnTypes = array_pop($matches);
        $returnTypes = trim($returnTypes);
        $returnTypes = explode('|', $returnTypes);

        return $returnTypes;
    }