@param DocBlock $docBlock

@return string
482607
protected function getMethodDescription($docBlock): string
    {
        if ($docBlock->hasTag(self::API_METHOD_DESCRIPTION)) {
            $tags = $docBlock->getTagsByName(self::API_METHOD_DESCRIPTION);

            return (string)$tags[0];
        }

        return $docBlock->getSummary();
    }
1315335
private function block($textblock)
    {
        $length = 0;
        foreach ($textblock as $line) {
            $n = strlen($line);
            if ($length < $n) {
                $length = $n;
            }
        }

        foreach ($textblock as $i => $line) {
            $textblock[$i] .= str_repeat(' ', $length - strlen($line));
        }

        return $textblock;
    }
288799
protected function parseHeader($block)
    {
        if (!$block || strlen($block) != 512) {
            throw new ArchiveCorruptedException('Unexpected length of header');
        }

        // null byte blocks are ignored
        if(trim($block) === '') return false;

        for ($i = 0, $chks = 0; $i < 148; $i++) {
            $chks += ord($block[$i]);
        }

        for ($i = 156, $chks += 256; $i < 512; $i++) {
            $chks += ord($block[$i]);
        }

        $header = @unpack(
            "a100filename/a8perm/a8uid/a8gid/a12size/a12mtime/a8checksum/a1typeflag/a100link/a6magic/a2version/a32uname/a32gname/a8devmajor/a8devminor/a155prefix",
            $block
        );
        if (!$header) {
            throw new ArchiveCorruptedException('Failed to parse header');
        }

        $return['checksum'] = OctDec(trim($header['checksum']));
        if ($return['checksum'] != $chks) {
            throw new ArchiveCorruptedException('Header does not match it\'s checksum');
        }

        $return['filename'] = trim($header['filename']);
        $return['perm']     = OctDec(trim($header['perm']));
        $return['uid']      = OctDec(trim($header['uid']));
        $return['gid']      = OctDec(trim($header['gid']));
        $return['size']     = OctDec(trim($header['size']));
        $return['mtime']    = OctDec(trim($header['mtime']));
        $return['typeflag'] = $header['typeflag'];
        $return['link']     = trim($header['link']);
        $return['uname']    = trim($header['uname']);
        $return['gname']    = trim($header['gname']);

        // Handle ustar Posix compliant path prefixes
        if (trim($header['prefix'])) {
            $return['filename'] = trim($header['prefix']).'/'.$return['filename'];
        }

        // Handle Long-Link entries from GNU Tar
        if ($return['typeflag'] == 'L') {
            // following data block(s) is the filename
            $filename = trim($this->readbytes(ceil($return['size'] / 512) * 512));
            // next block is the real header
            $block  = $this->readbytes(512);
            $return = $this->parseHeader($block);
            // overwrite the filename
            $return['filename'] = $filename;
        }

        return $return;
    }
664266
protected function getDocblockTagsSection($docblock)
    {
        $docblock = $this->sanitizeDocblock($docblock);
        preg_match('/^\s*\\'.self::TOKEN_ANNOTATION_IDENTIFIER.'/m', $docblock, $matches, PREG_OFFSET_CAPTURE);

        // return found docblock tag section or empty string
        return isset($matches[0]) ? substr($docblock, $matches[0][1]) : '';
    }
385038
public function getParentBlock(Dwoo_Block_Plugin $block)
	{
		$index = array_search($block, $this->stack, true);
		if ($index !== false && $index > 0) {
			return $this->stack[$index-1];
		}
		return false;
	}
1194905
private function extractDocBlockPartsWrapper(): void
  {
    // Get the DocBlock parts from the source of the stored routine.
    $this->extractDocBlockPartsSource();

    // Generate the parameters parts of the DocBlock to be used by the wrapper.
    $parameters = [];
    foreach ($this->parameters as $parameter_info)
    {
      $parameters[] = ['parameter_name'       => $parameter_info['parameter_name'],
                       'php_type'             => DataTypeHelper::columnTypeToPhpTypeHinting($parameter_info).'|null',
                       'data_type_descriptor' => $parameter_info['data_type_descriptor'],
                       'description'          => $this->getParameterDocDescription($parameter_info['parameter_name'])];
    }

    // Compose all the DocBlock parts to be used by the wrapper generator.
    $this->docBlockPartsWrapper = ['sort_description' => $this->docBlockPartsSource['sort_description'],
                                   'long_description' => $this->docBlockPartsSource['long_description'],
                                   'parameters'       => $parameters];
  }
