Skip to content

Commit

Permalink
Merge pull request #91 from phug-php/fix/expression-read-in-assignment
Browse files Browse the repository at this point in the history
Fix expression read in assignments
  • Loading branch information
kylekatarnls authored Oct 8, 2022
2 parents ef09097 + 7533aaf commit 9a03e8e
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 25 deletions.
41 changes: 32 additions & 9 deletions .multi-tester.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
pug-php/pug: default
pug-php/pug:
install:
- composer config --no-plugins allow-plugins.nodejs-php-fallback/nodejs-php-fallback true
- composer install --no-interaction

pug/bemto:
autoload:
Expand All @@ -8,11 +11,20 @@ pug/bemto:
- composer dump-autoload --optimize --no-interaction --quiet
- composer self-update --2

pug-php/pug-assets: default
pug-php/pug-assets:
install:
- composer config --no-plugins allow-plugins.nodejs-php-fallback/nodejs-php-fallback true
- composer install --no-interaction

pug-php/pug-minify: default
pug-php/pug-minify:
install:
- composer config --no-plugins allow-plugins.nodejs-php-fallback/nodejs-php-fallback true
- composer install --no-interaction

pug/slim: default
pug/slim:
install:
- composer config --no-plugins allow-plugins.nodejs-php-fallback/nodejs-php-fallback true
- composer install --no-interaction

pug/twig:
autoload:
Expand All @@ -21,8 +33,19 @@ pug/twig:
- composer dump-autoload --optimize --no-interaction --quiet
- composer self-update --2

ci-pug/ci-pug: default

bkwld/laravel-pug: default

pug/yii2: default
ci-pug/ci-pug:
install:
- composer config --no-plugins allow-plugins.nodejs-php-fallback/nodejs-php-fallback true
- composer install --no-interaction

bkwld/laravel-pug:
install:
- composer config --no-plugins allow-plugins.pug/installer true
- composer config --no-plugins allow-plugins.nodejs-php-fallback/nodejs-php-fallback true
- composer install --no-interaction

pug/yii2:
install:
- composer config --no-plugins allow-plugins.yiisoft/yii2-composer true
- composer config --no-plugins allow-plugins.nodejs-php-fallback/nodejs-php-fallback true
- composer install --no-interaction
10 changes: 8 additions & 2 deletions src/Phug/Lexer/Lexer/Scanner/AssignmentScanner.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,15 @@ class AssignmentScanner implements ScannerInterface
{
public function scan(State $state)
{
return $state->scanToken(
foreach ($state->scanToken(
AssignmentToken::class,
'&(?<name>[a-zA-Z_][a-zA-Z0-9\-_]*)'
);
) as $token) {
yield $token;

foreach ($state->scan(AttributeScanner::class, ['allow_name' => false]) as $attributeToken) {
yield $attributeToken;
}
}
}
}
30 changes: 20 additions & 10 deletions src/Phug/Lexer/Lexer/Scanner/AttributeScanner.php
Original file line number Diff line number Diff line change
Expand Up @@ -120,13 +120,15 @@ private function getAttributeValue(Reader $reader, array $chars = null)
return $expression;
}

private function readAttributeValue(Reader $reader, AttributeToken $token)
private function readAttributeValue(Reader $reader, AttributeToken $token, $expression = '')
{
$expression = $this->getAttributeValue($reader);
$expression .= $this->getAttributeValue($reader);

while ($this->isTruncatedExpression($reader, $expression)) {
$this->skipComments($reader);
$expression .= $this->getAttributeValue($reader);
}

$token->setValue($expression);

//Ignore a comma if found
Expand Down Expand Up @@ -212,17 +214,25 @@ private function getAttributeToken(State $state)
$token->escape();
$token->check();

if ($variadic = $reader->peekString('...')) {
if ($reader->peekString('...')) {
$token->setIsVariadic(true);
$reader->consume();
}

return $token;
}

private function seedAttributeToken(State $state, AttributeToken $token, $expression)
private function seedAttributeToken(State $state, AttributeToken $token, $expression, array $options)
{
$reader = $state->getReader();
$allowName = isset($options['allow_name']) ? $options['allow_name'] : true;

if (!$allowName) {
$this->readAttributeValue($reader, $token, $expression);
$this->skipComments($reader);

return;
}

$token->setName($expression);

Expand Down Expand Up @@ -254,7 +264,7 @@ private function seedAttributeToken(State $state, AttributeToken $token, $expres
}
}

private function scanParenthesesContent(State $state)
private function scanParenthesesContent(State $state, array $options)
{
$reader = $state->getReader();

Expand All @@ -265,7 +275,7 @@ private function scanParenthesesContent(State $state)
continue;
}

$this->seedAttributeToken($state, $token, $expression);
$this->seedAttributeToken($state, $token, $expression, $options);

yield $token;

Expand All @@ -277,15 +287,15 @@ private function scanParenthesesContent(State $state)
}
}

