forks / luoyu / api_generator / branches / master / vendors / introspector.php
history
<?php
/* SVN FILE: $Id$ */
/**
* Introspector Introspect stuff
*
*
*
* PHP versions 4 and 5
*
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
* Copyright 2006-2008, Cake Software Foundation, Inc.
* 1785 E. Sahara Avenue, Suite 490-204
* Las Vegas, Nevada 89104
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @filesource
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
* @package cake
* @subpackage cake.api_generator.vendors
* @since
* @version
* @modifiedby
* @lastmodified
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
/**
* Introspector provides factory methods and common methods for
* reflection parsing
*
* @package cake.api_generator.vendors
*/
class Introspector {
/**
* reflector classMappings
*
* @var array
**/
protected static $_reflectorMap = array(
'class' => 'ClassDocumentor',
'function' => 'FunctionDocumentor',
);
/**
* Get the correct reflector type for the requested object
*
* @param string $type The type of reflector needed
* @param string $name The name of the function/class being reflected
* @return object constructed reflector type.
* @throws Exception
*/
public static function getReflector($type, $name = null) {
if ($name === null) {
$name = $type;
$type = 'class';
}
if (!isset(self::$_reflectorMap[$type])) {
throw new Exception('Missing reflector mapping type');
}
if (!class_exists(self::$_reflectorMap[$type])) {
$reflectorName = 'ApiGenerator.' . self::$_reflectorMap[$type];
App::import('Vendor', $reflectorName);
}
return new self::$_reflectorMap[$type]($name);
}
/**
* parseDocBlock
*
* Cleans input comments of stars and /'s so it is more readable.
* Creates a multi dimensional array. That contains semi parsed comments
*
* Returns an array with the following
* 'title' contains the title / first line of the doc-block
* 'desc' contains the remainder of the doc block
* 'tags' contains all the doc-blocks @tags.
*
* @param string $comments The comment block to be cleaned
* @return array Array of Filtered and separated comments
**/
public static function parseDocBlock($comments){
$com = array();
//remove stars and slashes
$tmp = preg_replace('#^(\s*/\*\*|\s*\*+/|\s+\* ?)#m', '', $comments);
//fix new lines
$tmp = str_replace("\r\n", "\n", $tmp);
$tmp = explode("\n", $tmp);
$desc = '';
$tags = array();
$preprocessed = array();
for ($i = 0, $count = count($tmp); $i < $count; $i++ ) {
$line = $tmp[$i];
if (substr($line, 0, 1) !== '@' && $line !== '*' && !isset($preprocessed[$i])) {
$desc .= "\n" . $line;
}
if (preg_match('/@([a-z0-9_-]+)\s(.*)$/i', $tmp[$i], $parsedTag)) {
// capture continued lines. (indented with 3 spaces or 1 tab)
$done = false;
$next = $i + 1;
while (!$done) {
if (isset($tmp[$next]) && preg_match('/^(?: {1,3}|\t)([^\t]*)$/i', $tmp[$next], $nextLine)) {
$parsedTag[2] .= ' ' . trim($nextLine[1]);
$preprocessed[$next] = true;
$next++;
} else {
$done = true;
}
}
if (isset($tags[$parsedTag[1]]) && !is_array($tags[$parsedTag[1]])) {
$tags[$parsedTag[1]] = (array)$tags[$parsedTag[1]];
$tags[$parsedTag[1]][] = $parsedTag[2];
} elseif (isset($tags[$parsedTag[1]]) && is_array($tags[$parsedTag[1]])) {
$tags[$parsedTag[1]][] = $parsedTag[2];
} else {
$tags[$parsedTag[1]] = $parsedTag[2];
}
}
}
if (isset($tags['param'])) {
$params = (array)$tags['param'];
$tags['param'] = array();
foreach ($params as $param) {
$paramDoc = explode(' ', $param, 3);
switch (count($paramDoc)) {
case 2:
list($type, $name) = $paramDoc;
break;
case 3:
list($type, $name, $description) = $paramDoc;
break;
}
$name = @trim($name, '$');
$tags['param'][$name] = compact('type', 'description');
}
}
$com['description'] = trim($desc);
$com['tags'] = $tags;
return $com;
}
/**
* Create a string representation of the method signature.
*
* @param ReflectionFunctionAbstract $func The function you want a signature for.
* @return void
**/
public static function makeFunctionSignature(ReflectionFunctionAbstract $func ) {
$signature = $func->getName() . '( ';
foreach ($func->getParameters() as $param) {
$signature .= '$' . $param->getName();
if ($param->isDefaultValueAvailable()) {
$signature .= ' = ' . var_export($param->getDefaultValue(), true);
}
$signature .= ', ';
}
if ($func->getNumberOfParameters() > 0) {
$signature = substr($signature, 0, -2);
}
$signature .= ' )';
return $signature;
}
}