Skip to content

Conversation

@jasmith-hs
Copy link
Contributor

Handles the {% continue %} and {% break %} tags in eager execution.

There are 4 situations considered, each of them tested via a separate test:

  1. Continue tag is used in an already deferred for loop
  2. Continue tag is used in a for loop that is being flattened, but is in deferred execution mode
  3. Break tag is used in an already deferred for loop
  4. Break tag is used in a for loop that is being flattened, but is in deferred execution mode

The break tag is easiest to handle. We can simply use the EagerGenericTag wrapper. If a DeferredValueException is thrown when evaluating the BreakTag, then it will be reconstructed. This works for both flattened for-loops (because a {% for __ignored__ in [0] %} wrapper is already added to preserve the scope, meaning when the break tag is hit, it will break out of the single-level for-loop) and for deferred for loops.

The continue tag is a bit trickier because it wouldn't work in a flattened for loop as it would effectively become a {% break %}:

{% for __ignored__ in [0] %}
  {% if deferred %}
    {% continue %} {# if we were to continue here, we'd just end up skipping the code that's from the subsequent iterations of the loop #}
  {% endif %}
  i is: 0
  {% if deferred %}
    {% continue %}
  {% endif %}
  i is: 1
{% endfor %}

Instead, when encountering a {% continue %} tag that must be deferred, we'll reconstruct it and mark the for loop that it's currently in as deferred (as we don't know if it would continue or not after that). Omitting this step is basically an optimization for the {% break %} tag because it functions the same in a flattened or a deferred for-loop.

.put(IfTag.class, EagerIfTag.class)
.put(UnlessTag.class, EagerUnlessTag.class)
.put(CallTag.class, EagerCallTag.class)
.put(ContinueTag.class, EagerContinueTag.class)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

break doesn't need to map to anything? Not even EagerGenericTag?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It auto-maps to EagerGenericTag if it's not in TAG_CLASSES_TO_SKIP

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks!

.put(IfTag.class, EagerIfTag.class)
.put(UnlessTag.class, EagerUnlessTag.class)
.put(CallTag.class, EagerCallTag.class)
.put(ContinueTag.class, EagerContinueTag.class)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants