112 lines
2.2 KiB
PHP
112 lines
2.2 KiB
PHP
<?php declare(strict_types=1);
|
|
|
|
namespace Aviat\Kilo\Tokens;
|
|
|
|
use function Aviat\Kilo\tabs_to_spaces;
|
|
|
|
class PHP {
|
|
/**
|
|
* Use 'token_get_all' to get the tokens for a file,
|
|
* organized by row number
|
|
*
|
|
* @param string $code
|
|
* @return array
|
|
*/
|
|
public static function getTokens(string $code): array
|
|
{
|
|
$rawTokens = token_get_all($code);
|
|
$tokens = [];
|
|
$lineNum = 1;
|
|
$line = [];
|
|
foreach($rawTokens as $t)
|
|
{
|
|
if (is_array($t))
|
|
{
|
|
[$type, $rawChar, $currentLine] = $t;
|
|
$char = tabs_to_spaces($rawChar);
|
|
|
|
$current = [
|
|
'type' => $type,
|
|
'typeName' => token_name($type),
|
|
'char' => $char,
|
|
'line' => $currentLine,
|
|
];
|
|
|
|
if ($char === "\n")
|
|
{
|
|
$line[] = $current;
|
|
$tokens[$lineNum] = $line;
|
|
$lineNum++;
|
|
$line = [];
|
|
}
|
|
|
|
// Only return the first line of a multi-line token for this line array
|
|
if ($char !== "\n" && strpos($char, "\n") !== FALSE)
|
|
{
|
|
$chars = explode("\n", $char);
|
|
$current['original'] = [
|
|
'string' => $char,
|
|
'lines' => $chars,
|
|
];
|
|
$current['char'] = array_shift($chars);
|
|
|
|
// Add new lines for additional newline characters
|
|
$nextLine = $currentLine;
|
|
foreach ($chars as $char)
|
|
{
|
|
$nextLine++;
|
|
|
|
if ( ! array_key_exists($nextLine, $tokens))
|
|
{
|
|
$tokens[$nextLine] = [];
|
|
}
|
|
|
|
$tokens[$nextLine][] = [
|
|
'type' => -1,
|
|
'typeName' => 'RAW',
|
|
'char' => $char,
|
|
];
|
|
}
|
|
}
|
|
|
|
if ($currentLine !== $lineNum)
|
|
{
|
|
$existing = $tokens[$lineNum] ?? [];
|
|
$tokens[$lineNum] = array_merge($existing, $line);
|
|
|
|
$lineNum = $currentLine;
|
|
$line = [];
|
|
}
|
|
|
|
$line[] = $current;
|
|
}
|
|
else if (is_string($t))
|
|
{
|
|
// Simple characters, usually delimiters or single character operators
|
|
$line[] = [
|
|
'type' => -1,
|
|
'typeName' => 'RAW',
|
|
'char' => tabs_to_spaces($t),
|
|
];
|
|
}
|
|
}
|
|
|
|
$tokens[$lineNum] = array_merge($tokens[$lineNum] ?? [], $line);
|
|
|
|
ksort($tokens);
|
|
|
|
return $tokens;
|
|
}
|
|
|
|
public static function getFileTokens(string $filename): array
|
|
{
|
|
$code = file_get_contents($filename);
|
|
|
|
if ($code === FALSE)
|
|
{
|
|
return [];
|
|
}
|
|
|
|
return self::getTokens($code);
|
|
}
|
|
} |