3 * Parser Data Structures
\r
5 * phpDocumentor :: automatic documentation generator
\r
7 * PHP versions 4 and 5
\r
9 * Copyright (c) 2002-2006 Gregory Beaver
\r
13 * This library is free software; you can redistribute it
\r
14 * and/or modify it under the terms of the GNU Lesser General
\r
15 * Public License as published by the Free Software Foundation;
\r
16 * either version 2.1 of the License, or (at your option) any
\r
19 * This library is distributed in the hope that it will be useful,
\r
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
\r
22 * Lesser General Public License for more details.
\r
24 * You should have received a copy of the GNU Lesser General Public
\r
25 * License along with this library; if not, write to the Free Software
\r
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\r
28 * @package phpDocumentor
\r
29 * @subpackage ParserData
\r
30 * @author Gregory Beaver <cellog@php.net>
\r
31 * @copyright 2002-2006 Gregory Beaver
\r
32 * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
\r
33 * @version CVS: $Id: ParserData.inc,v 1.8 2007/04/24 21:27:43 ashnazg Exp $
\r
34 * @link http://www.phpdoc.org
\r
35 * @link http://pear.php.net/PhpDocumentor
\r
39 * Contains information about a PHP file, used to group procedural elements
\r
41 * @package phpDocumentor
\r
42 * @subpackage ParserData
\r
43 * @author Greg Beaver <cellog@php.net>
\r
45 * @version $Id: ParserData.inc,v 1.8 2007/04/24 21:27:43 ashnazg Exp $
\r
50 * Type is used by many functions to skip the hassle of if
\r
51 * <code>phpDocumentor_get_class($blah) == 'parserBlah'</code>
\r
56 * not implemented in this version, will be used to link xml output pages
\r
61 * filename.ext (no path)
\r
66 * relative source location
\r
69 var $sourceLocation = '';
\r
71 * phpdoc-safe name (only letters, numbers and _)
\r
76 * original phpdoc-safe name (only letters, numbers and _)
\r
78 * This fixes [ 1391432 ] Too many underscores in include links.
\r
85 var $category = 'default';
\r
89 var $package = 'default';
\r
93 var $subpackage = '';
\r
97 var $parserVersion = PHPDOCUMENTOR_VER;
\r
99 * not implemented yet
\r
100 * file modification date, will be used for makefiles
\r
105 * @var string full path this page represents
\r
109 * Tokenized source code of the file
\r
112 var $source = array();
\r
114 * Used to limit output, contains contents of --packageoutput commandline.
\r
115 * Does not increase parsing time. Use --ignore for that
\r
116 * @see phpDocumentor_IntermediateParser::$packageoutput, Converter::$package_output
\r
117 * @var mixed either false or an array of packages
\r
119 var $packageOutput = false;
\r
122 * sets package to default package
\r
123 * @global string default package name
\r
125 function parserPage()
\r
127 global $phpDocumentor_DefaultPackageName;
\r
128 $this->package = $GLOBALS['phpDocumentor_DefaultPackageName'];
\r
132 * @return string always "page"
\r
140 * Sets the source code of the file for highlighting.
\r
142 * PHP 4.3.0+ passes an array of tokenizer tokens by line number. PHP
\r
143 * 4.2.3- passes a string to be passed to {@link highlight_string()}
\r
144 * @param string|array
\r
146 function setSource($source)
\r
148 $this->source = $source;
\r
152 * Sets the name to display in documentation (can be an alias set with @name)
\r
153 * @param string $file
\r
155 function setFile($file)
\r
157 $this->file = $file;
\r
161 * @return string filename.ext or @name alias
\r
165 if (!isset($this->file)) return false;
\r
166 return $this->file;
\r
170 * @param string $path full path to file
\r
172 function setPath($path)
\r
174 // look for special windows case
\r
175 if(SMART_PATH_DELIMITER === '\\')
\r
176 $this->path = strtr($path,'/','\\');
\r
178 $this->path = $path;
\r
182 * @return string fully delimited path (OS-dependent format)
\r
186 if (!isset($this->path)) return false;
\r
187 return $this->path;
\r
191 * @param array $packages array of packages to display in documentation (package1,package2,...)
\r
192 * @see phpDocumentor_IntermediateParser::$packageoutput
\r
194 function setPackageOutput($packages)
\r
196 $this->packageOutput = $packages;
\r
200 * @return array array of packages (package1,package2,...)
\r
201 * @see phpDocumentor_IntermediateParser::$packageoutput
\r
203 function getPackageOutput()
\r
205 return $this->packageOutput;
\r
209 * @param string $name phpdoc-safe name (only _, numbers and letters) set by Parser::parse()
\r
210 * @see Parser::parse()
\r
212 function setName($name)
\r
214 $this->origName = $name;
\r
215 $this->name = $name;
\r
219 * @return string phpdoc-safe name (only _, numbers and letters)
\r
223 if (!isset($this->name)) return false;
\r
224 return $this->name;
\r
228 * @param string $source path of this file relative to program root
\r
230 function setSourceLocation($source)
\r
232 $this->sourceLocation = $source;
\r
237 * @param boolean if this parameter is true, it will truncate the source location to the
\r
238 * subdirectory of pear
\r
239 * @return string path of this file relative to program root
\r
240 * @todo determine if the str_replace in the 'pear/' ELSE branch should be removed
\r
241 * (see Documentation/tests/bug1574043.php). It does NOT exist in the similar
\r
242 * function parserClass->getSourceLocation() in ParserElements.inc.
\r
244 function getSourceLocation ($c,$pearize = false)
\r
246 global $_phpDocumentor_options;
\r
247 if (!isset($this->sourceLocation))
\r
253 $sl = $this->sourceLocation;
\r
256 if (strpos($sl,'pear/'))
\r
258 $sl = substr($sl,strpos($sl,'pear/') + 5);
\r
262 $sl = str_replace($_phpDocumentor_options['Program_Root'] . PATH_DELIMITER,'',$sl);
\r
269 * Not implemented in this version
\r
270 * @return boolean tell the parser whether to parse the file, otherwise
\r
271 * this function will retrieve the parsed data from external file
\r
273 function getParseData()
\r
280 * Contains an in-memory representation of all documentable elements
\r
281 * ({@link parserPage}, {@link parserFunction}, {@link parserDefine},
\r
282 * {@link parserInclude}, {@link parserClass}, {@link parserMethod},
\r
283 * {@link parserVar}) and their DocBlocks ({@link parserDocBlock}).
\r
285 * This class works in coordination with {@link phpDocumentor_IntermediateParser}
\r
286 * to take output from {@link Parser::handleEvent()} and create indexes, links,
\r
287 * and other assorted things (all documented in phpDocumentor_IntermediateParser
\r
288 * and {@link Converter})
\r
289 * @package phpDocumentor
\r
290 * @subpackage ParserData
\r
291 * @author Greg Beaver <cellog@php.net>
\r
293 * @version $Id: ParserData.inc,v 1.8 2007/04/24 21:27:43 ashnazg Exp $
\r
298 * {@link parserPage} element that is this parserData's parent, or false if
\r
300 * @var false|parserPage
\r
302 var $parent = false;
\r
304 * array of parsed elements
\r
307 var $elements = array();
\r
312 var $_hasclasses = false;
\r
317 var $_hasinterfaces = false;
\r
319 * array of parsed elements with @access private
\r
322 var $privateelements = array();
\r
324 * array of parsed class elements
\r
327 var $classelements = array();
\r
330 * @var parserTutorial|false
\r
332 var $tutorial = false;
\r
334 * array of parsed class elements with @access private
\r
337 var $privateclasselements = array();
\r
339 * array of links descended from {@link abstractLink}
\r
341 * @see pageLink, defineLink, classLink, functionLink, methodLink, varLink
\r
343 var $links = array();
\r
345 * used by {@link phpDocumentor_IntermediateParser::handleDocBlock()} to
\r
346 * determine whether a docblock is a page-level docblock or not. $clean is
\r
347 * true as long as only 0 or 1 docblock has been parsed, and no element
\r
348 * other than parserPage has been parsed
\r
353 * DocBlock ({@link parserDocBlock}) for this page, or false if not set
\r
356 var $docblock = false;
\r
358 * Flag used to determine whether a page-level docblock is present
\r
362 var $_explicitdocblock = false;
\r
364 * Type is used by many functions to skip the hassle of if
\r
365 * <code>phpDocumentor_get_class($blah) == 'parserBlah'</code>
\r
366 * always 'page', used in element indexing and conversion functions found in
\r
367 * {@link Converter}
\r
370 var $type = 'page';
\r
373 * @param parserElement add a parsed element to the {@link $elements} array,
\r
374 * also sets {@link $clean} to false
\r
376 function addElement(&$element)
\r
378 $element->setPath($this->parent->path);
\r
379 if ($element->getType() == 'class' || $element->getType() == 'method' || $element->getType() == 'var'
\r
380 || $element->getType() == 'const')
\r
382 if ($element->getType() == 'class') {
\r
383 if ($element->isInterface()) {
\r
384 $this->_hasinterfaces = true;
\r
386 $this->_hasclasses = true;
\r
389 $this->classelements[] = $element;
\r
392 $this->elements[] = $element;
\r
394 $this->clean = false;
\r
398 * Does this package have interfaces?
\r
402 function hasInterfaces()
\r
404 return $this->_hasinterfaces;
\r
408 * Does this package have classes?
\r
412 function hasClasses()
\r
414 return $this->_hasclasses;
\r
418 * @param parserTutorial
\r
421 function addTutorial($t,&$c)
\r
423 $this->tutorial = new tutorialLink;
\r
424 $this->tutorial->addLink('',$t->path,$t->name,$t->package,$t->subpackage,$t->getTitle($c));
\r
428 * If this file has a tutorial associated with it, returns a link to the
\r
430 * @return tutorialLink
\r
432 function getTutorial()
\r
434 return $this->tutorial;
\r
438 * If the page-level DocBlock was present in the source, returns true
\r
441 function hasExplicitDocBlock()
\r
443 return $this->_explicitdocblock;
\r
447 * Tells this page that its DocBlock was not implicit
\r
449 function explicitDocBlock()
\r
451 $this->_explicitdocblock = true;
\r
455 * @param parserElement element to add a new link (descended from
\r
456 * {@link abstractLink})to the {@link $links} array
\r
457 * @param string classname for elements that are class-based (this may be
\r
458 * deprecated in the future, as the classname should be
\r
459 * contained within the element. if $element is a page, this
\r
460 * parameter is a package name
\r
461 * @param string subpackage name for page elements
\r
463 function addLink(&$element,$classorpackage = '', $subpackage = '')
\r
465 switch($element->type)
\r
468 $x = new functionLink;
\r
469 $x->addLink($this->parent->path, $this->parent->name, $element->name, $element->docblock->package, $element->docblock->subpackage);
\r
473 $x = new defineLink;
\r
474 $x->addLink($this->parent->path, $this->parent->name, $element->name, $element->docblock->package, $element->docblock->subpackage);
\r
478 $x = new globalLink;
\r
479 $x->addLink($this->parent->path, $this->parent->name, $element->name, $element->docblock->package, $element->docblock->subpackage);
\r
483 $x = new classLink;
\r
484 $x->addLink($this->parent->path, $this->parent->name, $element->name, $element->docblock->package, $element->docblock->subpackage);
\r
488 $x = new methodLink;
\r
489 $x->addLink($classorpackage, $this->parent->path, $this->parent->name, $element->name, $element->docblock->package, $element->docblock->subpackage);
\r
494 $x->addLink($classorpackage, $this->parent->path, $this->parent->name, $element->name, $element->docblock->package, $element->docblock->subpackage);
\r
498 if (empty($classorpackage)) $classorpackage = $GLOBALS['phpDocumentor_DefaultPackageName'];
\r
500 $x->addLink($element->path,$element->name,$element->file,$classorpackage, $subpackage);
\r
506 function &getLink(&$c, $text = false)
\r
508 $a = $c->getPageLink($this->parent->file, $this->docblock->package, $this->parent->path, $text);
\r
513 * returns a list of all classes declared in a file
\r
514 * @param Converter &$c
\r
515 * @return array Format: array(packagename => parserClass,packagename => parserClass,...)
\r
517 function getClasses(&$c)
\r
519 $r = $c->classes->getClassesInPath($this->parent->path);
\r
522 foreach($r as $class => $obj)
\r
524 $rr[$obj->docblock->package][] = $obj;
\r
530 * Get the output-safe filename (. changed to _)
\r
535 if (isset($this->parent) && $this->parent)
\r
536 return $this->parent->getName();
\r
540 * @param parserPage parent element of this parsed data
\r
542 function setParent(&$parent)
\r
544 $this->parent = $parent;
\r
548 * @return bool returns the value of {@link $clean}
\r
552 return $this->clean;
\r
556 * @param parserDocBlock
\r
557 * @see parserDocBlock
\r
559 function setDocBlock(&$docblock)
\r
561 $this->docblock = $docblock;
\r
566 * Base class for all elements
\r
567 * @package phpDocumentor
\r
568 * @subpackage ParserData
\r
570 * @author Greg Beaver <cellog@php.net>
\r
572 * @version $Id: ParserData.inc,v 1.8 2007/04/24 21:27:43 ashnazg Exp $
\r
577 * Type is used by many functions to skip the hassle of if phpDocumentor_get_class($blah) == 'parserBlah'
\r
581 var $type = 'base';
\r
583 * set to different things by its descendants
\r
587 var $value = false;
\r
590 * @return string returns value of {@link $type}
\r
594 return $this->type;
\r
598 * @param mixed set the value of this element
\r
600 function setValue($value)
\r
602 $this->value = $value;
\r
606 * @return mixed get the value of this element (element-dependent)
\r
608 function getValue()
\r
610 return $this->value;
\r
616 * Used to represent strings that contain inline tags, so that they can be properly parsed at link time
\r
617 * @package phpDocumentor
\r
618 * @subpackage ParserData
\r
619 * @author Greg Beaver <cellog@php.net>
\r
621 * @version $Id: ParserData.inc,v 1.8 2007/04/24 21:27:43 ashnazg Exp $
\r
623 class parserStringWithInlineTags extends parserBase
\r
626 * Type is used by many functions to skip the hassle of if phpDocumentor_get_class($blah) == 'parserBlah'
\r
630 var $type = '_string';
\r
631 /** @access private */
\r
632 var $cache = false;
\r
634 * array of strings and {@link parserInlineTag}s
\r
636 * array(string1,string2,parserInlineTag1,string3,parserInlineTag2,...)
\r
639 var $value = array();
\r
642 * equivalent to the . operator ($a = $b . $c)
\r
643 * @param mixed either a string or a {@link parserInlineTag}
\r
645 function add($stringOrInlineTag)
\r
647 if (is_string($stringOrInlineTag))
\r
649 if (!count($this->value))
\r
651 $this->value[] = $stringOrInlineTag;
\r
654 if (is_string($this->value[count($this->value) - 1]))
\r
656 $this->value[count($this->value) - 1] .= $stringOrInlineTag;
\r
660 $this->value[] = $stringOrInlineTag;
\r
665 if (is_a($stringOrInlineTag,'parserinlinetag') && phpDocumentor_setup::checkIgnoreTag($stringOrInlineTag->inlinetype, true)) return;
\r
666 $this->value[] = $stringOrInlineTag;
\r
671 * Determine whether the string contains any inline tags
\r
672 * @tutorial inlinetags.pkg
\r
675 function hasInlineTag()
\r
677 for($i=0;$i<count($this->value);$i++)
\r
679 if (is_a($this->value[$i],'parserinlinetag')) return true;
\r
685 * Pass source code to any {@}source} tags contained within the string
\r
686 * for later conversion.
\r
687 * @param string|array source code ready to be highlighted
\r
689 function setSource($source)
\r
691 for($i=0;$i<count($this->value);$i++)
\r
693 if (phpDocumentor_get_class($this->value[$i]) == 'parsersourceinlinetag')
\r
695 $this->value[$i]->setSource($source);
\r
701 * equivalent to trim(strlen($string))
\r
702 * @return integer length of the string this object represents
\r
704 function trimmedStrlen()
\r
707 for($i=0;$i<count($this->value);$i++)
\r
709 if (is_string($this->value[$i]))
\r
713 $a += strlen(ltrim($this->value[$i]));
\r
714 } elseif ($i == count($this->value[$i]) - 1)
\r
716 $a += strlen(chop($this->value[$i]));
\r
720 $a += $this->value[$i]->Strlen();
\r
727 * return the string unconverted (all inline tags are taken out - this
\r
728 * should only be used in pre-parsing to see if any other text
\r
729 * is in the string)
\r
730 * @uses parserInlineTag::getString() removes inline tag length, as it is
\r
731 * indeterminate until conversion.
\r
732 * @return string trimmed value
\r
734 function getString($trim = true)
\r
737 for($i=0; $i<count($this->value); $i++)
\r
739 if (is_string($this->value[$i]))
\r
741 $a .= $this->value[$i];
\r
744 $a .= $this->value[$i]->getString();
\r
747 if ($trim) $a = trim($a);
\r
752 * Use to convert the string to a real string with all inline tags parsed and linked
\r
753 * @see Converter::returnSee()
\r
755 * @param boolean true if one needs to postprocess
\r
756 * @param boolean false if the output should not be trimmed
\r
758 function Convert(&$converter,$postprocess = true, $trim = true)
\r
762 if ($converter->name == $this->cache['name'] && $converter->outputformat == $this->cache['output'] && $converter->checkState($this->cache['state']) && $this->cache['postprocess'] === $postprocess) return $this->cache['contents'];
\r
763 if ($converter->name != $this->cache['name']) {
\r
764 $this->cache = false;
\r
767 if (is_string($this->value)) return $this->value;
\r
769 for($i=0; $i<count($this->value); $i++)
\r
771 if (is_string($this->value[$i]))
\r
773 if ($postprocess && !method_exists($converter,'postProcess')) var_dump('a',$converter);
\r
774 if ($postprocess) $a .= $converter->postProcess($this->value[$i]);
\r
775 else $a .= $this->value[$i];
\r
778 $a .= $this->value[$i]->Convert($converter, $postprocess);
\r
784 $this->cache = array('name' => $converter->name,'output' => $converter->outputformat, 'contents' => $a, 'state' => $converter->getState(), 'postprocess' => $postprocess);
\r