1157917
protected function getMethodReturn($method, $docBlock = null): SmdReturn
    {
        $result = new SmdReturn();
        $result->types = ['mixed'];

        if (PHP_VERSION_ID > 70000) {
            $result->types = [$method->getReturnType()];
        }

        if ($docBlock !== null && $docBlock->hasTag(self::API_METHOD_RETURN)) {
            /** @var DocBlock\Tags\Return_ $return */
            $return = $docBlock->getTagsByName(self::API_METHOD_RETURN)[0];
            if (!empty((string)$return->getType())) {
                $result->types = explode('|', (string)$return->getType());
            }
            if (!empty((string)$return->getDescription())) {
                $result->description = (string)$return->getDescription();
            }
        }

        return $result;
    }
482692
private function parseDocBlock( $lines )
	{
#		remark( "Parsing DocBlock" );
		$data		= array();
		$descLines	= array();
		foreach( $lines as $line )
		{
			if( preg_match( $this->regexDocParam, $line, $matches ) )
			{
				$param	= array(
					'type'			=> $matches[2],
					'name'			=> $matches[4],
					'description'	=> isset( $matches[5] ) ? $matches[5] : NULL,
				);
				if( !isset( $data['param'] ) )
					$data['param']	= array();
				$data['param'][$matches[4]]	= $param;
			}
			else if( preg_match( "@\*\s+\@return\s+(\w+)\s*(.+)?$@i", $line, $matches ) )
			{
				$data['return']	= array(
					'type'			=> trim( $matches[1] ),
					'description'	=> isset( $matches[2] ) ? trim( $matches[2] ) : "",
				);
			}
			else if( preg_match( "@\*\s+\@author\s+(.+)\s*(<(.+)>)?$@iU", $line, $matches ) )
			{
				$data['author'][]	= array(
					'name'	=> trim( $matches[1] ),
					'mail'	=> isset( $matches[3] ) ? trim( $matches[3] ) : "",
				);
			}
			else if( preg_match( "@\*\s+\@license\s+(\S+)( .+)?$@i", $line, $matches ) )
			{
				if( isset( $matches[2] ) )
				{
					$url	= trim( $matches[1] );
					$name	= trim( $matches[2] );
					if( preg_match( "@^http://@", $matches[2] ) )
					{
						$url	= trim( $matches[2] );
						$name	= trim( $matches[1] );
					}
				}
				else
				{
					$url	= "";
					$name	= trim( $matches[1] );
					if( preg_match( "@^http://@", $matches[1] ) )
						$url	= trim( $matches[1] );
				}
			
				$data['license'][]	= array(
					'url'	=> $url,
					'name'	=> $name,
				);
			}
			else if( preg_match( "/^\*\s+@(\w+)\s+(.+)$/", $line, $matches ) )
			{
				switch( $matches[1] )
				{
					case 'implements':
					case 'deprecated':
					case 'todo':
					case 'see':
					case 'link':
					case 'copyright':
					case 'license':
					case 'author':
					case 'see':
					case 'uses':
					case 'throws':
					case 'link':
						$data[$matches[1]][]	= $matches[2];			
						break;
					default:
						$data[$matches[1]]	= $matches[2];			
						break;
				}
			}
			else if( !$data && preg_match( "/^\*\s*([^@].+)?$/", $line, $matches ) )
				$descLines[]	= isset( $matches[1] ) ? trim( $matches[1] ) : "";
		}
		$data['description']	= trim( implode( "\n", $descLines ) );
		if( !isset( $data['throws'] ) )
			$data['throws']	= array();
		foreach( $data['throws'] as $throws )
		{
			$list	= array();
			$parts	= explode( ",", $throws );
			foreach( $parts as $part )
				$list[]	= trim( $part );
			$data['throws']	= $list;
		}
		return $data;
	}
