fix for and add reversed argument

This commit is contained in:
danhanson committed 2026-09-08 02:42:50 -05:00
1 parent 356cc3a885
commit 06aa8706c8
6 files changed
+61334 -60227

No files matched your search

+4
View File
@@ -242,6 +242,10 @@ documentation or memory. Both checks are worth repeating whenever tags, filters
`{% cache 500 sidebar.name %}` names a fragment there, `{% cache 500 using="c" %}` names a fragment `{% cache 500 sidebar.name %}` names a fragment there, `{% cache 500 using="c" %}` names a fragment
called `using="c"` rather than choosing a cache, and `{% cache 500 sidebar using= %}` takes an empty called `using="c"` rather than choosing a cache, and `{% cache 500 sidebar using= %}` takes an empty
name. All three are errors here. name. All three are errors here.
- `do_for` reads `reversed` off the end of the tag before it looks for `in`, so `{% for x in reversed %}`
is an error there and a loop over a variable named `reversed` here. Writing the flag as well
(`{% for x in reversed reversed %}`) is accepted by both, which is why the name is not simply reserved
in that position.
- `do_translate` refuses `as` and `noop` as the value of its `context` option, so - `do_translate` refuses `as` and `noop` as the value of its `context` option, so
`{% trans "hi" context noop %}` is an error there and a context named by the variable `noop` here. `{% trans "hi" context noop %}` is an error there and a context named by the variable `noop` here.
- `partial`/`partialdef` are Django builtins as of Django 6; `elif`/`else`/`empty` are modelled as parts of - `partial`/`partialdef` are Django builtins as of Django 6; `elif`/`else`/`empty` are modelled as parts of
+17 -15
View File
@@ -291,6 +291,7 @@ const django = grammar({
// after it settles // after it settles
conflicts: ($) => [ conflicts: ($) => [
[$.template], [$.template],
[$.for_scope],
[$.predicate], [$.predicate],
[$.library, $.load], [$.library, $.load],
[$._translate_option], [$._translate_option],
@@ -621,24 +622,25 @@ const django = grammar({
optional(asVariable($)), optional(asVariable($)),
), ),
for_scope: ($) => for_scope: ($) =>
prec.left( seq(
seq( block(
block( "for",
"for", part(field("variable", $.identifier)),
part(field("variable", $.identifier)), repeat(
repeat( seq(
seq( optional(SEP),
optional(SEP), ",",
",", optional(SEP),
optional(SEP), field("variable", $.identifier),
field("variable", $.identifier),
),
), ),
part("in"),
part($.filtered_value),
), ),
optional($.template), part("in"),
part($.filtered_value),
// do_for reads this off the end and takes the sequence from the bit
// before it, so it comes last or not at all
optional(part("reversed")),
), ),
optional($.template),
), ),
for_group: ($) => for_group: ($) =>
seq( seq(
+148 -128
View File
@@ -3262,44 +3262,84 @@
] ]
}, },
"for_scope": { "for_scope": {
"type": "PREC_LEFT", "type": "SEQ",
"value": 0, "members": [
"content": { {
"type": "SEQ", "type": "SEQ",
"members": [ "members": [
{ {
"type": "SEQ", "type": "STRING",
"members": [ "value": "{%"
{ },
"type": "STRING", {
"value": "{%" "type": "CHOICE",
}, "members": [
{ {
"type": "CHOICE", "type": "PATTERN",
"members": [ "value": "[ \\t\\r\\n]+"
{ },
"type": "PATTERN", {
"value": "[ \\t\\r\\n]+" "type": "BLANK"
},
{
"type": "BLANK"
}
]
},
{
"type": "FIELD",
"name": "tag",
"content": {
"type": "STRING",
"value": "for"
} }
}, ]
{ },
{
"type": "FIELD",
"name": "tag",
"content": {
"type": "STRING",
"value": "for"
}
},
{
"type": "SEQ",
"members": [
{
"type": "PATTERN",
"value": "[ \\t\\r\\n]+"
},
{
"type": "FIELD",
"name": "variable",
"content": {
"type": "SYMBOL",
"name": "identifier"
}
}
]
},
{
"type": "REPEAT",
"content": {
"type": "SEQ", "type": "SEQ",
"members": [ "members": [
{ {
"type": "PATTERN", "type": "CHOICE",
"value": "[ \\t\\r\\n]+" "members": [
{
"type": "PATTERN",
"value": "[ \\t\\r\\n]+"
},
{
"type": "BLANK"
}
]
},
{
"type": "STRING",
"value": ","
},
{
"type": "CHOICE",
"members": [
{
"type": "PATTERN",
"value": "[ \\t\\r\\n]+"
},
{
"type": "BLANK"
}
]
}, },
{ {
"type": "FIELD", "type": "FIELD",
@@ -3310,109 +3350,86 @@
} }
} }
] ]
}, }
{ },
"type": "REPEAT", {
"content": { "type": "SEQ",
"members": [
{
"type": "PATTERN",
"value": "[ \\t\\r\\n]+"
},
{
"type": "STRING",
"value": "in"
}
]
},
{
"type": "SEQ",
"members": [
{
"type": "PATTERN",
"value": "[ \\t\\r\\n]+"
},
{
"type": "SYMBOL",
"name": "filtered_value"
}
]
},
{
"type": "CHOICE",
"members": [
{
"type": "SEQ", "type": "SEQ",
"members": [ "members": [
{ {
"type": "CHOICE", "type": "PATTERN",
"members": [ "value": "[ \\t\\r\\n]+"
{
"type": "PATTERN",
"value": "[ \\t\\r\\n]+"
},
{
"type": "BLANK"
}
]
}, },
{ {
"type": "STRING", "type": "STRING",
"value": "," "value": "reversed"
},
{
"type": "CHOICE",
"members": [
{
"type": "PATTERN",
"value": "[ \\t\\r\\n]+"
},
{
"type": "BLANK"
}
]
},
{
"type": "FIELD",
"name": "variable",
"content": {
"type": "SYMBOL",
"name": "identifier"
}
} }
] ]
},
{
"type": "BLANK"
} }
}, ]
{ },
"type": "SEQ", {
"members": [ "type": "CHOICE",
{ "members": [
"type": "PATTERN", {
"value": "[ \\t\\r\\n]+" "type": "PATTERN",
}, "value": "[ \\t\\r\\n]+"
{ },
"type": "STRING", {
"value": "in" "type": "BLANK"
} }
] ]
}, },
{ {
"type": "SEQ", "type": "STRING",
"members": [ "value": "%}"
{ }
"type": "PATTERN", ]
"value": "[ \\t\\r\\n]+" },
}, {
{ "type": "CHOICE",
"type": "SYMBOL", "members": [
"name": "filtered_value" {
} "type": "SYMBOL",
] "name": "template"
}, },
{ {
"type": "CHOICE", "type": "BLANK"
"members": [ }
{ ]
"type": "PATTERN", }
"value": "[ \\t\\r\\n]+" ]
},
{
"type": "BLANK"
}
]
},
{
"type": "STRING",
"value": "%}"
}
]
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "template"
},
{
"type": "BLANK"
}
]
}
]
}
}, },
"for_group": { "for_group": {
"type": "SEQ", "type": "SEQ",
@@ -7947,6 +7964,9 @@
[ [
"template" "template"
], ],
[
"for_scope"
],
[ [
"predicate" "predicate"
], ],
+4
View File
@@ -2816,6 +2816,10 @@
"type": "resetcycle", "type": "resetcycle",
"named": false "named": false
}, },
{
"type": "reversed",
"named": false
},
{ {
"type": "rjust", "type": "rjust",
"named": false "named": false
+60811 -60084
View File
File diff suppressed because it is too large. Load diff
+350
View File
@@ -95,3 +95,353 @@ For With Empty
(template (template
(content))) (content)))
(content)) (content))
==================
For With A Tag In Its Body
==================
{% for x in y %}
{% if a %}b{% endif %}
{% endfor %}
---
(template
(content)
(for_group
(for_scope
variable: (identifier)
(filtered_value
(value
(variable_attribute
(identifier))))
(template
(content)
(if_group
(predicate
(filtered_value
(value
(variable_attribute
(identifier)))))
(template
(content)))
(content))))
(content))
==================
For With A Nested For
==================
{% for x in y %}
{% for z in x %}a{% endfor %}
{% endfor %}
---
(template
(content)
(for_group
(for_scope
variable: (identifier)
(filtered_value
(value
(variable_attribute
(identifier))))
(template
(content)
(for_group
(for_scope
variable: (identifier)
(filtered_value
(value
(variable_attribute
(identifier))))
(template
(content))))
(content))))
(content))
==================
For With Tags In Both Branches
==================
{% for x in y %}
{% if a %}b{% endif %}
{% empty %}
{% with c=1 %}d{% endwith %}
{% endfor %}
---
(template
(content)
(for_group
(for_scope
variable: (identifier)
(filtered_value
(value
(variable_attribute
(identifier))))
(template
(content)
(if_group
(predicate
(filtered_value
(value
(variable_attribute
(identifier)))))
(template
(content)))
(content)))
(template
(content)
(with_group
variable: (identifier)
(filtered_value
(value
(literal
(number))))
(template
(content)))
(content)))
(content))
==================
For With A Named Block In Its Body
==================
{% for x in y %}
{% block b %}c{% endblock b %}
{% endfor %}
---
(template
(content)
(for_group
(for_scope
variable: (identifier)
(filtered_value
(value
(variable_attribute
(identifier))))
(template
(content)
(block_group
name: (push_block)
(template
(content))
(pop_block))
(content))))
(content))
==================
For Nested In A Tag
==================
{% if a %}
{% for x in y %}{% if b %}c{% endif %}{% endfor %}
{% endif %}
---
(template
(content)
(if_group
(predicate
(filtered_value
(value
(variable_attribute
(identifier)))))
(template
(content)
(for_group
(for_scope
variable: (identifier)
(filtered_value
(value
(variable_attribute
(identifier))))
(template
(if_group
(predicate
(filtered_value
(value
(variable_attribute
(identifier)))))
(template
(content))))))
(content)))
(content))
==================
For With An Empty Body
==================
{% for x in y %}{% endfor %}
---
(template
(content)
(for_group
(for_scope
variable: (identifier)
(filtered_value
(value
(variable_attribute
(identifier))))))
(content))
==================
For Reversed
==================
{% for x in y reversed %}
a
{% endfor %}
---
(template
(content)
(for_group
(for_scope
variable: (identifier)
(filtered_value
(value
(variable_attribute
(identifier))))
(template
(content))))
(content))
==================
For With Multiple Variables Reversed
==================
{% for k,v in y reversed %}
a
{% endfor %}
---
(template
(content)
(for_group
(for_scope
variable: (identifier)
variable: (identifier)
(filtered_value
(value
(variable_attribute
(identifier))))
(template
(content))))
(content))
==================
For With A Filtered Sequence Reversed
==================
{% for x in y|slice:":2" reversed %}
a
{% endfor %}
---
(template
(content)
(for_group
(for_scope
variable: (identifier)
(filtered_value
(value
(variable_attribute
(identifier)))
(filter_expression
(filter
argument: (value
(literal
(string))))))
(template
(content))))
(content))
==================
For Reversed With Empty
==================
{% for x in y reversed %}
a
{% empty %}
b
{% endfor %}
---
(template
(content)
(for_group
(for_scope
variable: (identifier)
(filtered_value
(value
(variable_attribute
(identifier))))
(template
(content)))
(template
(content)))
(content))
==================
For Reversed With A Tag In Its Body
==================
{% for x in y reversed %}
{% if a %}b{% endif %}
{% endfor %}
---
(template
(content)
(for_group
(for_scope
variable: (identifier)
(filtered_value
(value
(variable_attribute
(identifier))))
(template
(content)
(if_group
(predicate
(filtered_value
(value
(variable_attribute
(identifier)))))
(template
(content)))
(content))))
(content))
==================
For With Reversed Twice
:error
==================
{% for x in y reversed reversed %}a{% endfor %}
---
==================
For With Reversed Before In
:error
==================
{% for x reversed in y %}a{% endfor %}
---