* @package phpDocumentor * @subpackage WordParsers * @since 1.2 */ /** * Like WordParser, but expects an array of tokens from the tokenizer instead * of a string. * @author Greg Beaver * @package phpDocumentor * @subpackage WordParsers * @since 1.2 */ class phpDocumentorTWordParser extends WordParser { /**#@+ * @access private */ /** * tokenized array from {@link token_get_all()} * @var array */ var $_all; /** * List of tokens that can contain a newline * @var array */ var $_nl_check = array( T_WHITESPACE, T_ENCAPSED_AND_WHITESPACE, T_COMMENT, T_DOC_COMMENT, T_OPEN_TAG, T_CLOSE_TAG, T_INLINE_HTML); /** * @var array */ var $_global_search; /** * current source line number (relative) * @var integer */ var $_sourceline; /** * Source of the entire file, parsed into arrays of tokens on each line * @var array */ var $_file_source = array(); /** * Line number the last comment was on * @var integer */ var $_docblock_linenum; /**#@-*/ /** * Uses {@link token_get_all()} to tokenize the source code. * {@internal * Also, it divides the source tokens into separate lines for use by * the @filesource tag. * * {@source}}} * @var string source code */ function setup(&$input) { $input = rtrim(ltrim($input, "\r\n")); $this->data = &$input; // fix php warnings on invalid source code $this->_all = @token_get_all($input); $this->_file_source = array(); $this->addFileSource($this->_all); $this->_sourceline = 0; $this->pos = 0; $this->linenum = 0; } /** * @return array */ function getSource() { $source = $this->source; $this->source = array(); $this->getsource = false; return $source; } /** * @return array source code tokens split up by line number */ function getFileSource() { return $this->_file_source; } /** * Begin retrieving source code * @access private * @param string word to add the beginning of source code */ function retrievesource($word = '') { $this->source = array(array($word)); $this->_sourceline = 0; $this->getsource = true; } /** * Utility function to determine whether two tokens from the tokenizer are equal * @static */ function tokenEquals($a, $b) { if (is_array($a)) $a = $a[1]; if (is_array($b)) $b = $b[1]; return $a == $b; } /** * Utility function to convert a series of tokens into a string * @static */ function concatTokens($a) { $b = ''; foreach($a as $c) { if (is_array($c)) $c = $c[1]; $b .= $c; } return $b; } /** * Retrieve a token for the phpDocumentorTParser * {@internal * This method adds source code to the array for a function to be returned * to a {@}source} tag, and will return the token unless it is T_WHITESPACE * and {@link $returnWhiteSpace} is false. * * The global variable search is more complicated than it is in the * WordParser, as we have to compare an array of tokens to each other, and * that is what this code does}} * @return string|array token from tokenizer */ function getWord() { if (!isset($this->_all[$this->pos])) return false; $oldlinenum = $this->linenum; $word = $this->_all[$this->pos++]; // if we're looking for a global variable declaration, then this section // will search the upcoming tokens to see if they match the tokens // that define the global variable if (isset($this->_global_search)) { $pos = $this->pos; $gpos = 0; $found = false; if ($this->tokenEquals($word,$this->_global_search[$gpos++])) { $found = true; for(;$gpos_global_search);$gpos++,$pos++) { if (!$this->tokenEquals($this->_global_search[$gpos],$this->_all[$pos])) $found = false; } } if ($found) { $a = $this->concatTokens($this->_global_search); $this->pos += count($this->_global_search) - 1; unset($this->_global_search); return $a; } } if ($this->getsource) { $this->addSource($word); } if (is_array($word)) { if (in_array($word[0],$this->_nl_check)) { $this->linenum += substr_count($word[1],"\n"); } if ($word[0] == T_WHITESPACE && !$this->returnWhiteSpace) return $this->getWord(); // seeing if we can get line numbers out of the beast } if (is_array($word) && $word[0] == T_COMMENT) $this->_docblock_linenum = $oldlinenum; return $word; } /** * Wrapper for {@link addSource()} used to retrieve the entire source code * organized by line number in setup() * @param array full file source code */ function addFileSource($word) { $this->_sourceline = 0; foreach($word as $token) { $this->addSource($token, true); } // var_dump($this->_file_source); } /** * Generate source token arrays organized by line number * * This code will split up tokens that contain "\n" and add them to the * source code as separate tokens on different lines. * @param array|string token to add * @param boolean true if this should be added to {@link $_file_source} * @param array|string next token, for lookahead splitting * @uses _set_sars() */ function addSource($word, $file = false) { if (is_array($word)) { $lines = str_replace("\r", '', explode("\n",$word[1])); foreach($lines as $i => $line) { $this->_set_sars($file, array($word[0],$line)); if ($i < count($lines) - 1) { // increment sourceline $this->_sourceline++; } } } else $this->_set_sars($file, $word); } /** * Add tokens to source code * * {@source} * @access private * @param boolean true if this is file source, otherwise it is function source * @param string|array token to add */ function _set_sars($type,$word) { if ($type) { $this->_file_source[$this->_sourceline][] = $word; } else { $this->source[$this->_sourceline][] = $word; } } /** * Tell the phpDocumentorTWordParser to return the entire global variable * if it is found. * @uses $_global_search * @param array tokens that represent the global variable definition */ function findGlobal($tokens) { if (!$tokens) { unset($this->_global_search); } else $this->_global_search = $tokens; } function backupPos() { $this->pos--; $word = $this->_all[$this->pos]; if ($this->getsource) { unset($this->source[$this->_sourceline][count($this->source[$this->_sourceline]) - 1]); if (empty($this->source[$this->_sourceline])) unset($this->source[$this->_sourceline]); else $this->source[$this->_sourceline] = array_values($this->source[$this->_sourceline]); } if (is_array($word)) { if ($word[0] == T_WHITESPACE && !$this->returnWhiteSpace) return $this->getWord(); // seeing if we can get line numbers out of the beast if (in_array($word[0],$this->_nl_check)) { $this->linenum -= substr_count($word[1],"\n"); } } } } ?>