getName(); } /** * Print the method, property or class modifiers. * * Technically this should be a trait. Can't wait for 5.4 :) * * @param \Reflector $reflector * * @return string Formatted modifiers */ private static function formatModifiers(\Reflector $reflector) { return implode(' ', array_map(function ($modifier) { return sprintf('%s', $modifier); }, \Reflection::getModifierNames($reflector->getModifiers()))); } /** * Format a class signature. * * @param \ReflectionClass $reflector * * @return string Formatted signature */ private static function formatClass(\ReflectionClass $reflector) { $chunks = array(); if ($modifiers = self::formatModifiers($reflector)) { $chunks[] = $modifiers; } if (version_compare(PHP_VERSION, '5.4', '>=') && $reflector->isTrait()) { $chunks[] = 'trait'; } else { $chunks[] = $reflector->isInterface() ? 'interface' : 'class'; } $chunks[] = sprintf('%s', self::formatName($reflector)); if ($parent = $reflector->getParentClass()) { $chunks[] = 'extends'; $chunks[] = sprintf('%s', $parent->getName()); } $interfaces = $reflector->getInterfaceNames(); if (!empty($interfaces)) { sort($interfaces); $chunks[] = 'implements'; $chunks[] = implode(', ', array_map(function ($name) { return sprintf('%s', $name); }, $interfaces)); } return implode(' ', $chunks); } /** * Format a constant signature. * * @param ReflectionConstant $reflector * * @return string Formatted signature */ private static function formatConstant(ReflectionConstant $reflector) { $value = $reflector->getValue(); $style = self::getTypeStyle($value); return sprintf( 'const %s = <%s>%s', self::formatName($reflector), $style, OutputFormatter::escape(Json::encode($value)), $style ); } /** * Helper for getting output style for a given value's type. * * @param mixed $value * * @return string */ private static function getTypeStyle($value) { if (is_int($value) || is_float($value)) { return 'number'; } elseif (is_string($value)) { return 'string'; } elseif (is_bool($value) || is_null($value)) { return 'bool'; } else { return 'strong'; } } /** * Format a property signature. * * @param \ReflectionProperty $reflector * * @return string Formatted signature */ private static function formatProperty(\ReflectionProperty $reflector) { return sprintf( '%s $%s', self::formatModifiers($reflector), $reflector->getName() ); } /** * Format a function signature. * * @param \ReflectionFunction $reflector * * @return string Formatted signature */ private static function formatFunction(\ReflectionFunctionAbstract $reflector) { return sprintf( 'function %s%s(%s)', $reflector->returnsReference() ? '&' : '', self::formatName($reflector), implode(', ', self::formatFunctionParams($reflector)) ); } /** * Format a method signature. * * @param \ReflectionMethod $reflector * * @return string Formatted signature */ private static function formatMethod(\ReflectionMethod $reflector) { return sprintf( '%s %s', self::formatModifiers($reflector), self::formatFunction($reflector) ); } /** * Print the function params. * * @param \ReflectionFunctionAbstract $reflector * * @return string */ private static function formatFunctionParams(\ReflectionFunctionAbstract $reflector) { $params = array(); foreach ($reflector->getParameters() as $param) { $hint = ''; try { if ($param->isArray()) { $hint = 'array '; } elseif ($class = $param->getClass()) { $hint = sprintf('%s ', $class->getName()); } } catch (\Exception $e) { // sometimes we just don't know... // bad class names, or autoloaded classes that haven't been loaded yet, or whathaveyou. // come to think of it, the only time I've seen this is with the intl extension. // Hax: we'll try to extract it :P $chunks = explode('$' . $param->getName(), (string) $param); $chunks = explode(' ', trim($chunks[0])); $guess = end($chunks); $hint = sprintf('%s ', $guess); } if ($param->isOptional()) { if (!$param->isDefaultValueAvailable()) { $value = 'unknown'; $typeStyle = 'urgent'; } else { $value = $param->getDefaultValue(); $typeStyle = self::getTypeStyle($value); $value = is_array($value) ? 'array()' : is_null($value) ? 'null' : var_export($value, true); } $default = sprintf(' = <%s>%s', $typeStyle, OutputFormatter::escape($value), $typeStyle); } else { $default = ''; } $params[] = sprintf( '%s%s$%s%s', $param->isPassedByReference() ? '&' : '', $hint, $param->getName(), $default ); } return $params; } }