Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Twig 4] Introduce ForElseNode #4473

Open
wants to merge 1 commit into
base: 4.x
Choose a base branch
from
Open

Commits on Nov 24, 2024

  1. Introduce ForElseNode

    Currently there is no line number information for `{% else %}` inside a `for` loop.
    
    Normally, this wouldn't be such a big deal.
    
    But TwigStan uses this line information to map errors in PHP back to the original Twig source.
    
    Let's say you have the following template:
    
    ```twig
    {% for product in products %}
        <h2>{{ product.name }}</h2>
    {% else %}
        <p>No products found</p>
    {% endfor %}
    ```
    
    And `products` is of type `non-empty-array<Product>`, it means that the else will never happen.
    
    This is currently reported as:
    ```
    Negated boolean expression is always false.
    🔖 booleanNot.alwaysFalse
    🐘 compiled_index.php:83
    🌱 templates/product/index.html.twig:2
    🎯 src/Controller/ProductController.php:15
    ```
    
    But as you can see, it points to line number 2, instead of line number 3.
    
    In the compiled code, it looks like this:
    ```php
    // line /Volumes/CS/opensource/twigstan-demo/templates/product/index.html.twig:1
    foreach ($context['_seq'] as $context["_key"] => $context["product"]) {
        // line /Volumes/CS/opensource/twigstan-demo/templates/product/index.html.twig:2
        yield "        <h2>";
        // line /Volumes/CS/opensource/twigstan-demo/templates/product/index.html.twig:2
        yield \Twig\Extension\CoreExtension::getAttribute($this->env, $this->source, $context
        // line /Volumes/CS/opensource/twigstan-demo/templates/product/index.html.twig:2
        yield "</h2>\n    ";
        $context['_iterated'] = \true;
    }
    if (!$context['_iterated']) {
        // line /Volumes/CS/opensource/twigstan-demo/templates/product/index.html.twig:4
        yield "        <p>No products found</p>\n    ";
    }
    ```
    
    With this change, we will change the compiled code to become:
    ```php
    // line /Volumes/CS/opensource/twigstan-demo/templates/product/index.html.twig:1
    foreach ($context['_seq'] as $context["_key"] => $context["product"]) {
        // line /Volumes/CS/opensource/twigstan-demo/templates/product/index.html.twig:2
        yield "        <h2>";
        // line /Volumes/CS/opensource/twigstan-demo/templates/product/index.html.twig:2
        yield \Twig\Extension\CoreExtension::getAttribute($this->env, $this->source, $context
        // line /Volumes/CS/opensource/twigstan-demo/templates/product/index.html.twig:2
        yield "</h2>\n    ";
        $context['_iterated'] = \true;
    }
    // line /Volumes/CS/opensource/twigstan-demo/templates/product/index.html.twig:3
    if (!$context['_iterated']) {
        // line /Volumes/CS/opensource/twigstan-demo/templates/product/index.html.twig:4
        yield "        <p>No products found</p>\n    ";
    }
    ```
    ruudk committed Nov 24, 2024
    Configuration menu
    Copy the full SHA
    cebfbb1 View commit details
    Browse the repository at this point in the history