288119
protected function getMethodName($method, $docBlock = null): string
    {
        if ($docBlock !== null && $docBlock->hasTag(self::API_METHOD_NAME)) {
            $tags = $docBlock->getTagsByName(self::API_METHOD_NAME);

            return (string)$tags[0];
        }

        $controllerName = $method->getDeclaringClass();

        if (!empty($this->server->endpoint)) {
            return $method->getName();
        }

        return $this->getShortNameForController($controllerName->getName()) . '_' . $method->getName();
    }
297403
public static function parse($doc)
    {
        $block = new DocBlock();
        $lines = explode("\n", $doc);

        // remove first line
        unset($lines[0]);

        foreach ($lines as $line) {
            $line = trim($line);
            $line = substr($line, 2);

            if (isset($line[0]) && $line[0] == '@') {
                $line = substr($line, 1);
                $sp   = strpos($line, ' ');
                $bp   = strpos($line, '(');

                if ($sp !== false || $bp !== false) {
                    if ($sp !== false && $bp === false) {
                        $pos = $sp;
                    } elseif ($sp === false && $bp !== false) {
                        $pos = $bp;
                    } else {
                        $pos = $sp < $bp ? $sp : $bp;
                    }

                    $key   = substr($line, 0, $pos);
                    $value = substr($line, $pos);
                } else {
                    $key   = $line;
                    $value = null;
                }

                $key   = trim($key);
                $value = trim($value);

                if (!empty($key)) {
                    // if key contains backslashes its a namespace use only the
                    // short name
                    $pos = strrpos($key, '\\');
                    if ($pos !== false) {
                        $key = substr($key, $pos + 1);
                    }

                    $block->addAnnotation($key, $value);
                }
            }
        }

        return $block;
    }
379959
def _docstring_getblocks(self):
        
        #If there are no lines to look at, we have nothing to do here.
        if self.ibuffer[0] == self.ibuffer[1]:
            return []

        lines = self.context.bufferstr[self.ibuffer[0]:self.ibuffer[1]]
        docblock = []
        result = []
        self._doclines = []

        #We need to keep track of the line number for the start of the
        #documentation strings.
        docline = 0
        doclength = 0

        first = self.docparser.RE_DOCS.match(lines[0])
        if first is not None:
            docblock.append(first.group("docstring"))
            docline = self.ibuffer[0]
            self._doclines.append(docline)
            doclength += len(lines[0]) + 1 # + 1 for \n removed by split.

            #We need to search backwards in the main buffer string for
            #additional tags to add to the block
            i = self.ibuffer[0] - 1
            while i > 0:
                current = self.context.bufferstr[i]
                docmatch = self.docparser.RE_DOCS.match(current)
                if docmatch is not None:
                    docblock.append(docmatch.group("docstring"))
                    docline = i
                    doclength += len(current) + 1
                else:
                    break
                i -= 1

        #Reverse the docblock list since we were going backwards and appending.
        if len(docblock) > 0:
            docblock.reverse()

        #Now handle the lines following the first line. Also handle the
        #possibility of multiple, separate blocks that are still valid XML.
        #We have to keep going until we have exceed the operational changes
        #or found the decorating element.
        i = self.ibuffer[0] + 1
        while (i < len(self.context.bufferstr) and 
               (i < self.ibuffer[1] or len(docblock) > 0)):
            line = self.context.bufferstr[i]
            docmatch = self.docparser.RE_DOCS.match(line)
            if docmatch is not None:
                docblock.append(docmatch.group("docstring"))
                doclength += len(line)
                if docline == 0:
                    docline = i
                #Only track actual documentation lines that are within the 
                #operations list of lines.
                if i < self.ibuffer[1]:
                    self._doclines.append(i)

            elif len(docblock) > 0:
                key = self._docstring_key(line)
                result.append((docblock, docline, doclength, key))
                docblock = []
                docline = 0
                doclength = 0

            #We need to exit the loop if we have exceeded the length of
            #the operational changes
            if len(docblock) == 0 and i > self.ibuffer[1]:
                break
            i += 1

        return result
