/** * Get the type and name for this include. * * @param DocBlox_Token_Iterator $tokens * * @return void */ protected function processGenericInformation(DocBlox_Token_Iterator $tokens) { $this->type = ucwords(strtolower(str_replace('_', ' ', substr($tokens->current()->getName(), 2)))); if ($token = $tokens->gotoNextByType(T_CONSTANT_ENCAPSED_STRING, 10, array(';'))) { $this->setName(trim($token->getContent(), '\'"')); } elseif ($token = $tokens->gotoNextByType(T_VARIABLE, 10, array(';'))) { $this->setName(trim($token->getContent(), '\'"')); } }
/** * Retrieve the name of the class starting from the T_CLASS token. * * @param DocBlox_Token_Iterator $tokens * * @return string */ protected function extractClassName(DocBlox_Token_Iterator $tokens) { // a class name can be a combination of a T_NAMESPACE and T_STRING $name = ''; while ($token = $tokens->next()) { if (!in_array($token->type, array(T_WHITESPACE, T_STRING, T_NS_SEPARATOR))) { $tokens->previous(); break; } $name .= $token->content; } return trim($name); }
public function testGetTokenIdsOfParenthesisPair() { $this->object->seek(0); $this->object->gotoNextByType(T_FUNCTION, 0); $result = $this->object->getTokenIdsOfParenthesisPair(); $this->assertInternalType('array', $result, 'Expected result to be an array'); $this->assertArrayHasKey(0, $result, 'Expected result to have a start element'); $this->assertArrayHasKey(1, $result, 'Expected result to have an end element'); $this->assertEquals(17, $result[0], 'Expected the first brace to be at token id 17'); $this->assertEquals(18, $result[1], 'Expected the closing brace to be at token id 18'); }
/** * Returns the first docblock preceding the active token within 10 tokens. * * Please note that the iterator cursor does not change with to this method. * * @param DocBlox_Token_Iterator $tokens * * @return DocBlox_Reflection_DocBlock|null */ protected function findDocBlock(DocBlox_Token_Iterator $tokens) { $result = null; $docblock = $tokens->findPreviousByType(T_DOC_COMMENT, 10, array('{', '}', ';')); try { $result = $docblock ? new DocBlox_Reflection_DocBlock($docblock->getContent()) : null; if ($result) { // attach line number to class, the DocBlox_Reflection_DocBlock does not know the number $result->line_number = $docblock->getLineNumber(); } } catch (Exception $e) { $this->log($e->getMessage(), Zend_Log::CRIT); } $this->validateDocBlock($this->filename, $docblock ? $docblock->getLineNumber() : 0, $result); // if the object has no DocBlock _and_ is not a Closure; throw a warning $type = substr(get_class($this), strrpos(get_class($this), '_') + 1); if (!$result && ($type !== 'Function' && $this->getName() !== 'Closure')) { $this->log('No DocBlock was found for ' . $type . ' ' . $this->getName() . ' in file ' . $tokens->getFilename() . ' on line ' . $this->getLineNumber(), Zend_Log::ERR); } return $result; }
/** * Generic method which iterates through all tokens between the braces following the current position in the token * iterator. * * Please note: This method will also move the cursor position in the token iterator forward. * When a token is encountered this method will invoke the processToken method, which is defined in the * DocBlox_Reflection_Abstract class. Literals are ignored. * * @see DocBlox_Reflection_Abstract * * @param DocBlox_Token_Iterator $tokens * * @return int[] */ public function processTokens(DocBlox_Token_Iterator $tokens) { $level = -1; $start = 0; $end = 0; $token = null; // parse class contents $this->debug('>> Processing tokens'); while ($tokens->valid()) { /** @var DocBlox_Token $token */ $token = $token === null ? $tokens->current() : $tokens->next(); $token_type = false; $token_content = false; if ($token instanceof DocBlox_Token) { $token_type = $token->type; $token_content = $token->content; } // if we encounter a semi-colon before we have an opening brace then this is an abstract or interface function // which have no body; stop looking! if ($token_type === null && $token_content === ';' && $level === -1) { return array($start, $end); } // determine where the 'braced' section starts and end. // the first open brace encountered is considered the opening brace for the block and processing will // be 'breaked' when the closing brace is encountered if ((!$token_type || $token_type == T_CURLY_OPEN || $token_type == T_DOLLAR_OPEN_CURLY_BRACES) && ($token_content == '{' || $token_content == '}')) { switch ($token_content) { case '{': // expect the first brace to be an opening brace if ($level == -1) { $level++; $start = $tokens->key(); } $level++; break; case '}': if ($level == -1) { continue; } $level--; // reached the end; break from the while if ($level === 0) { $end = $tokens->key(); break 2; // time to say goodbye } break; } continue; } if ($token && $token_type) { // if a token is encountered and it is not a literal, invoke the processToken method $this->processToken($token, $tokens); } } // return the start and end token index return array($start, $end); }
/** * Retrieves the generic information. * * Finds out whether this variable has a default value and sets the name on top of the information found using the * DocBlox_Reflection_DocBlockedAbstract parent method. * * @param DocBlox_Token_Iterator $tokens * * @see DocBlox_Reflection_DocBlockedAbstract::processGenericInformation * * @return void */ protected function processGenericInformation(DocBlox_Token_Iterator $tokens) { $this->setName($tokens->current()->content); $this->default = $this->findDefault($tokens); parent::processGenericInformation($tokens); }
/** * Finds the name of this function starting from the T_FUNCTION token. * * If a function has no name it is probably a Closure and will have the name Closure. * * @param DocBlox_Token_Iterator $tokens * * @return string */ protected function findName(DocBlox_Token_Iterator $tokens) { $name = $tokens->findNextByType(T_STRING, 5, array('{', ';')); $this->setType($name ? self::TYPE_FUNCTION : self::TYPE_CLOSURE); return $name ? $name->content : 'Closure'; }
/** * Parses any T_STRING token to find generic keywords to process. * * This token is used to find any: * * * `define`, thus constants which are defined using the define keyword * * Globals * * @param DocBlox_Token_Iterator $tokens Tokens to interpret with the * pointer at the token to be processed. * * @todo implement globals support since the exact algorythm needs to be * defined, see GH #68 * * @return void */ protected function processString(DocBlox_Token_Iterator $tokens) { /** @var DocBlox_Token $token */ $token = $tokens->current(); switch ($token->getContent()) { case 'define': $this->resetTimer('constant'); $constant = new DocBlox_Reflection_Constant(); $constant->setFilename($this->filename); $constant->setNamespace($this->active_namespace); $constant->setNamespaceAliases($this->namespace_aliases); $constant->parseTokenizer($tokens); $this->debugTimer('>> Processed define: ' . $constant->getName(), 'constant'); $this->constants[$constant->getName()] = $constant; break; } }
/** * Retrieves the generic information. * * Finds out what the name and value is of this constant on top of the information found using the * DocBlox_Reflection_DocBlockedAbstract parent method. * * @param DocBlox_Token_Iterator $tokens * * @see DocBlox_Reflection_DocBlockedAbstract::processGenericInformation * * @return void */ protected function processGenericInformation(DocBlox_Token_Iterator $tokens) { if ($tokens->current()->getContent() == 'define') { // find the first encapsed string and strip the opening and closing // apostrophe $name_token = $tokens->gotoNextByType(T_CONSTANT_ENCAPSED_STRING, 5, array(',')); if (!$name_token) { $this->log('Unable to process constant in file ' . $tokens->getFilename() . ' at line ' . $tokens->current()->getLineNumber(), DocBlox_Core_Log::CRIT); return; } $this->setName(substr($name_token->getContent(), 1, -1)); // skip to after the comma while ($tokens->current()->getContent() != ',') { if ($tokens->next() === false) { break; } } // get everything until the closing brace and use that for value, take child parenthesis under consideration $value = ''; $level = 0; while (!($tokens->current()->getContent() == ')' && $level == -1)) { if ($tokens->next() === false) { break; } switch ($tokens->current()->getContent()) { case '(': $level++; break; case ')': $level--; break; } $value .= $tokens->current()->getContent(); } $this->setValue(trim(substr($value, 0, -1))); } else { $this->setName($tokens->gotoNextByType(T_STRING, 5, array('='))->getContent()); $this->setValue($this->findDefault($tokens)); } parent::processGenericInformation($tokens); }
/** * Retrieves the generic information. * * Find the name, type and default value for this argument. * * @param DocBlox_Token_Iterator $tokens * * @return void */ protected function processGenericInformation(DocBlox_Token_Iterator $tokens) { $this->setName($tokens->current()->getContent()); $this->type = $this->findType($tokens); $this->default = $this->findDefault($tokens); }
/** * Searches for visibility specifiers with the current token. * * @param DocBlox_Token_Iterator $tokens Token iterator to search in. * * @return string public|private|protected */ protected function findVisibility(DocBlox_Token_Iterator $tokens) { $result = 'public'; $result = $tokens->findPreviousByType(T_PRIVATE, 5, array('{', ';')) ? 'private' : $result; $result = $tokens->findPreviousByType(T_PROTECTED, 5, array('{', ';')) ? 'protected' : $result; return $result; }