diff --git a/src/Row.php b/src/Row.php index 4861031..89d3299 100644 --- a/src/Row.php +++ b/src/Row.php @@ -22,12 +22,14 @@ class Row { private array $phpTokenHighlightMap = [ // Delimiters - T_CLOSE_TAG => Highlight::DELIMITER, T_ARRAY => Highlight::DELIMITER, T_CURLY_OPEN => Highlight::DELIMITER, T_DOLLAR_OPEN_CURLY_BRACES => Highlight::DELIMITER, T_OPEN_TAG => Highlight::DELIMITER, T_OPEN_TAG_WITH_ECHO => Highlight::DELIMITER, + T_CLOSE_TAG => Highlight::DELIMITER, + T_START_HEREDOC => Highlight::DELIMITER, + T_END_HEREDOC => Highlight::DELIMITER, // Number literals T_DNUMBER => Highlight::NUMBER, @@ -432,15 +434,23 @@ class Row { protected function updateSyntaxPHP():void { - if ( ! isset($this->parent->syntax->tokens)) + $rowNum = $this->idx + 1; + + if ( + ( ! isset($this->parent->syntax->tokens)) + || ( ! array_key_exists($rowNum, $this->parent->syntax->tokens)) + || $this->idx > $this->parent->numRows) { return; } - // The index for the tokens should exist - $tokens = $this->parent->syntax->tokens[$this->idx + 1]; + $tokens = $this->parent->syntax->tokens[$rowNum]; + if (empty($tokens)) + { + return; + } - // $inComment = ($this->idx > 0 && $this->parent->rows[$this->idx - 1]->hlOpenComment); + $inComment = ($this->idx > 0 && $this->parent->rows[$this->idx - 1]->hlOpenComment); // Keep track of where you are in the line, so that // multiples of the same tokens can be effectively matched @@ -455,15 +465,65 @@ class Row { $char = $token['char']; $charLen = strlen($char); + if ($charLen === 0) + { + continue; + } $charStart = strpos($this->render, $char, $offset); if ($charStart === FALSE) { - $offset++; continue; } $charEnd = $charStart + $charLen; + // Comments + if ($inComment) + { + if (substr($this->render, $offset, 2) === '*/') + { + $inComment = FALSE; + array_replace_range($this->hl, $offset, 2, Highlight::ML_COMMENT); + $offset += 2; + continue; + } + + $this->hl[$offset] = Highlight::ML_COMMENT; + $offset++; + continue; + } + if (in_array($token['type'], [T_DOC_COMMENT, T_COMMENT], TRUE)) + { + // Single line comments + if (strpos($token['char'], '//') !== FALSE) + { + array_replace_range($this->hl, $charStart, $charLen, Highlight::COMMENT); + break; + } + + // Start of multi-line comment + $start = strpos($this->render, '/*', $offset); + $inComment = strpos($this->render, '*/', $offset) === FALSE; + array_replace_range($this->hl, $start, strlen($char) - $offset, Highlight::ML_COMMENT); + $offset = $start + strlen($char) - $offset; + + if ($inComment) + { + break; + } + + continue; + } + + // Highlight specific tokens + if (($token['typeName'] !== 'RAW') && array_key_exists($token['type'], $this->phpTokenHighlightMap)) + { + $hl = $this->phpTokenHighlightMap[$token['type']]; + array_replace_range($this->hl, $charStart, $charLen, $hl); + $offset = $charEnd; + continue; + } + // Highlight raw characters if (($token['typeName'] === 'RAW') && array_key_exists($token['char'], $this->phpCharacterHighlightMap)) { @@ -473,14 +533,14 @@ class Row { continue; } - // Highlight specific tokens - if (array_key_exists($token['type'], $this->phpTokenHighlightMap)) - { - $hl = $this->phpTokenHighlightMap[$token['type']]; - array_replace_range($this->hl, $charStart, $charLen, $hl); - $offset = $charEnd; - continue; - } + $offset++; + } + + $changed = $this->hlOpenComment !== $inComment; + $this->hlOpenComment = $inComment; + if ($changed && $this->idx + 1 < $this->parent->numRows) + { + $this->parent->rows[$this->idx + 1]->updateSyntax(); } } } diff --git a/src/functions.php b/src/functions.php index 517fefc..7b18b9e 100644 --- a/src/functions.php +++ b/src/functions.php @@ -340,6 +340,12 @@ function get_php_tokens(string $code): array [$type, $char, $currentLine] = $token; + // Only return the first line of a multi-line token + if ($char !== "\n" && strpos($char, "\n") !== FALSE) + { + $char = explode("\n", $char)[0]; + } + $current = [ 'type' => $type, 'typeName' => token_name($type), diff --git a/test.php b/test.php index 6153388..8d0db23 100644 --- a/test.php +++ b/test.php @@ -3,6 +3,13 @@ interface Ifoo {} abstract class Foo implements Ifoo { + /** + * @param int $a + * @param float $b + * @param array $c + * @param callable $d + * @return string + */ abstract public function bar(int $a, float $b, array $c, callable $d): string; protected function doNothing(): void {} @@ -46,7 +53,7 @@ $sql = <<{x} TEMPLATE;