1022373
public function getDocBlock() {
    if ($this->docBlock === NULL) {
      $namespace = '\\';
      $aliases = array();
      /** @var NamespaceNode $namespace_node */
      $namespace_node = $this->closest(Filter::isInstanceOf('\Pharborist\Namespaces\NamespaceNode'));
      if ($namespace_node !== NULL) {
        $namespace = $namespace_node->getName() ? $namespace_node->getName()->getAbsolutePath() : '';
        $aliases = $namespace_node->getClassAliases();
      } else {
        /** @var RootNode $root_node */
        $root_node = $this->closest(Filter::isInstanceOf('\Pharborist\RootNode'));
        if ($root_node !== NULL) {
          $aliases = $root_node->getClassAliases();
        }
      }
      $context = new DocBlock\Context($namespace, $aliases);
      $this->docBlock = new DocBlock($this->text, $context);
    }
    return $this->docBlock;
  }
1259896
public function getValidBlockItems(Block $block)
    {
        if (isset($this->validBlockItems[$block])) {
            return $this->validBlockItems[$block];
        }

        return $this->validBlockItems[$block] = $this->getStorageGateway()->getValidBlockItems($block);
    }
1301869
public function getDocComment($prefix = "\t\t")
    {
        $serializer = new DocBlockSerializer(1, $prefix);

        if ($this->phpdoc) {
            if ($this->config->get('ide-helper.include_class_docblocks')) {
                // if a class doesn't expose any DocBlock tags
                // we can perform reflection on the class and
                // add in the original class DocBlock
                if (count($this->phpdoc->getTags()) === 0) {
                    $class = new ReflectionClass($this->root);
                    $this->phpdoc = new DocBlock($class->getDocComment());
                }
            }

            $this->removeDuplicateMethodsFromPhpDoc();
            return $serializer->getDocComment($this->phpdoc);
        }

        return '';
    }
347307
protected function doCodeBlocks($text) {
		$text = preg_replace_callback('{
				(?:\n\n|\A\n?)
				(	            # $1 = the code block -- one or more lines, starting with a space/tab
				  (?>
					[ ]{'.$this->tab_width.'}  # Lines must start with a tab or a tab-width of spaces
					.*\n+
				  )+
				)
				((?=^[ ]{0,'.$this->tab_width.'}\S)|\Z)	# Lookahead for non-space at line-start, or end of doc
			}xm',
			array($this, '_doCodeBlocks_callback'), $text);

		return $text;
	}
1031860
function _getIgnoredByDocBlock()
    {
        if ($this->_c_ignored_docblock)
            // DocBlock Parsed To Cache Previously !!
            return $this->_c_ignored_docblock;


        $ignoredMethods = array();


        $ref = $this->_newReflection();
        $refuseIgnore = $this->getRefuseIgnore();


        // ignored methods from Class DocComment:
        $classDocComment = $ref->getDocComment();
        if ($classDocComment !== false && preg_match_all('/.*[\n]?/', $classDocComment, $lines)) {
            $lines = $lines[0];
            $regex = '/.+(@method).+((?P<method_name>\b\w+)\(.*\))\s@'.self::HYDRATE_IGNORE.'\s/';
            foreach($lines as $line) {
                if (preg_match($regex, $line, $matches)) {
                    if (! in_array($matches['method_name'], $refuseIgnore) )
                        $ignoredMethods[] = $matches['method_name'];
                }
            }
        }

        // ignored methods from Method DocBlock
        $methods = $ref->getMethods(\ReflectionMethod::IS_PUBLIC);
        foreach($methods as $m)
        {
            if (!(
                ('get'   == substr($m->getName(), 0, 3) && $prefix = 'get')
                ||  ('is'    == substr($m->getName(), 0, 2) && $prefix = 'is' )
            ))
                // It's Not Getter Method
                continue;


            if (! in_array($m->getName(), $refuseIgnore) ) {
                // it's not refused so check for ignore sign docblock
                $mc = $m->getDocComment();
                if ($mc !== false && preg_match('/@'.self::HYDRATE_IGNORE.'\s/', $mc, $matches))
                    $ignoredMethods[] = $m->getName();
            }
        }

        return $this->_c_ignored_docblock = $ignoredMethods;
    }
280567
public function _doCodeBlocks_callback($matches)
	{
		$codeblock = $this->outdent($matches[1]);
		if(($codeblock = $this->highlightCodeBlock($codeblock)) !== null)
			return "\n\n".$this->hashBlock($codeblock)."\n\n";
		else
			return parent::_doCodeBlocks_callback($matches);
	}