Skip to content

Commit

Permalink
Disable interpolation in comments
Browse files Browse the repository at this point in the history
  • Loading branch information
kylekatarnls committed May 16, 2020
1 parent 512263a commit b53a717
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 34 deletions.
5 changes: 5 additions & 0 deletions src/Phug/Lexer/Lexer/AbstractToken.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,9 @@ public function markAsHandled()
{
$this->handled = true;
}

public function __toString()
{
return '['.get_class($this).']';
}
}
12 changes: 1 addition & 11 deletions src/Phug/Lexer/Lexer/Analyzer/LineAnalyzer.php
Original file line number Diff line number Diff line change
Expand Up @@ -122,17 +122,7 @@ public function getLines()
public function getFlatLines()
{
return array_map(function ($line) {
$rawText = '';

foreach ($line as $chunk) {
if ($chunk instanceof TokenInterface) {
continue;
}

$rawText .= $chunk;
}

return $rawText;
return implode('', $line);
}, $this->lines);
}

Expand Down
1 change: 1 addition & 0 deletions src/Phug/Lexer/Lexer/Scanner/CommentScanner.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public function scan(State $state)
$token = $state->createToken(TextToken::class);

$analyzer = new LineAnalyzer($state, $reader, $lines);
$analyzer->disallowInterpolation();
$analyzer->analyze(false);
$lines = $analyzer->getFlatLines();

Expand Down
46 changes: 32 additions & 14 deletions src/Phug/Lexer/Lexer/Scanner/InterpolationScanner.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,35 @@

class InterpolationScanner implements ScannerInterface
{
protected $interpolationChars = [
'tagInterpolation' => ['[', ']'],
'interpolation' => ['{', '}'],
];

protected $regExp;

public function __construct()
{
$interpolations = [];
$backIndex = 2;

foreach ($this->interpolationChars as $name => list($start, $end)) {
$start = preg_quote($start, '/');
$end = preg_quote($end, '/');
$interpolations[] = $start.'(?<'.$name.'>'.
'(?>"(?:\\\\[\\S\\s]|[^"\\\\])*"|\'(?:\\\\[\\S\\s]|[^\'\\\\])*\'|[^'.
$start.$end.
'\'"]++|(?-'.$backIndex.'))*+'.
')'.$end;
$backIndex++;
}

$this->regExp = '(?<text>.*?)'.
'(?<!\\\\)'.
'(?<escape>#|!(?='.preg_quote($this->interpolationChars['interpolation'][0], '/').'))'.
'(?<wrap>'.implode('|', $interpolations).')';
}

protected function throwEndOfLineExceptionIf(State $state, $condition)
{
if ($condition) {
Expand Down Expand Up @@ -103,21 +132,9 @@ public function scan(State $state)
{
$reader = $state->getReader();

//TODO: $state->endToken
while ($reader->match(
'(?<text>.*?)'.
'(?<!\\\\)'.
'(?<escape>#|!(?=\{))(?<wrap>'.
'\\[(?<tagInterpolation>'.
'(?>"(?:\\\\[\\S\\s]|[^"\\\\])*"|\'(?:\\\\[\\S\\s]|[^\'\\\\])*\'|[^\\[\\]\'"]++|(?-2))*+'.
')\\]|'.
'\\{(?<interpolation>'.
'(?>"(?:\\\\[\\S\\s]|[^"\\\\])*"|\'(?:\\\\[\\S\\s]|[^\'\\\\])*\'|[^{}\'"]++|(?-3))*+'.
')\\}'.
')'
)) {
while ($reader->match($this->regExp)) {
$text = $reader->getMatch('text');
$text = preg_replace('/\\\\([#!]\\[|#\\{)/', '$1', $text);
$text = preg_replace('/\\\\([#!]\\[|#{)/', '$1', $text);

if (mb_strlen($text) > 0) {
/** @var TextToken $token */
Expand All @@ -142,6 +159,7 @@ public function scan(State $state)
/** @var TextToken $token */
$token = $state->createToken(TextToken::class);
$token->setValue("\n");

yield $token;
}
}
Expand Down
22 changes: 14 additions & 8 deletions tests/Phug/Lexer/Scanner/CommentScannerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -151,25 +151,31 @@ public function testCommentInIndent()
*/
public function testInterpolationInComment()
{
$code = implode("\n", [
'//',
$comment = implode("\n", [
'',
' p.',
' go to #[a(href=\'\') page]',
]);

$this->assertTokens($code, [
$this->assertTokens("//$comment", [
CommentToken::class,
TextToken::class,
], null, $tokens);

/** @var TextToken $text */
$text = $tokens[1];

$this->assertSame(implode("\n", [
'',
' p.',
' go to page',
]), $text->getValue());
$this->assertSame($comment, $text->getValue());

$this->assertTokens("//-$comment", [
CommentToken::class,
TextToken::class,
], null, $tokens);

/** @var TextToken $text */
$text = $tokens[1];

$this->assertSame($comment, $text->getValue());
}

/**
Expand Down
2 changes: 1 addition & 1 deletion tests/Phug/Lexer/Scanner/InterpolationScannerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ public function testNewLineInTagInterpolation()
$this->expectMessageToBeThrown('End of line was reached with no closing bracket for interpolation.');

$input = "p #[em\n]";
$tokens = iterator_to_array($this->lexer->lex($input));
iterator_to_array($this->lexer->lex($input));
}

/**
Expand Down
10 changes: 10 additions & 0 deletions tests/Phug/Lexer/Token/InterpolationStartTokenTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,14 @@ public function testEnd()
$start->setEnd($end);
self::assertSame($end, $start->getEnd());
}

/**
* @covers ::__toString
*/
public function testStringification()
{
$start = new InterpolationStartToken();

self::assertSame('['.InterpolationStartToken::class.']', "$start");
}
}

0 comments on commit b53a717

Please sign in to comment.