Skip to content
Snippets Groups Projects
Commit 11e9bec3 authored by Jean Valverde's avatar Jean Valverde :construction_site:
Browse files

Issue #3461538 by pdureau, mogtofu33: Twig validator: Shorter IF/FOR syntax,...

Issue #3461538 by pdureau, mogtofu33: Twig validator: Shorter IF/FOR syntax, check only if the if is for the same variable
parent 8599865a
Branches
Tags 1.0.0
No related merge requests found
Pipeline #405056 passed
......@@ -7,13 +7,15 @@ namespace Drupal\sdc_devel\Plugin\TwigValidatorRule;
use Drupal\Core\Logger\RfcLogLevel;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\sdc_devel\Attribute\TwigValidatorRule;
use Drupal\sdc_devel\TwigValidator\TwigNodeFinder;
use Drupal\sdc_devel\TwigValidatorRulePluginBase;
use Drupal\sdc_devel\ValidatorMessage;
use Twig\Node\Node;
use Drupal\sdc_devel\TwigValidator\NodeAttribute;
/**
* Plugin implementation of the twig_validator_rule.
*
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
*/
#[TwigValidatorRule(
id: 'node',
......@@ -50,12 +52,22 @@ final class TwigValidatorRuleNode extends TwigValidatorRulePluginBase {
return [ValidatorMessage::createForNode($id, $node, $message)];
case 'Twig\Node\ForNode':
$inConditionIf = TwigNodeFinder::findParentIs(
$node,
'Twig\Node\IfNode'
);
if (!$inConditionIf) {
return [];
if (!$node->hasAttribute(NodeAttribute::PARENT)) {
break;
}
$parent = $node->getAttribute(NodeAttribute::PARENT);
if (!$parent->hasAttribute(NodeAttribute::PARENT)) {
break;
}
$firstParent = $parent->getAttribute(NodeAttribute::PARENT);
if (!\is_a($firstParent, 'Twig\Node\IfNode')) {
break;
}
if (!$this->checkIfVariableName($node, $firstParent)) {
break;
}
$message = new TranslatableMarkup('Loop in a condition can be replaced by compact syntax without if.');
......@@ -65,4 +77,42 @@ final class TwigValidatorRuleNode extends TwigValidatorRulePluginBase {
return [];
}
/**
* Check variable name between 2 nodes.
*
* @param \Twig\Node\Node $forNode
* The for node.
* @param \Twig\Node\Node $ifNode
* The if node.
*
* @return bool
* If the variable name is the same.
*/
private function checkIfVariableName(Node $forNode, Node $ifNode): bool {
if (!$forNode->hasNode('seq')) {
return FALSE;
}
$forVariableName = $forNode->getNode('seq')->getAttribute('name');
if (!$ifNode->hasNode('tests')) {
return FALSE;
}
$ifNodes = $ifNode->getNode('tests');
foreach ($ifNodes->getIterator() as $value) {
$ifVariableName = FALSE;
if ($value->hasAttribute('name')) {
$ifVariableName = $value->getAttribute('name');
}
if ($value->hasNode('left')) {
$ifVariableName = $value->getNode('left')->getAttribute('name');
}
if ($ifVariableName === $forVariableName) {
return TRUE;
}
}
return FALSE;
}
}
......@@ -35,6 +35,7 @@ final class TwigValidatorRuleNodeTest extends TwigValidatorTestBase {
{% set foo = ['foo', 'bar'] %}
{% for item in foo %}{{ item }}{% else %}No foo{% endfor %} {# valid, no message #}
{% if foo %}{% for item in foo %}{{ item }}{% endfor %}{% else %}No foo{% endif %}
{% if foo %}<span>{% for item in foo %}{{ item }}{% endfor %}{% else %}No foo</span>{% endif %} {# ignored because string #}
",
[
[1, RfcLogLevel::ERROR],
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment