diff --git a/composer.json b/composer.json index 57ff4ed..2b63c77 100644 --- a/composer.json +++ b/composer.json @@ -16,10 +16,12 @@ "require-dev": { "ext-json": "*", "phpunit/phpunit": "^9.5.0", + "phpstan/phpstan": "^0.12.19", "spatie/phpunit-snapshot-assertions": "^4.2.0" }, "scripts": { "coverage": "phpdbg -qrr -- vendor/bin/phpunit -c phpunit.xml tests", + "phpstan": "phpstan analyse -c phpstan.neon", "test": "vendor/bin/phpunit -c phpunit.xml --no-coverage tests", "test-update": "vendor/bin/phpunit -c phpunit.xml --no-coverage -d --update-snapshots tests" }, diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..6633eab --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,8 @@ +parameters: + checkGenericClassInNonGenericObjectType: false + checkMissingIterableValueType: false + inferPrivatePropertyTypeFromConstructor: true + level: 8 + paths: + - src + - ./kilo \ No newline at end of file diff --git a/src/Row.php b/src/Row.php index ce0d9db..3b7aa92 100644 --- a/src/Row.php +++ b/src/Row.php @@ -36,7 +36,9 @@ class Row { T_START_HEREDOC => Highlight::DELIMITER, T_END_HEREDOC => Highlight::DELIMITER, - // Number literals + // Number literals and magic constants + T_DIR => Highlight::NUMBER, + T_TRAIT_C => Highlight::NUMBER, T_DNUMBER => Highlight::NUMBER, T_LNUMBER => Highlight::NUMBER, @@ -49,6 +51,7 @@ class Row { T_STRING_VARNAME => Highlight::VARIABLE, // Operators + T_AS => Highlight::OPERATOR, T_AND_EQUAL => Highlight::OPERATOR, T_BOOLEAN_AND => Highlight::OPERATOR, T_BOOLEAN_OR => Highlight::OPERATOR, @@ -107,9 +110,11 @@ class Row { T_ENDIF => Highlight::KEYWORD1, T_ENDSWITCH => Highlight::KEYWORD1, T_ENDWHILE => Highlight::KEYWORD1, + T_EXIT => Highlight::KEYWORD1, T_EXTENDS => Highlight::KEYWORD1, T_FINAL => Highlight::KEYWORD1, T_FINALLY => Highlight::KEYWORD1, + T_FN => Highlight::KEYWORD1, T_FOR => Highlight::KEYWORD1, T_FOREACH => Highlight::KEYWORD1, T_FUNCTION => Highlight::KEYWORD1, @@ -122,6 +127,7 @@ class Row { T_INSTEADOF => Highlight::KEYWORD1, T_INTERFACE => Highlight::KEYWORD1, T_NAMESPACE => Highlight::KEYWORD1, + T_MATCH => Highlight::KEYWORD1, T_NEW => Highlight::KEYWORD1, T_PRIVATE => Highlight::KEYWORD1, T_PUBLIC => Highlight::KEYWORD1, @@ -141,9 +147,10 @@ class Row { // Not string literals, but identifiers, keywords, etc. // T_STRING => Highlight::KEYWORD2, - // Type casts + // Types and casts T_ARRAY_CAST => Highlight::KEYWORD2, T_BOOL_CAST => Highlight::KEYWORD2, + T_CALLABLE => Highlight::KEYWORD2, T_DOUBLE_CAST => Highlight::KEYWORD2, T_INT_CAST => Highlight::KEYWORD2, T_OBJECT_CAST => Highlight::KEYWORD2, @@ -493,7 +500,7 @@ class Row { break; } - $char = $token['char'] ?? ''; + $char = $token['char']; // ?? ''; $charLen = strlen($char); if ($charLen === 0 || $offset >= $this->rsize) { @@ -546,29 +553,24 @@ class Row { } } - // Highlight specific tokens - if ($token['typeName'] !== 'RAW') + if (array_key_exists($token['type'], $this->phpTokenHighlightMap)) { - if (array_key_exists($token['type'], $this->phpTokenHighlightMap)) - { - $hl = $this->phpTokenHighlightMap[$token['type']]; - array_replace_range($this->hl, $charStart, $charLen, $hl); - $offset = $charEnd; - continue; - } + $hl = $this->phpTokenHighlightMap[$token['type']]; + array_replace_range($this->hl, $charStart, $charLen, $hl); + $offset = $charEnd; + continue; + } - // Types/identifiers/keywords that don't have their own token - if ($token['type'] === T_STRING && - in_array($token['char'], $this->parent->syntax->keywords2, TRUE)) - { - array_replace_range($this->hl, $charStart, $charLen, Highlight::KEYWORD2); - $offset = $charEnd; - continue; - } + // Types/identifiers/keywords that don't have their own token + if (in_array($token['char'], $this->parent->syntax->keywords2, TRUE)) + { + array_replace_range($this->hl, $charStart, $charLen, Highlight::KEYWORD2); + $offset = $charEnd; + continue; } // Highlight raw characters - if (($token['type'] === self::T_RAW) && array_key_exists(trim($token['char']), $this->phpCharacterHighlightMap)) + if (array_key_exists(trim($token['char']), $this->phpCharacterHighlightMap)) { $hl = $this->phpCharacterHighlightMap[trim($token['char'])]; array_replace_range($this->hl, $charStart, $charLen, $hl); diff --git a/src/functions.php b/src/functions.php index e204d67..10cb86e 100644 --- a/src/functions.php +++ b/src/functions.php @@ -249,7 +249,7 @@ function str_contains(string $haystack, string $str, ?int $offset = NULL): bool return ($offset !== NULL) ? strpos($haystack, $str, $offset) !== FALSE - : strpos($haystack, $str) !== FALSE; + : \str_contains($haystack, $str); } /** @@ -260,7 +260,8 @@ function str_contains(string $haystack, string $str, ?int $offset = NULL): bool */ function syntax_to_color(int $hl): int { - $map = [ + return match ($hl) + { Highlight::COMMENT => Color::FG_CYAN, Highlight::ML_COMMENT => Color::FG_BRIGHT_BLACK, Highlight::KEYWORD1 => Color::FG_YELLOW, @@ -272,11 +273,8 @@ function syntax_to_color(int $hl): int Highlight::DELIMITER => Color::FG_BLUE, Highlight::INVALID => Color::BG_BRIGHT_RED, Highlight::MATCH => Color::INVERT, - ]; - - return (array_key_exists($hl, $map)) - ? $map[$hl] - : Color::FG_WHITE; + default => Color::FG_WHITE, + }; } /** diff --git a/test.php b/test.php index 0fc75f3..49361d0 100644 --- a/test.php +++ b/test.php @@ -44,8 +44,33 @@ class FooBar extends Foo implements Ifoo { } } +trait Baz { + public function about(): array + { + return [ + '__CLASS__' => __CLASS__, + '__DIR__' => __DIR__, + '__FILE__' => __FILE__, + '__FUNCTION__' => __FUNCTION__, + '__LINE__' => __LINE__, + '__METHOD__' => __METHOD__, + '__NAMESPACE__' => __NAMESPACE__, + '__TRAIT__' => __TRAIT__, + ]; + } +} + $square = fn (int $x) => $x ** 2; +foreach ([-1, 0, 1, 2] as $x) +{ + $not = match ($x) { + 0 => 1, + 1,-1 => 0, + default => 0, + }; +} + /* * Multi-line comment */ diff --git a/tokens.php b/tokens.php new file mode 100644 index 0000000..bb76aec --- /dev/null +++ b/tokens.php @@ -0,0 +1,14 @@ +type = $token->getTokenName(); + return $token; +} + +$tokens = array_map('addName', $tokens); + +var_export($tokens); \ No newline at end of file