public static function parsePhp($code)
{
if (Strings::match($code, '#//nette' . 'loader=(\\S*)#')) {
return;
}
$tokens = @token_get_all($code);
$namespace = $class = $classLevel = $level = $docComment = NULL;
$res = $uses = [];
while (list(, $token) = each($tokens)) {
switch (is_array($token) ? $token[0] : $token) {
case T_DOC_COMMENT:
$docComment = $token[1];
break;
case T_NAMESPACE:
$namespace = self::fetch($tokens, [T_STRING, T_NS_SEPARATOR]) . '\\';
$uses = [];
break;
case T_CLASS:
case T_INTERFACE:
case T_TRAIT:
if ($name = self::fetch($tokens, T_STRING)) {
$class = $namespace . $name;
$classLevel = $level + 1;
$res[$class] = [];
if ($docComment) {
$res[$class]['class'] = $docComment;
}
if ($uses) {
$res[$class]['use'] = $uses;
}
}
break;
case T_FUNCTION:
self::fetch($tokens, '&');
if ($level === $classLevel && $docComment && ($name = self::fetch($tokens, T_STRING))) {
$res[$class][$name] = $docComment;
}
break;
case T_VAR:
case T_PUBLIC:
case T_PROTECTED:
self::fetch($tokens, T_STATIC);
if ($level === $classLevel && $docComment && ($name = self::fetch($tokens, T_VARIABLE))) {
$res[$class][$name] = $docComment;
}
break;
case T_USE:
while (!$class && ($name = self::fetch($tokens, [T_STRING, T_NS_SEPARATOR]))) {
if (self::fetch($tokens, T_AS)) {
$uses[self::fetch($tokens, T_STRING)] = ltrim($name, '\\');
} else {
$tmp = explode('\\', $name);
$uses[end($tmp)] = $name;
}
if (!self::fetch($tokens, ',')) {
break;
}
}
break;
case T_CURLY_OPEN:
case T_DOLLAR_OPEN_CURLY_BRACES:
case '{':
$level++;
break;
case '}':
if ($level === $classLevel) {
$class = $classLevel = NULL;
}
$level--;
// break omitted
// break omitted
case ';':
$docComment = NULL;
}
}
return $res;
}