private function scanParentheses(State $state)
private function scanParentheses(State $state, array $options)
{
$reader = $state->getReader();

if ($reader->peekChar(')')) {
return;
}

foreach ($this->scanParenthesesContent($state) as $token) {
foreach ($this->scanParenthesesContent($state, $options) as $token) {
yield $token;
}

Expand All @@ -296,7 +306,7 @@ private function scanParentheses(State $state)
}
}

public function scan(State $state)
public function scan(State $state, array $options = [])
{
$reader = $state->getReader();

Expand All @@ -309,7 +319,7 @@ public function scan(State $state)
$reader->consume();
yield $state->endToken($start);

foreach ($this->scanParentheses($state) as $token) {
foreach ($this->scanParentheses($state, $options) as $token) {
yield $token;
}

Expand Down
7 changes: 4 additions & 3 deletions src/Phug/Lexer/Lexer/State.php
Original file line number Diff line number Diff line change
Expand Up @@ -230,20 +230,21 @@ public function indent($level = null)
* use the `loopScan`-method
*
* @param array|string $scanners the scanners to run
* @param array $options options to be passed for the scanner
*
* @throws LexerException
*
* @return iterable the generator yielding all tokens found
*/
public function scan($scanners)
public function scan($scanners, array $options = [])
{
$scanners = $this->filterScanners($scanners);

foreach ($scanners as $key => $scanner) {
foreach ($scanners as $scanner) {

/** @var ScannerInterface $scanner */
$success = false;
foreach ($scanner->scan($this) as $token) {
foreach ($scanner->scan($this, $options) as $token) {
if (!($token instanceof TokenInterface)) {
$this->throwException(
'Scanner '.get_class($scanner).' generated a result that is not a '.TokenInterface::class
Expand Down
2 changes: 1 addition & 1 deletion tests/Phug/Lexer/Scanner/AssignmentScannerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public function testObjectInTernary()

self::assertSame(
'isNestedFile ? {\'href\': \'../account-orders.html\'} : {\'href\': \'accountorders.html\'}',
$tok->getName()
$tok->getValue()
);
}
}
24 changes: 24 additions & 0 deletions tests/Phug/Lexer/Scanner/AttributeScannerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Phug\Lexer;
use Phug\Lexer\Scanner\AttributeScanner;
use Phug\Lexer\State;
use Phug\Lexer\Token\AssignmentToken;
use Phug\Lexer\Token\AttributeEndToken;
use Phug\Lexer\Token\AttributeStartToken;
use Phug\Lexer\Token\AttributeToken;
Expand Down Expand Up @@ -601,4 +602,27 @@ public function testJsAttributeStyle()
self::assertSame('class', $class->getName());
self::assertSame('"a"', $class->getValue());
}

/**
* @covers \Phug\Lexer\Scanner\AssignmentScanner::scan
*/
public function testTernaryRendering()
{
list($tag, $assignment, $start, $attribute, $end) = $this->assertTokens(
'div&attributes(val === "42" ? {"answer": "42"} : {"ko": "failed"})',
[
TagToken::class,
AssignmentToken::class,
AttributeStartToken::class,
AttributeToken::class,
AttributeEndToken::class,
]
);

self::assertSame('div', $tag->getName());
self::assertSame('attributes', $assignment->getName());
self::assertSame(0, $start->getLevel());
self::assertSame('val === "42" ? {"answer": "42"} : {"ko": "failed"}', $attribute->getValue());
self::assertSame(0, $end->getLevel());
}
}
13 changes: 13 additions & 0 deletions tests/Phug/RendererTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1418,6 +1418,19 @@ public function testBooleanCastAbleObject()
self::assertSame('<p>if true</p><p>unless false</p><p>while</p><p>while</p>', trim($pug->render($code, $data)));
}

public function testTernaryRendering()
{
include_once __DIR__.'/Utils/BooleanAble.php';

$pug = new Renderer([
'modules' => [JsPhpizePhug::class],
]);
$code = 'div&attributes(val === "42" ? {"answer": "42"} : {"ko": "failed"})';

self::assertSame('<div answer="42"></div>', trim($pug->render($code, ['val' => '42'])));
self::assertSame('<div ko="failed"></div>', trim($pug->render($code, ['val' => '1'])));
}

private function getJsPhpizeVersion()
{
$directory = __DIR__.'/../../vendor/composer';
Expand Down

0 comments on commit 9a03e8e

Please sign in to comment.