summaryrefslogtreecommitdiff
path: root/buildscripts/PhpDocumentor/phpDocumentor/ParserDocBlock.inc
diff options
context:
space:
mode:
Diffstat (limited to 'buildscripts/PhpDocumentor/phpDocumentor/ParserDocBlock.inc')
-rwxr-xr-xbuildscripts/PhpDocumentor/phpDocumentor/ParserDocBlock.inc1227
1 files changed, 1227 insertions, 0 deletions
diff --git a/buildscripts/PhpDocumentor/phpDocumentor/ParserDocBlock.inc b/buildscripts/PhpDocumentor/phpDocumentor/ParserDocBlock.inc
new file mode 100755
index 00000000..2e29caeb
--- /dev/null
+++ b/buildscripts/PhpDocumentor/phpDocumentor/ParserDocBlock.inc
@@ -0,0 +1,1227 @@
+<?php
+/**
+ * DocBlock Parser Classes
+ *
+ * phpDocumentor :: automatic documentation generator
+ *
+ * PHP versions 4 and 5
+ *
+ * Copyright (c) 2002-2006 Gregory Beaver
+ *
+ * LICENSE:
+ *
+ * This library is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General
+ * Public License as published by the Free Software Foundation;
+ * either version 2.1 of the License, or (at your option) any
+ * later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * @package phpDocumentor
+ * @subpackage ParserDocBlock
+ * @author Gregory Beaver <cellog@php.net>
+ * @copyright 2002-2006 Gregory Beaver
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @version CVS: $Id: ParserDocBlock.inc 287886 2009-08-30 05:31:05Z ashnazg $
+ * @link http://www.phpdoc.org
+ * @link http://pear.php.net/PhpDocumentor
+ * @see Parser, WordParser
+ * @since 1.0rc1
+ */
+/**
+ * represents a short or long description in a DocBlock ({@link parserDocBlock})
+ * @package phpDocumentor
+ * @subpackage ParserDocBlock
+ * @author Greg Beaver <cellog@php.net>
+ * @since 1.0rc1
+ * @version $Id: ParserDocBlock.inc 287886 2009-08-30 05:31:05Z ashnazg $
+ */
+class parserDesc extends parserStringWithInlineTags
+{
+ /**
+ * Type is used by many functions to skip the hassle of if phpDocumentor_get_class($blah) == 'parserBlah'
+ * always '_desc'
+ * @var string
+ */
+ var $type = '_desc';
+
+ /**
+ * @param mixed like {@link parserStringWithInlineTags::add()}, this can be a string or parserInlineTag, but it can also be a
+ * parserStringWithInlineTags, and the contents will be merged
+ */
+ function add($stringOrClass)
+ {
+ if (is_object($stringOrClass))
+ {
+ if (phpDocumentor_get_class($stringOrClass) == 'parserstringwithinlinetags' ||
+ phpDocumentor_get_class($stringOrClass) == 'parserdesc')
+ {
+ for($i=0;$i<count($stringOrClass->value);$i++)
+ {
+ parserStringWithInlineTags::add($stringOrClass->value[$i]);
+ }
+ } else
+ {
+ parserStringWithInlineTags::add($stringOrClass);
+ }
+ } else return parserStringWithInlineTags::add($stringOrClass);
+ }
+
+ /**
+ * @return boolean whether this desc has an {@}inheritdoc} inline tag
+ */
+ function hasInheritDoc()
+ {
+ for($i=0;$i<count($this->value);$i++)
+ {
+ if (phpDocumentor_get_class($this->value[$i])=='parserinheritdocinlinetag') return true;
+ }
+ }
+
+ /**
+ * @return boolean whether this desc has an {@}source} inline tag
+ */
+ function hasSource()
+ {
+ for($i=0;$i<count($this->value);$i++)
+ {
+ if (phpDocumentor_get_class($this->value[$i])=='parsersourceinlinetag') return true;
+ }
+ }
+
+ /**
+ * replaces {@}inheritdoc} with the contents of the parent DocBlock
+ * @param parserDesc parent parserDesc, used to retrieve the description
+ */
+ function replaceInheritDoc($desc)
+ {
+ $value = $this->value;
+ $this->value = array();
+ for($i=0;$i<count($value);$i++)
+ {
+ if (phpDocumentor_get_class($value[$i])=='parserinheritdocinlinetag')
+ {
+ for($j=0;$j<count($desc->value);$j++)
+ {
+ $this->add($desc->value[$j]);
+ }
+ } else $this->add($value[$i]);
+ }
+ }
+}
+
+/**
+ * Represents a docblock and its components, {@link $desc}, {@link $sdesc}, {@link $tags}, and also {@link $params} for functions
+ * @package phpDocumentor
+ * @subpackage ParserDocBlock
+ * @author Greg Beaver <cellog@php.net>
+ * @since 1.0rc1
+ * @version $Id: ParserDocBlock.inc 287886 2009-08-30 05:31:05Z ashnazg $
+ */
+class parserDocBlock
+{
+ /**
+ * @var parserDesc
+ */
+ var $desc = false;
+ /**
+ * @var array array of {@link parserDesc}s
+ */
+ var $processed_desc = false;
+ /**
+ * @var array array of {@link parserDesc}s
+ */
+ var $processed_sdesc = false;
+ /**
+ * @var parserDesc
+ */
+ var $sdesc = false;
+ /**
+ * Line number in the source on which this docblock begins
+ * @since 1.2
+ * @var false|integer
+ */
+ var $linenumber = false;
+ /**
+ * Line number in the source on which this docblock ends
+ * @since 1.2
+ * @var false|integer
+ */
+ var $endlinenumber = false;
+ /**
+ * array of {@link parserTag}s
+ * @var array
+ */
+ var $tags = array();
+ /**
+ * array of unrecognized {@link parserTag}s
+ * @var array
+ */
+ var $unknown_tags = array();
+ /**
+ * array of param data.
+ * Format:
+ * array(index of param in function parameter list -OR- parameter name =>
+ * parserStringWithInlineTags,...)
+ * @var array
+ */
+ var $params = array();
+ /**
+ * array of global variable data.
+ * Format:
+ * array(index of global variable in @global tag list -OR- global variable name =>
+ * array(datatype,parserStringWithInlineTags),...)
+ * @var array
+ */
+ var $funcglobals = array();
+
+ /**
+ * array of static variable data.
+ * Format:
+ * array(index of static variable in @global tag list -OR- static variable name =>
+ * {@link parserStaticvarTag},...)
+ * @var array
+ */
+ var $statics = array();
+ /**
+ * array of {@link parserPropertyTag}, {@link parserPropertyReadTag}, {@link parserPropertyWriteTag}, {@link parserMethodTag} magic tags
+ */
+ var $properties = array();
+ /**
+ * This is either a {@link parserReturnTag} or false if no return tag is present
+ * @var mixed
+ */
+ var $return = false;
+ /**
+ * This is either a {@link parserVarTag} or false if no var tag is present
+ * @var mixed
+ */
+ var $var = false;
+ /**
+ * fix for bug 591396
+ * @var boolean
+ */
+ var $explicitpackage = false;
+ /**
+ * fix for bug 708559
+ * @var boolean
+ */
+ var $explicitcategory = false;
+ /** @var string */
+ var $category;
+ /** @var string */
+ var $package = 'default';
+ /** @var string */
+ var $subpackage = '';
+ /**
+ * whether this DocBlock has an @access tag
+ * @var boolean */
+ var $hasaccess = false;
+ /**
+ * whether this DocBlock has a @name tag
+ * @var boolean */
+ var $hasname = false;
+ /**
+ * description of package parsed from @package tag
+ * Unused in this version
+ * @var string
+ */
+ var $packagedescrip = '';
+ /**
+ * description of subpackage parsed from @package tag
+ * Unused in this version
+ * @var string
+ */
+ var $subpackagedescrip = '';
+ /**
+ * Determines whether a DocBlock can legally have a {@}source} tag
+ * @tutorial tags.inlinesource.pkg
+ * @var boolean
+ * @access private
+ */
+ var $_canSource = false;
+
+ /**
+ * sets package to default
+ * @global string default package name
+ */
+ function parserDocBlock()
+ {
+ global $phpDocumentor_DefaultPackageName;
+ $this->package = $GLOBALS['phpDocumentor_DefaultPackageName'];
+ $this->category = $GLOBALS['phpDocumentor_DefaultCategoryName'];
+ }
+
+ /**
+ * Sets the starting line number for the DocBlock
+ * @param integer
+ */
+ function setLineNumber($number)
+ {
+ $this->linenumber = $number;
+ }
+
+ /**
+ * Retrieve starting line number
+ * @return integer
+ */
+ function getLineNumber()
+ {
+ return $this->linenumber;
+ }
+
+ /**
+ * Sets the ending line number for the DocBlock
+ * @param integer
+ */
+ function setEndLineNumber($number)
+ {
+ $this->endlinenumber = $number;
+ }
+
+ /**
+ * Retrieve ending line number
+ * @return integer
+ */
+ function getEndLineNumber()
+ {
+ return $this->endlinenumber;
+ }
+
+ /**
+ * Parse out any html tags from doc comments, and make them into
+ * abstract structures
+ * @uses parserDescParser::parse()
+ */
+ function postProcess()
+ {
+ if ($this->sdesc)
+ {
+ $parser = new parserDescParser;
+ $parser->subscribe('*',$this);
+ if ($this->desc) $parser->parse($this->desc->value);
+ $parser->parse($this->sdesc->value,true);
+ }
+ }
+
+ /**
+ * Tells the DocBlock it can have a @filesource tag
+ *
+ * Only page-level DocBlocks may have a @filesource tag
+ */
+ function canSource()
+ {
+ $this->_canSource = true;
+ }
+
+ /**
+ * Tells the DocBlock it can't have a @filesource tag
+ *
+ * Only page-level DocBlocks may have a @filesource tag
+ */
+ function cantSource()
+ {
+ $this->_canSource = false;
+ }
+
+ /**
+ * Indirectly called after parsing by {@link postProcess}
+ *
+ * @param integer either 1 for long desc or 2 for short desc
+ * @param array data organized into paragraphs. Each entry is a {@link parserStringWithInlineTags}
+ * @uses $processed_desc sets to the array passed from {@link parserDescParser::parse()}
+ * @uses $processed_sdesc sets to the array passed from {@link parserDescParser::parse()}
+ * @access private
+ */
+ function HandleEvent($event,$data)
+ {
+ if ($event == 1)
+ $this->processed_desc = $data;
+ else
+ $this->processed_sdesc = $data;
+ }
+
+ /**
+ * @param array
+ */
+ function updateModifiers($modifiers)
+ {
+ if (is_array($modifiers) && count($modifiers))
+ {
+ foreach ($modifiers as $modifier)
+ {
+ switch ($modifier)
+ {
+ case 'private' :
+ case 'public' :
+ case 'protected' :
+ unset($this->tags['access']);
+ $x = new parserAccessTag($modifier);
+ if ($x->isvalid)
+ {
+ $this->hasaccess = true;
+ $this->tags['access'][] = $x;
+ }
+ break;
+ case 'static' :
+ case 'abstract' :
+ unset($this->tags[$modifier]);
+ $this->addKeyword($modifier, '');
+ break;
+ }
+ }
+ }
+ }
+
+ /**
+ * Set the short description of the DocBlock
+ *
+ * Setting the short description is possible by passing in one of three
+ * possible parameters:
+ * <ul>
+ * <li>another DocBlock's short description</li>
+ * <li>another DocBlock, the short description will be extracted</li>
+ * <li>a Zend Studio-compatible @desc tag</li>
+ * </ul>
+ * @param parserDesc|parserDocBlock|parserTag sets {@link $sdesc}
+ */
+ function setShortDesc($desc)
+ {
+ if (phpDocumentor_get_class($desc) == 'parsertag')
+ {
+ $this->sdesc = new parserDesc;
+ $this->processed_sdesc = $desc->value;
+ return;
+ }
+ if (phpDocumentor_get_class($desc) == 'parserdesc') {
+ $this->sdesc = $desc;
+ } else
+ {
+ $this->sdesc = $desc->sdesc;
+ $this->processed_sdesc = $desc->processed_sdesc;
+ }
+
+ if ($this->sdesc && $this->sdesc->hasSource())
+ {
+ addWarning(PDERROR_SOURCE_TAG_IGNORED,$this->sdesc->getString());
+ }
+ }
+
+ /**
+ * Passes to {@link parserStringWithInlineTags::setSource()}
+ *
+ * After passing, it calls {@link postProcess()} to set up the new
+ * source
+ * @param string|array tokenized highlight-ready source code
+ * @param false|string name of class if this is a method source
+ */
+ function setSource($source, $class = false)
+ {
+ if ($this->desc)
+ {
+ $this->desc->setSource($source, $class);
+ $this->postProcess();
+ }
+ }
+
+ /**
+ * @param parserDesc|parserDocBlock sets {@link $desc}
+ */
+ function setDesc($desc)
+ {
+ if (phpDocumentor_get_class($desc) == 'parserdesc')
+ $this->desc = $desc;
+ else
+ {
+ $this->desc = $desc->desc;
+ $this->processed_desc = $desc->processed_desc;
+ }
+ }
+
+ /**
+ * Wrapper for {@link parserDesc::hasInheritDoc()}
+ * @return boolean
+ */
+ function hasInheritDoc()
+ {
+ if (!$this->desc) return false;
+ return $this->desc->hasInheritDoc();
+ }
+
+ /**
+ * Wrapper for {@link parserDesc::replaceInheritDoc()}
+ *
+ * Also replaces {@}inheritdoc} in the {@link $processed_desc}
+ * @param parserDesc
+ */
+ function replaceInheritDoc($desc)
+ {
+ if (!$this->desc) return false;
+ $this->desc->replaceInheritDoc($desc->desc);
+ $this->postProcess();
+ }
+
+ /**
+ * @param Converter takes {@link $sdesc} and converts it to a string and returns it if present, otherwise returns ''
+ * @return string
+ */
+ function getSDesc(&$converter)
+ {
+ if ($this->sdesc && $this->processed_sdesc)
+ {
+ $result = '';
+ foreach($this->processed_sdesc as $desc)
+ {
+ if (count($desc->value))
+ $result .= $desc->Convert($converter);
+ }
+ return $result;
+ } else
+ {
+// var_dump($this->desc,$this->processed_desc);
+ }
+ return '';
+ }
+
+ /**
+ * @param Converter takes {@link $desc} and converts it to a string and returns it if present, otherwise returns ''
+ * @return string
+ */
+ function getDesc(&$converter)
+ {
+ if ($this->desc && $this->processed_desc)
+ {
+ $result = '';
+ foreach($this->processed_desc as $desc)
+ {
+ if (count($desc->value))
+ $result .= $converter->EncloseParagraph($desc->Convert($converter));
+ }
+ return $result;
+ } else
+ {
+// var_dump($this->desc,$this->processed_desc);
+ }
+ return '';
+ }
+
+ /**
+ * @param string $paramVar if empty, param is indexed in the order received and set using {@link changeParam()}
+ * @param parserStringWithInlineTags $value
+ */
+ function addParam($paramVar, $paramType, $value)
+ {
+ if (empty($paramVar))
+ $this->params[count($this->params)] = new parserParamTag($paramType,$value);
+ else
+ $this->params[$paramVar] = new parserParamTag($paramType,$value);
+ }
+
+ function resetParams()
+ {
+ $this->params = array();
+ }
+ /**
+ * @param integer $index index of parameter in the {@link $params} array
+ * @param string $name name of the parameter to set in the $params array
+ * @param string|null $type type of the parameter
+ */
+ function changeParam($index, $name, $type)
+ {
+ if ($name === $index) {
+ return;
+ }
+ $this->params[$name] = $this->params[$index];
+ unset($this->params[$index]);
+ }
+
+ /**
+ * replaces nameless parameters in the {@link $params} array with their names
+ * add @param tags for params in the function with no entry
+ * @param array $params Format: array(parameter key =>
+ * array(0 => parameter name[,1 => default value][,2 => type hint]),...)
+ */
+ function updateParams($params)
+ {
+ $countparams = array_values($params);
+ reset($params);
+ for($i=0;$i<count($countparams);$i++, next($params))
+ {
+ if (isset($this->params[$i]))
+ {
+ $info = current($params);
+ $type = isset($info[2]) ? $info[2] : null;
+ $this->changeParam($i, key($params), $type);
+ $params[key($params)] = false;
+ }
+ }
+ $blank = new parserStringWithInlineTags;
+ foreach ($params as $key => $info) {
+ if (!$info) {
+ continue;
+ }
+ $type = isset($info[2]) ? $info[2] : null;
+ if (!isset($this->params[$info[0]])) {
+ $this->addParam($info[0], $type, $blank);
+ }
+ }
+ reset($params);
+
+ if (isset($this->tags))
+ unset($this->tags['param']);
+ }
+
+ /**
+ * Used to insert DocBlock Template tags into a docblock
+ * @param parserTag tag
+ * @global array used to determine whether to add ignored tags, or not
+ */
+ function addTag($tag)
+ {
+ global $_phpDocumentor_setting;
+ if (phpDocumentor_setup::checkIgnoreTag($tag->keyword)) return;
+ $value = $tag->value;
+ if (is_array($value)) {
+ $value = empty($value[0]) ? '' : $value[0];
+ }
+ if ($tag->keyword == 'uses')
+ {
+ $this->addUses($value, $tag->_description);
+ } else
+ {
+ $this->addKeyword($tag->keyword, $value);
+ }
+ }
+
+ /**
+ * @param string $keyword tag name
+ * @param parserStringWithInlineTags $value the contents of the tag
+ * @global array used to determine whether to add the @internal tag or not
+ */
+ function addKeyword($keyword, $value)
+ {
+ global $_phpDocumentor_setting;
+ $keyword = trim($keyword);
+ if (phpDocumentor_setup::checkIgnoreTag($keyword)) return;
+ // don't add the tag at all if it was specified to ignore it with --ignore-tags
+ if ($keyword == 'package' || $keyword == 'subpackage' || $keyword == 'category') return $this->addPackage($keyword, $value);
+ if ($keyword == 'access') return $this->addAccess($value);
+ if ($keyword == 'link') return $this->addLink($value);
+ if ($keyword == 'see' || $keyword == 'tutorial') return $this->addSee($keyword,$value);
+ if ($keyword == 'uses') return $this->addUses($keyword, $value);
+ if ($keyword == 'name') return $this->addName($value);
+ if (!in_array($keyword,$GLOBALS['_phpDocumentor_tags_allowed']))
+ $this->addUnknownTag($keyword,$value);
+ else
+ {
+ if ($keyword == 'internal' && (!isset($_phpDocumentor_setting['parseprivate']) || $_phpDocumentor_setting['parseprivate'] == 'off')) return;
+ if (!isset($this->tags[$keyword])) {
+ $this->tags[$keyword] = array();
+ }
+ $ptag = 'parserTag';
+ if (class_exists('parser'.$keyword.'tag'))
+ $ptag = 'parser'.ucfirst($keyword).'Tag';
+ array_unshift($this->tags[$keyword], new $ptag($keyword, $value));
+ }
+ }
+
+ /**
+ * adds an @example tag
+ * @param string contents of the tag
+ * @param string path to the file containing this tag
+ */
+ function addExample($value, $path)
+ {
+ $this->tags['example'][] = new parserExampleTag($value, $path);
+ }
+
+ /**
+ * adds an unknown tag to the {@link $unknown_tags} array for use by custom converters
+ * @param string tag name
+ * @param string tag value
+ */
+ function addUnknownTag($keyword, $value)
+ {
+ addWarning(PDERROR_UNKNOWN_TAG,$keyword);
+ $this->unknown_tags[$keyword][] = new parserTag($keyword, $value);
+ }
+
+ /**
+ * set the element's package to the passed values. Used in {@link phpDocumentor_IntermediateParser} to align package of
+ * elements inside a class or procedural page to the package of the class/procedural page
+ * @param string
+ * @param string
+ * @param string
+ * @param string element name
+ * @param string element type (include, define, var, method, global, function, const)
+ */
+ function overridePackage($category, $package,$subpackage,$elname,$type)
+ {
+ if ($this->package != $GLOBALS['phpDocumentor_DefaultPackageName'])
+ {
+ addError(PDERROR_OVERRIDDEN_PACKAGE_TAGS,$elname,$type,$this->package);
+ $this->explicitpackage = false;
+ }
+ if (!empty($this->subpackage))
+ addError(PDERROR_OVERRIDDEN_SUBPACKAGE_TAGS,$type,$elname,$this->subpackage);
+ $this->package = $GLOBALS['phpDocumentor_DefaultPackageName'];
+ $this->subpackage = '';
+ $this->category = $category;
+ $this->addPackage('package',$package);
+ $this->addPackage('subpackage',$subpackage);
+ }
+
+ /**
+ * Used if this docblock has a @package tag.
+ *
+ * phpDocumentor will guess package for DocBlocks that don't have
+ * a @package tag
+ * @uses $explicitpackage
+ */
+ function setExplicitPackage()
+ {
+ $this->explicitpackage = true;
+ }
+
+ /**
+ * If the DocBlock has a @package tag, then this returns true
+ * @return boolean
+ */
+ function getExplicitPackage()
+ {
+ return $this->explicitpackage;
+ }
+
+ /**
+ * Used if this docblock has a @category tag.
+ *
+ * phpDocumentor will guess category for DocBlocks that don't have
+ * a @category tag
+ * @uses $explicitcategory
+ */
+ function setExplicitCategory()
+ {
+ $this->explicitcategory = true;
+ }
+
+ /**
+ * If the DocBlock has a @category tag, then this returns true
+ * @return boolean
+ */
+ function getExplicitCategory()
+ {
+ return $this->explicitcategory;
+ }
+
+ /**
+ * @param string $keyword tag name (either package or subpackage)
+ * @param mixed $value either a string or a parserStringWithInlineTags. Strips all inline tags and use the text as the package
+ */
+ function addPackage($keyword, $value)
+ {
+ if ($keyword == 'package')
+ {
+ if (!$this->explicitpackage)
+ {
+ if (!is_string($value))
+ $value = $value->getString();
+ $rest = '';
+ $value = explode(' ',$value);
+ if (count($value) - 1)
+ {
+ $rest = $value;
+ $value = trim($value[0]);
+ unset($rest[0]);
+ $rest = implode($rest,' ');
+ } else
+ {
+ $value = explode("\t",$value[0]);
+ if (count($value) - 1)
+ {
+ $rest = $value;
+ $value = trim($value[0]);
+ unset($rest[0]);
+ $rest = implode($rest,"\t");
+ } else $value = trim($value[0]);
+ }
+ $value = preg_replace('/[^\[\]0-9\-a-zA-Z_\x7f-\xff]/', '-', $value);
+ $this->packagedescrip = $this->package = trim($value);
+ if (!empty($rest)) $this->packagedescrip = $rest;
+ } else
+ {
+ if (is_string($value))
+ addError(PDERROR_MULTIPLE_PACKAGE_TAGS,$value);
+ else
+ addError(PDERROR_MULTIPLE_PACKAGE_TAGS,$value->getString());
+ }
+ } elseif ($keyword == 'subpackage')
+ {
+ if (empty($this->subpackage))
+ {
+ if (!is_string($value))
+ $value = $value->getString();
+ $rest = '';
+ $value = explode(' ',$value);
+ if (count($value) - 1)
+ {
+ $rest = $value;
+ $value = $value[0];
+ unset($rest[0]);
+ $rest = implode($rest,' ');
+ } else
+ {
+ $value = explode("\t",$value[0]);
+ if (count($value) - 1)
+ {
+ $rest = $value;
+ $value = $value[0];
+ unset($rest[0]);
+ $rest = implode($rest,"\t");
+ } else $value = $value[0];
+ }
+ if (!empty($value))
+ {
+ $value = preg_replace('/[^\[\]0-9\-a-zA-Z_\x7f-\xff]/', '-', $value);
+ }
+ $this->subpackage = trim($value);
+ if (!empty($rest)) $this->subpackagedescrip = $rest;
+ } else
+ {
+ if (is_string($value))
+ addError(PDERROR_MULTIPLE_SUBPACKAGE_TAGS,$value);
+ else
+ addError(PDERROR_MULTIPLE_SUBPACKAGE_TAGS,$value->getString());
+ }
+ } elseif ($keyword == 'category')
+ {
+ if (!$this->explicitcategory)
+ {
+ if (!is_string($value))
+ $value = $value->getString();
+ $value = preg_replace('/[^\[\]0-9\-a-zA-Z_\x7f-\xff]/', '-', $value);
+ $this->category = $value;
+ } else
+ {
+ if (is_string($value))
+ addError(PDERROR_MULTIPLE_CATEGORY_TAGS,$value);
+ else
+ addError(PDERROR_MULTIPLE_CATEGORY_TAGS,$value->getString());
+ }
+ }
+ }
+
+ /**
+ * Adds a @name tag to the tag list
+ * @param string new name of element
+ */
+ function addName($value)
+ {
+ if (is_object($value)) $value = $value->getString();
+ if (!$this->hasname)
+ {
+ $x = new parserNameTag('name',$value);
+ $this->hasname = true;
+ $this->tags['name'][] = $x;
+ } else
+ {
+ addError(PDERROR_MULTIPLE_NAME_TAGS,$value);
+ }
+ }
+
+ /**
+ * @param string if empty, staticvar is indexed in the order received and set using {@link changeStatic()}
+ * @param string data type
+ * @param parserStringWithInlineTags
+ */
+ function addStaticVar($staticvar, $type, $descrip)
+ {
+ if (empty($staticvar))
+ $this->statics[] = new parserStaticvarTag($type,$descrip);
+ else
+ $this->statics[$staticvar] = new parserStaticvarTag($type,$descrip);
+ }
+
+ /**
+ * adds a function declaration of @global to the {@link $funcglobals} array
+ * @param string global type
+ * @param string description of how the global is used in the function
+ */
+ function addFuncGlobal($type,$value)
+ {
+ $this->funcglobals[] = array($type,$value);
+ }
+
+ /**
+ * @param integer $index index of parameter in the {@link $funcglobals} array
+ * @param string $name name of the parameter to set in the $funcglobals array
+ */
+ function changeGlobal($index,$name)
+ {
+ $this->funcglobals[$name] = $this->funcglobals[$index];
+ unset($this->funcglobals[$index]);
+ }
+
+ /**
+ * @param integer $index index of parameter in the {@link $statics} array
+ * @param string $name name of the parameter to set in the $statics array
+ */
+ function changeStatic($index,$name)
+ {
+ $this->statics[$name] = $this->statics[$index];
+ unset($this->statics[$index]);
+ }
+
+ /**
+ * replaces nameless global variables in the {@link $funcglobals} array with their names
+ * @param array
+ */
+ function updateGlobals($funcs)
+ {
+ for($i=0;$i<count($funcs);$i++)
+ {
+ if (isset($this->funcglobals[$i]))
+ {
+ $this->changeGlobal($i,$funcs[$i]);
+ }
+ }
+ }
+
+ /**
+ * replaces nameless static variables in the {@link $statics} array with their names
+ * @param array
+ */
+ function updateStatics($funcs)
+ {
+ for($i=0;$i<count($funcs);$i++)
+ {
+ if (isset($this->statics[$i]))
+ {
+ $this->changeStatic($i,$funcs[$i]);
+ }
+ }
+ }
+
+ /**
+ * add an @access tag to the {@link tags} array
+ * @param string should be either public or private
+ */
+ function addAccess($value)
+ {
+ if (is_object($value)) $value = $value->getString();
+ $value = strtolower($value);
+ if (!$this->hasaccess)
+ {
+ $x = new parserAccessTag($value);
+ if ($x->isvalid)
+ {
+ $this->hasaccess = true;
+ $this->tags['access'][] = $x;
+ }
+ } else
+ {
+ if (is_string($value))
+ addError(PDERROR_MULTIPLE_ACCESS_TAGS,$value);
+ else
+ addError(PDERROR_MULTIPLE_ACCESS_TAGS,$value->getString());
+ }
+ }
+
+ /**
+ * Adds a new @filesource tag to the DocBlock
+ * @tutorial tags.filesource.pkg
+ * @param string full path to the file
+ * @param array tokenized source code, ordered by line number
+ */
+ function addFileSource($path, $source)
+ {
+ if (isset($this->tags['filesource'])) return;
+ $this->tags['filesource'][] = new parserFileSourceTag($path, $source);
+ }
+
+ /**
+ * creates a {@link parserLinkTag} and adds it to the {@link $tags} array
+ * @param string $link
+ */
+ function addLink($link)
+ {
+ if (phpDocumentor_setup::checkIgnoreTag('@link')) return;
+ $this->tags['link'][] = new parserLinkTag($link);
+ }
+
+ /**
+ * creates a {@link parserLinkTag} and adds it to the {@link $tags} array
+ * @param string either see or uses
+ * @param string $value
+ */
+ function addSee($keyword,$value)
+ {
+ if (phpDocumentor_setup::checkIgnoreTag($keyword)) return;
+ $tag = 'parser'.ucfirst($keyword).'Tag';
+ $this->tags[$keyword][] = new $tag($value);
+ }
+
+ /**
+ * creates a {@link parserReturnTag} and adds it to the {@link $tags} array
+ * @param string $returnType the one-word name of the return type (mixed should be used if more than one type)
+ * @param parserStringWithInlineTags $value
+ */
+ function addReturn($returnType, $value)
+ {
+ // only take the first one
+ if (!$this->return)
+ {
+ $this->return = new parserReturnTag($returnType, $value);
+ } else
+ {
+ addError(PDERROR_MULTIPLE_RETURN_TAGS,$returnType,$value->getString());
+ }
+ }
+
+ /**
+ * creates a {@link parserVarTag} and adds it to the {@link $tags} array
+ * @param string $varType the one-word name of the variable type (mixed should be used if more than one type)
+ * @param parserStringWithInlineTags $value
+ */
+ function addVar($varType, $value)
+ {
+ // only take the first one
+ if (!$this->var)
+ {
+ $this->var = new parserVarTag($varType, $value);
+ } else
+ {
+ addError(PDERROR_MULTIPLE_VAR_TAGS,$varType,$value->getString());
+ }
+ }
+
+ /**
+ * Adds a virtual @usedby tag to output
+ * @param abstractLink link to the element that has a @uses tag
+ * @param parserStringWithInlinetags description of how the elements uses
+ * this one
+ * @access private
+ */
+ function addUsedBy($link, $descrip)
+ {
+ $this->tags['usedby'][] = new parserUsedByTag($link, $descrip);
+ }
+
+ /**
+ * Add a @uses tag to the DocBlock
+ * @param string @see-style text, used for {@link Converter::getLink()}
+ * @param parserStringWithInlineTags description of how the used element is
+ * used
+ * @tutorial tags.uses.pkg
+ */
+ function addUses($seeel, $description)
+ {
+ $this->tags['uses'][] = new parserUsesTag($seeel, $description);
+ usort($this->tags['uses'], array($this, '_sortUses'));
+ }
+
+ /**
+ * Adds a @property(-read or -write) or @method magic tag to the DocBlock
+ */
+ function addProperty( $tagName, $propertyName, $propertyType, $value )
+ {
+ if ( empty( $propertyName ) )
+ {
+ addWarning ( PDERROR_MISSING_PROPERTY_TAG_NAME, $tagName, $tagName, $propertyType, $value->getString() );
+ }
+ else
+ {
+ switch ( $tagName )
+ {
+ case 'property':
+ $this->properties[ $propertyName ] = new parserPropertyTag( $propertyType, $value );
+ break;
+ case 'property-read':
+ $this->properties[ $propertyName ] = new parserPropertyReadTag( $propertyType, $value );
+ break;
+ case 'property-write':
+ $this->properties[ $propertyName ] = new parserPropertyWriteTag( $propertyType, $value );
+ break;
+ case 'method':
+ $this->properties[ $propertyName ] = new parserMethodTag( $propertyType, $value );
+ break;
+ }
+ }
+ }
+
+ /**
+ * Custom sorting function for sorting @uses tags
+ *
+ * @param parserTag $a
+ * @param parserTag $b
+ * @access private
+ * @return int
+ */
+ function _sortUses($a, $b)
+ {
+ return strnatcasecmp($a->getString(), $b->getString());
+ }
+
+ /**
+ * @param string
+ * @return mixed false if no keyword, unconverted value if one keyword, array of unconverted values if more than one keyword
+ */
+ function getKeyword($keyword)
+ {
+ if ($keyword == 'filesource' && !$this->_canSource) return false;
+ if (isset($this->tags[$keyword]))
+ {
+ if (count($this->tags[$keyword]) == 1)
+ {
+ return $this->tags[$keyword][0];
+ } else return $this->tags[$keyword];
+ } else return false;
+ }
+
+ /**
+ * @return array Format: array('var' => tag name, 'data' => unconverted tag value)
+ */
+ function listParams()
+ {
+ if (isset($this->params))
+ {
+ $ret = array();
+ foreach($this->params as $key => $val)
+ {
+ $ret[] = array("var" => ucfirst($key),"data" => $val);
+ }
+ return $ret;
+ } else {
+ return array();
+ }
+ }
+
+ /**
+ * @return array Format: array('var' => tag name, 'data' => unconverted tag value)
+ */
+ function listProperties()
+ {
+ $ret = array();
+ if (isset($this->properties))
+ {
+ foreach($this->properties as $key => $val)
+ {
+ $ret[] = array("var" => ucfirst($key),"data" => $val);
+ }
+ }
+ return $ret;
+ }
+
+ /**
+ * @param Converter
+ */
+ function listTags()
+ {
+ $tags = array();
+ foreach($this->tags as $keyword => $vals)
+ {
+ if ($keyword == 'filesource' && !$this->_canSource) continue;
+ foreach($vals as $val)
+ {
+ $tags[] = $val;
+ }
+ }
+ usort($tags,'tagsort');
+ return $tags;
+ }
+
+ /** @return string always 'docblock' */
+ function getType()
+ {
+ return 'docblock';
+ }
+}
+
+/**
+ * Determines the arbitrary tag rank value for a given tag
+ * @access private
+ */
+function getTagRanking($tag)
+{
+ switch(phpDocumentor_get_class($tag))
+ {
+ case 'parserreturntag' :
+ $o = 0;
+ break;
+ case 'parservartag' :
+ $o = 1;
+ break;
+ case 'parsertutorialtag' :
+ $o = 2;
+ break;
+ case 'parserstaticvartag' :
+ $o = 3;
+ break;
+ case 'parserseetag' :
+ $o = 10;
+ break;
+ case 'parserlinktag' :
+ $o = 11;
+ break;
+ case 'parsertag' :
+ switch ($tag->keyword)
+ {
+ case 'author' :
+ $o = 4;
+ break;
+ case 'version' :
+ $o = 5;
+ break;
+ case 'copyright' :
+ $o = 6;
+ break;
+ case 'deprecated' :
+ case 'deprec' :
+ $o = 12;
+ break;
+ case 'todo' :
+ case 'TODO' :
+ $o = 13;
+ break;
+ case 'abstract' :
+ $o = 14;
+ break;
+ default :
+ $o = 15;
+ break;
+ }
+ break;
+ case 'parseraccesstag' :
+ $o = 18;
+ break;
+ case 'parsernametag' :
+ $o = 19;
+ break;
+ default :
+ $o = 20;
+ break;
+ }
+ return $o;
+}
+
+/**
+ * Utilizes the getTagRanking method to determine tag sort order of two given tags
+ * @access private
+ */
+function tagsort($a, $b)
+{
+ $returnval = 0;
+ $o = getTagRanking($a);
+ $p = getTagRanking($b);
+ if ($o == $p) return 0;
+ if ($o < $p) return -1;
+ if ($o > $p) return 1;
+}
+?>