Some progress on multi-line comments in PHP

This commit is contained in:
Timothy Warren 2019-11-05 16:56:18 -05:00
parent 155340df66
commit 0877bcd6dd
3 changed files with 88 additions and 15 deletions

View File

@ -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();
}
}
}

View File

@ -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),

View File

@ -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 = <<<SQL
SELECT * FROM "foo" WHERE "bar"='baz' AND id={$x};
SQL;
// Nowdoc
/* Nowdoc */
$template = <<<'TEMPLATE'
<foo>{x}</foo>
TEMPLATE;