From b3f80eaeb38ae94b9e70d56a50cff1fddbce3efe Mon Sep 17 00:00:00 2001
From: Josh
Date: Sun, 5 Jan 2025 01:38:30 -0600
Subject: [PATCH] wip
---
crates/djls-template-ast/src/ast.rs | 31 +-
crates/djls-template-ast/src/lexer.rs | 5 +-
crates/djls-template-ast/src/parser.rs | 72 +++--
...rser__tests__comments__parse_comments.snap | 1 +
...__tests__comments__parse_comments.snap.new | 20 ++
..._tests__django__parse_complex_if_elif.snap | 1 +
...ts__django__parse_complex_if_elif.snap.new | 76 +++++
...tests__django__parse_django_for_block.snap | 3 +-
...s__django__parse_django_for_block.snap.new | 59 ++++
..._tests__django__parse_django_if_block.snap | 1 +
...ts__django__parse_django_if_block.snap.new | 39 +++
..._tests__django__parse_django_variable.snap | 5 +-
...ts__django__parse_django_variable.snap.new | 23 ++
...r__tests__django__parse_filter_chains.snap | 9 +-
...ests__django__parse_filter_chains.snap.new | 33 +++
...r__tests__django__parse_mixed_content.snap | 33 +--
...ests__django__parse_mixed_content.snap.new | 269 ++++++++++++++++++
...r__tests__django__parse_nested_for_if.snap | 3 +-
...ests__django__parse_nested_for_if.snap.new | 68 +++++
...__tests__errors__parse_error_recovery.snap | 21 +-
...sts__errors__parse_error_recovery.snap.new | 126 ++++++++
...ts__errors__parse_unclosed_django_for.snap | 3 +-
...errors__parse_unclosed_django_for.snap.new | 34 +++
...sts__errors__parse_unclosed_django_if.snap | 1 +
..._errors__parse_unclosed_django_if.snap.new | 29 ++
...ests__errors__parse_unclosed_html_tag.snap | 1 +
...__errors__parse_unclosed_html_tag.snap.new | 15 +
..._tests__errors__parse_unclosed_script.snap | 1 +
...ts__errors__parse_unclosed_script.snap.new | 15 +
...__tests__errors__parse_unclosed_style.snap | 1 +
...sts__errors__parse_unclosed_style.snap.new | 15 +
...er__tests__full_templates__parse_full.snap | 29 +-
...tests__full_templates__parse_full.snap.new | 162 +++++++++++
...rser__tests__html__parse_html_doctype.snap | 1 +
...__tests__html__parse_html_doctype.snap.new | 15 +
...__parser__tests__html__parse_html_tag.snap | 1 +
...rser__tests__html__parse_html_tag.snap.new | 15 +
..._parser__tests__html__parse_html_void.snap | 1 +
...ser__tests__html__parse_html_void.snap.new | 15 +
...__parser__tests__script__parse_script.snap | 1 +
...rser__tests__script__parse_script.snap.new | 21 ++
...st__parser__tests__style__parse_style.snap | 1 +
...parser__tests__style__parse_style.snap.new | 20 ++
43 files changed, 1220 insertions(+), 75 deletions(-)
create mode 100644 crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__comments__parse_comments.snap.new
create mode 100644 crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_complex_if_elif.snap.new
create mode 100644 crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_django_for_block.snap.new
create mode 100644 crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_django_if_block.snap.new
create mode 100644 crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_django_variable.snap.new
create mode 100644 crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_filter_chains.snap.new
create mode 100644 crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_mixed_content.snap.new
create mode 100644 crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_nested_for_if.snap.new
create mode 100644 crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__errors__parse_error_recovery.snap.new
create mode 100644 crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__errors__parse_unclosed_django_for.snap.new
create mode 100644 crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__errors__parse_unclosed_django_if.snap.new
create mode 100644 crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__errors__parse_unclosed_html_tag.snap.new
create mode 100644 crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__errors__parse_unclosed_script.snap.new
create mode 100644 crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__errors__parse_unclosed_style.snap.new
create mode 100644 crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__full_templates__parse_full.snap.new
create mode 100644 crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__html__parse_html_doctype.snap.new
create mode 100644 crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__html__parse_html_tag.snap.new
create mode 100644 crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__html__parse_html_void.snap.new
create mode 100644 crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__script__parse_script.snap.new
create mode 100644 crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__style__parse_style.snap.new
diff --git a/crates/djls-template-ast/src/ast.rs b/crates/djls-template-ast/src/ast.rs
index 1c5c789..c524a38 100644
--- a/crates/djls-template-ast/src/ast.rs
+++ b/crates/djls-template-ast/src/ast.rs
@@ -42,7 +42,7 @@ impl Ast {
}
#[derive(Clone, Default, Debug, Serialize)]
-pub struct LineOffsets(Vec);
+pub struct LineOffsets(pub Vec);
impl LineOffsets {
pub fn new() -> Self {
@@ -55,11 +55,33 @@ impl LineOffsets {
}
pub fn position_to_line_col(&self, offset: u32) -> (u32, u32) {
+ eprintln!("LineOffsets: Converting position {} to line/col. Offsets: {:?}", offset, self.0);
+
+ // Find which line contains this offset by looking for the first line start
+ // that's greater than our position
let line = match self.0.binary_search(&offset) {
- Ok(line) => line,
- Err(line) => if line > 0 { line - 1 } else { line },
+ Ok(exact_line) => exact_line, // We're exactly at a line start, so we're on that line
+ Err(next_line) => {
+ if next_line == 0 {
+ 0 // Before first line start, so we're on line 0
+ } else {
+ let prev_line = next_line - 1;
+ // If we're at the start of the next line, we're on that line
+ if offset == self.0[next_line] - 1 {
+ prev_line
+ } else {
+ // Otherwise we're on the previous line
+ prev_line
+ }
+ }
+ }
};
+
+ // Calculate column as offset from line start
let col = offset - self.0[line];
+
+ eprintln!("LineOffsets: Found line {} starting at offset {}", line, self.0[line]);
+ eprintln!("LineOffsets: Calculated col {} as {} - {}", col, offset, self.0[line]);
(line as u32, col)
}
@@ -185,6 +207,7 @@ mod tests {
fn test_variable_spans() {
let template = "Hello\n{{ user.name }}\nWorld";
let tokens = Lexer::new(template).tokenize().unwrap();
+ println!("Tokens: {:#?}", tokens); // Add debug print
let mut parser = Parser::new(tokens);
let ast = parser.parse().unwrap();
@@ -236,6 +259,8 @@ mod tests {
// Check content span
if let Some(content) = children {
if let Node::Text { span, .. } = &content[0] {
+ eprintln!("content {:?}", content);
+ eprintln!("span start {:?}", span.start());
let (content_line, content_col) =
ast.line_offsets.position_to_line_col(*span.start());
assert_eq!(
diff --git a/crates/djls-template-ast/src/lexer.rs b/crates/djls-template-ast/src/lexer.rs
index b88a830..d1975e8 100644
--- a/crates/djls-template-ast/src/lexer.rs
+++ b/crates/djls-template-ast/src/lexer.rs
@@ -60,8 +60,11 @@ impl Lexer {
},
'\n' => {
self.consume()?;
+ let token = TokenType::Newline;
+ eprintln!("Lexer: Found newline at position {}, incrementing line from {} to {}",
+ self.start, self.line, self.line + 1);
self.line += 1;
- TokenType::Newline
+ token
}
' ' | '\t' | '\r' => {
let mut count = 1;
diff --git a/crates/djls-template-ast/src/parser.rs b/crates/djls-template-ast/src/parser.rs
index 4cf1c9a..db5d4f5 100644
--- a/crates/djls-template-ast/src/parser.rs
+++ b/crates/djls-template-ast/src/parser.rs
@@ -15,21 +15,25 @@ impl Parser {
pub fn parse(&mut self) -> Result {
let mut ast = Ast::default();
- let mut line_offsets = LineOffsets::new();
+ let mut line_offsets = LineOffsets::new(); // Already contains [0]
// First pass: collect line offsets
- let mut current_offset = 0;
for token in self.tokens.tokens() {
match token.token_type() {
TokenType::Newline => {
- current_offset += 1; // Add 1 for the newline character
- line_offsets.add_line(current_offset as u32);
- }
- _ => {
- if let Some(len) = token.token_type().len() {
- current_offset += len;
+ if let Some(start) = token.start() {
+ eprintln!("Parser: Found newline at position {}", start);
+ // Add line offset at the start of the next line
+ line_offsets.add_line(*start as u32 + 1);
+ eprintln!("Parser: Added line offset {} at position {}", line_offsets.0.len(), start + 1);
}
}
+ TokenType::Whitespace(count) => {
+ if let Some(start) = token.start() {
+ eprintln!("Parser: Found whitespace of length {} at position {}", count, start);
+ }
+ }
+ _ => {}
}
}
@@ -189,20 +193,21 @@ impl Parser {
}
let closing_token = self.peek_previous()?;
let closing_content = match closing_token.token_type() {
- TokenType::DjangoBlock(content) => content.len(),
+ TokenType::DjangoBlock(content) => content.len() + 5, // Add 5 for {% and %}
_ => 0,
};
- total_length = (closing_token.start().unwrap_or(0) + closing_content)
- - start_pos as usize;
+ let closing_start = closing_token.start().unwrap_or(0);
+ total_length = (closing_start + closing_content) - start_pos as usize;
+ let closing_span = Span::new(
+ closing_start as u32,
+ closing_content as u16,
+ );
children.push(Node::Block {
block_type: BlockType::Closing,
name: tag,
bits: vec![],
children: None,
- span: Span::new(
- closing_token.start().unwrap_or(0) as u32,
- closing_content as u16,
- ),
+ span: closing_span,
tag_span,
});
found_closing_tag = true;
@@ -210,7 +215,7 @@ impl Parser {
}
// Check if intermediate tag
if let Some(branches) = &spec.branches {
- if let Some(branch) = branches.iter().find(|i| i.name == tag) {
+ if let Some(branch) = branches.iter().find(|b| b.name == tag) {
// If we have a current branch, add it to children
if let Some((name, bits, branch_children)) = current_branch {
let branch_span = Span::new(start_pos, total_length as u16);
@@ -281,10 +286,11 @@ impl Parser {
}
fn parse_django_variable(&mut self, s: &str) -> Result {
- let start_token = self.peek_previous()?;
- let start_pos = start_token.start().unwrap_or(0) as u32;
+ let token = self.peek_previous()?;
+ let start_pos = token.start().unwrap_or(0) as u32;
+ let s = s.trim(); // Trim whitespace
let length = s.len() as u16;
- let span = Span::new(start_pos, length);
+ let span = Span::new(start_pos + 3, length); // Add 3 to skip "{{ "
let parts: Vec<&str> = s.split('|').collect();
let bits: Vec = parts[0].trim().split('.').map(String::from).collect();
@@ -324,10 +330,30 @@ impl Parser {
}
fn parse_text(&mut self) -> Result {
- let start_token = self.peek()?;
- let start_pos = start_token.start().unwrap_or(0) as u32;
+ let mut start_pos = self.peek()?.start().unwrap_or(0) as u32;
let mut text = String::new();
+ // Skip any leading newlines and whitespace
+ while let Ok(token) = self.peek() {
+ match token.token_type() {
+ TokenType::Newline => {
+ self.consume()?;
+ text.push('\n');
+ if let Ok(next) = self.peek() {
+ start_pos = next.start().unwrap_or(0) as u32;
+ }
+ }
+ TokenType::Whitespace(len) => {
+ self.consume()?;
+ text.push_str(&" ".repeat(*len));
+ if let Ok(next) = self.peek() {
+ start_pos = next.start().unwrap_or(0) as u32;
+ }
+ }
+ _ => break,
+ }
+ }
+
while let Ok(token) = self.peek() {
match token.token_type() {
TokenType::DjangoBlock(_)
@@ -530,7 +556,8 @@ mod tests {
}
#[test]
fn test_parse_complex_if_elif() {
- let source = "{% if x > 0 %}Positive{% elif x < 0 %}Negative{% else %}Zero{% endif %}";
+ let source =
+ "{% if x > 0 %}Positive{% elif x < 0 %}Negative{% else %}Zero{% endif %}";
let tokens = Lexer::new(source).tokenize().unwrap();
let mut parser = Parser::new(tokens);
let ast = parser.parse().unwrap();
@@ -734,6 +761,7 @@ mod tests {
let ast = parser.parse().unwrap();
let offsets = ast.line_offsets();
+ eprintln!("{:?}", offsets);
assert_eq!(offsets.position_to_line_col(0), (0, 0)); // Start of line 1
assert_eq!(offsets.position_to_line_col(6), (1, 0)); // Start of line 2
}
diff --git a/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__comments__parse_comments.snap b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__comments__parse_comments.snap
index f0bd382..ba19092 100644
--- a/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__comments__parse_comments.snap
+++ b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__comments__parse_comments.snap
@@ -15,4 +15,5 @@ nodes:
length: 18
line_offsets:
- 0
+ - 0
errors: []
diff --git a/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__comments__parse_comments.snap.new b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__comments__parse_comments.snap.new
new file mode 100644
index 0000000..20b4d11
--- /dev/null
+++ b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__comments__parse_comments.snap.new
@@ -0,0 +1,20 @@
+---
+source: crates/djls-template-ast/src/parser.rs
+assertion_line: 608
+expression: ast
+snapshot_kind: text
+---
+nodes:
+ - Text:
+ content: ""
+ span:
+ start: 0
+ length: 21
+ - Comment:
+ content: Django comment
+ span:
+ start: 21
+ length: 18
+line_offsets:
+ - 0
+errors: []
diff --git a/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_complex_if_elif.snap b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_complex_if_elif.snap
index dc1ea7b..39f2f54 100644
--- a/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_complex_if_elif.snap
+++ b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_complex_if_elif.snap
@@ -71,4 +71,5 @@ nodes:
length: 8
line_offsets:
- 0
+ - 0
errors: []
diff --git a/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_complex_if_elif.snap.new b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_complex_if_elif.snap.new
new file mode 100644
index 0000000..b13760e
--- /dev/null
+++ b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_complex_if_elif.snap.new
@@ -0,0 +1,76 @@
+---
+source: crates/djls-template-ast/src/parser.rs
+assertion_line: 535
+expression: ast
+snapshot_kind: text
+---
+nodes:
+ - Block:
+ block_type: Standard
+ name: if
+ bits:
+ - if
+ - x
+ - ">"
+ - "0"
+ children:
+ - Text:
+ content: Positive
+ span:
+ start: 14
+ length: 8
+ - Block:
+ block_type: Branch
+ name: elif
+ bits:
+ - x
+ - "<"
+ - "0"
+ children:
+ - Text:
+ content: Negative
+ span:
+ start: 38
+ length: 8
+ span:
+ start: 0
+ length: 8
+ tag_span:
+ start: 0
+ length: 8
+ - Block:
+ block_type: Branch
+ name: else
+ bits: []
+ children:
+ - Text:
+ content: Zero
+ span:
+ start: 56
+ length: 4
+ span:
+ start: 0
+ length: 8
+ tag_span:
+ start: 0
+ length: 8
+ - Block:
+ block_type: Closing
+ name: endif
+ bits: []
+ children: ~
+ span:
+ start: 60
+ length: 5
+ tag_span:
+ start: 0
+ length: 8
+ span:
+ start: 0
+ length: 65
+ tag_span:
+ start: 0
+ length: 8
+line_offsets:
+ - 0
+errors: []
diff --git a/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_django_for_block.snap b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_django_for_block.snap
index c0b743a..13feb69 100644
--- a/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_django_for_block.snap
+++ b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_django_for_block.snap
@@ -17,7 +17,7 @@ nodes:
- item
filters: []
span:
- start: 23
+ start: 25
length: 4
- Block:
block_type: Branch
@@ -54,4 +54,5 @@ nodes:
length: 17
line_offsets:
- 0
+ - 0
errors: []
diff --git a/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_django_for_block.snap.new b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_django_for_block.snap.new
new file mode 100644
index 0000000..9c37553
--- /dev/null
+++ b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_django_for_block.snap.new
@@ -0,0 +1,59 @@
+---
+source: crates/djls-template-ast/src/parser.rs
+assertion_line: 527
+expression: ast
+snapshot_kind: text
+---
+nodes:
+ - Block:
+ block_type: Standard
+ name: for
+ bits:
+ - for
+ - item
+ - in
+ - items
+ children:
+ - Variable:
+ bits:
+ - item
+ filters: []
+ span:
+ start: 26
+ length: 4
+ - Block:
+ block_type: Branch
+ name: empty
+ bits: []
+ children:
+ - Text:
+ content: No items
+ span:
+ start: 44
+ length: 8
+ span:
+ start: 0
+ length: 17
+ tag_span:
+ start: 0
+ length: 17
+ - Block:
+ block_type: Closing
+ name: endfor
+ bits: []
+ children: ~
+ span:
+ start: 52
+ length: 6
+ tag_span:
+ start: 0
+ length: 17
+ span:
+ start: 0
+ length: 58
+ tag_span:
+ start: 0
+ length: 17
+line_offsets:
+ - 0
+errors: []
diff --git a/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_django_if_block.snap b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_django_if_block.snap
index a3fd5f7..a890b84 100644
--- a/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_django_if_block.snap
+++ b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_django_if_block.snap
@@ -34,4 +34,5 @@ nodes:
length: 24
line_offsets:
- 0
+ - 0
errors: []
diff --git a/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_django_if_block.snap.new b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_django_if_block.snap.new
new file mode 100644
index 0000000..2f1ae42
--- /dev/null
+++ b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_django_if_block.snap.new
@@ -0,0 +1,39 @@
+---
+source: crates/djls-template-ast/src/parser.rs
+assertion_line: 519
+expression: ast
+snapshot_kind: text
+---
+nodes:
+ - Block:
+ block_type: Standard
+ name: if
+ bits:
+ - if
+ - user.is_authenticated
+ children:
+ - Text:
+ content: Welcome
+ span:
+ start: 30
+ length: 7
+ - Block:
+ block_type: Closing
+ name: endif
+ bits: []
+ children: ~
+ span:
+ start: 37
+ length: 5
+ tag_span:
+ start: 0
+ length: 24
+ span:
+ start: 0
+ length: 42
+ tag_span:
+ start: 0
+ length: 24
+line_offsets:
+ - 0
+errors: []
diff --git a/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_django_variable.snap b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_django_variable.snap
index 0a4dfbb..11a6477 100644
--- a/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_django_variable.snap
+++ b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_django_variable.snap
@@ -11,11 +11,12 @@ nodes:
- name: title
arguments: []
span:
- start: 10
+ start: 12
length: 5
span:
- start: 0
+ start: 2
length: 15
line_offsets:
- 0
+ - 0
errors: []
diff --git a/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_django_variable.snap.new b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_django_variable.snap.new
new file mode 100644
index 0000000..471a049
--- /dev/null
+++ b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_django_variable.snap.new
@@ -0,0 +1,23 @@
+---
+source: crates/djls-template-ast/src/parser.rs
+assertion_line: 503
+expression: ast
+snapshot_kind: text
+---
+nodes:
+ - Variable:
+ bits:
+ - user
+ - name
+ filters:
+ - name: title
+ arguments: []
+ span:
+ start: 10
+ length: 5
+ span:
+ start: 3
+ length: 15
+line_offsets:
+ - 0
+errors: []
diff --git a/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_filter_chains.snap b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_filter_chains.snap
index 23c7895..b19bc54 100644
--- a/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_filter_chains.snap
+++ b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_filter_chains.snap
@@ -11,21 +11,22 @@ nodes:
arguments:
- "'nothing'"
span:
- start: 6
+ start: 8
length: 17
- name: title
arguments: []
span:
- start: 24
+ start: 26
length: 5
- name: upper
arguments: []
span:
- start: 30
+ start: 32
length: 5
span:
- start: 0
+ start: 2
length: 35
line_offsets:
- 0
+ - 0
errors: []
diff --git a/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_filter_chains.snap.new b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_filter_chains.snap.new
new file mode 100644
index 0000000..c42904a
--- /dev/null
+++ b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_filter_chains.snap.new
@@ -0,0 +1,33 @@
+---
+source: crates/djls-template-ast/src/parser.rs
+assertion_line: 511
+expression: ast
+snapshot_kind: text
+---
+nodes:
+ - Variable:
+ bits:
+ - value
+ filters:
+ - name: default
+ arguments:
+ - "'nothing'"
+ span:
+ start: 6
+ length: 17
+ - name: title
+ arguments: []
+ span:
+ start: 24
+ length: 5
+ - name: upper
+ arguments: []
+ span:
+ start: 30
+ length: 5
+ span:
+ start: 3
+ length: 35
+line_offsets:
+ - 0
+errors: []
diff --git a/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_mixed_content.snap b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_mixed_content.snap
index cdde84b..fe5e876 100644
--- a/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_mixed_content.snap
+++ b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_mixed_content.snap
@@ -28,16 +28,16 @@ nodes:
- name: title
arguments: []
span:
- start: 54
+ start: 56
length: 5
- name: default
arguments:
- "'Guest'"
span:
- start: 60
+ start: 62
length: 15
span:
- start: 44
+ start: 46
length: 31
- Text:
content: "\n "
@@ -98,7 +98,7 @@ nodes:
- name
filters: []
span:
- start: 168
+ start: 170
length: 10
- Text:
content: "\n "
@@ -252,16 +252,17 @@ nodes:
length: 1
line_offsets:
- 0
- - 34
- - 70
- - 99
- - 130
- - 149
- - 184
- - 214
- - 224
- - 244
- - 255
- - 260
- - 270
+ - 0
+ - 40
+ - 82
+ - 117
+ - 160
+ - 185
+ - 232
+ - 274
+ - 290
+ - 310
+ - 327
+ - 338
+ - 348
errors: []
diff --git a/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_mixed_content.snap.new b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_mixed_content.snap.new
new file mode 100644
index 0000000..703a0f7
--- /dev/null
+++ b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_mixed_content.snap.new
@@ -0,0 +1,269 @@
+---
+source: crates/djls-template-ast/src/parser.rs
+assertion_line: 564
+expression: ast
+snapshot_kind: text
+---
+nodes:
+ - Text:
+ content: "Welcome, "
+ span:
+ start: 0
+ length: 9
+ - Block:
+ block_type: Standard
+ name: if
+ bits:
+ - if
+ - user.is_authenticated
+ children:
+ - Text:
+ content: "\n "
+ span:
+ start: 39
+ length: 5
+ - Variable:
+ bits:
+ - user
+ - name
+ filters:
+ - name: title
+ arguments: []
+ span:
+ start: 54
+ length: 5
+ - name: default
+ arguments:
+ - "'Guest'"
+ span:
+ start: 60
+ length: 15
+ span:
+ start: 47
+ length: 31
+ - Text:
+ content: "\n "
+ span:
+ start: 81
+ length: 5
+ - Block:
+ block_type: Standard
+ name: for
+ bits:
+ - for
+ - group
+ - in
+ - user.groups
+ children:
+ - Text:
+ content: "\n "
+ span:
+ start: 116
+ length: 9
+ - Block:
+ block_type: Standard
+ name: if
+ bits:
+ - if
+ - forloop.first
+ children:
+ - Text:
+ content: (
+ span:
+ start: 147
+ length: 1
+ - Block:
+ block_type: Closing
+ name: endif
+ bits: []
+ children: ~
+ span:
+ start: 148
+ length: 5
+ tag_span:
+ start: 125
+ length: 16
+ span:
+ start: 125
+ length: 28
+ tag_span:
+ start: 125
+ length: 16
+ - Text:
+ content: "\n "
+ span:
+ start: 159
+ length: 9
+ - Variable:
+ bits:
+ - group
+ - name
+ filters: []
+ span:
+ start: 171
+ length: 10
+ - Text:
+ content: "\n "
+ span:
+ start: 184
+ length: 9
+ - Block:
+ block_type: Standard
+ name: if
+ bits:
+ - if
+ - not
+ - forloop.last
+ children:
+ - Text:
+ content: ", "
+ span:
+ start: 218
+ length: 2
+ - Block:
+ block_type: Closing
+ name: endif
+ bits: []
+ children: ~
+ span:
+ start: 220
+ length: 5
+ tag_span:
+ start: 193
+ length: 19
+ span:
+ start: 193
+ length: 32
+ tag_span:
+ start: 193
+ length: 19
+ - Text:
+ content: "\n "
+ span:
+ start: 231
+ length: 9
+ - Block:
+ block_type: Standard
+ name: if
+ bits:
+ - if
+ - forloop.last
+ children:
+ - Text:
+ content: )
+ span:
+ start: 261
+ length: 1
+ - Block:
+ block_type: Closing
+ name: endif
+ bits: []
+ children: ~
+ span:
+ start: 262
+ length: 5
+ tag_span:
+ start: 240
+ length: 15
+ span:
+ start: 240
+ length: 27
+ tag_span:
+ start: 240
+ length: 15
+ - Text:
+ content: "\n "
+ span:
+ start: 273
+ length: 5
+ - Block:
+ block_type: Branch
+ name: empty
+ bits: []
+ children:
+ - Text:
+ content: "\n (no groups)\n "
+ span:
+ start: 289
+ length: 25
+ span:
+ start: 86
+ length: 24
+ tag_span:
+ start: 86
+ length: 24
+ - Block:
+ block_type: Closing
+ name: endfor
+ bits: []
+ children: ~
+ span:
+ start: 314
+ length: 6
+ tag_span:
+ start: 86
+ length: 24
+ span:
+ start: 86
+ length: 234
+ tag_span:
+ start: 86
+ length: 24
+ - Text:
+ content: "\n"
+ span:
+ start: 326
+ length: 1
+ - Block:
+ block_type: Branch
+ name: else
+ bits: []
+ children:
+ - Text:
+ content: "\n Guest\n"
+ span:
+ start: 337
+ length: 11
+ span:
+ start: 9
+ length: 24
+ tag_span:
+ start: 9
+ length: 24
+ - Block:
+ block_type: Closing
+ name: endif
+ bits: []
+ children: ~
+ span:
+ start: 348
+ length: 5
+ tag_span:
+ start: 9
+ length: 24
+ span:
+ start: 9
+ length: 344
+ tag_span:
+ start: 9
+ length: 24
+ - Text:
+ content: "!"
+ span:
+ start: 359
+ length: 1
+line_offsets:
+ - 0
+ - 40
+ - 82
+ - 117
+ - 160
+ - 185
+ - 232
+ - 274
+ - 290
+ - 310
+ - 327
+ - 338
+ - 348
+errors: []
diff --git a/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_nested_for_if.snap b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_nested_for_if.snap
index 081a6ab..8aa150d 100644
--- a/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_nested_for_if.snap
+++ b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_nested_for_if.snap
@@ -25,7 +25,7 @@ nodes:
- name
filters: []
span:
- start: 43
+ start: 45
length: 9
- Block:
block_type: Closing
@@ -63,4 +63,5 @@ nodes:
length: 17
line_offsets:
- 0
+ - 0
errors: []
diff --git a/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_nested_for_if.snap.new b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_nested_for_if.snap.new
new file mode 100644
index 0000000..f07854c
--- /dev/null
+++ b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_nested_for_if.snap.new
@@ -0,0 +1,68 @@
+---
+source: crates/djls-template-ast/src/parser.rs
+assertion_line: 544
+expression: ast
+snapshot_kind: text
+---
+nodes:
+ - Block:
+ block_type: Standard
+ name: for
+ bits:
+ - for
+ - item
+ - in
+ - items
+ children:
+ - Block:
+ block_type: Standard
+ name: if
+ bits:
+ - if
+ - item.active
+ children:
+ - Variable:
+ bits:
+ - item
+ - name
+ filters: []
+ span:
+ start: 46
+ length: 9
+ - Block:
+ block_type: Closing
+ name: endif
+ bits: []
+ children: ~
+ span:
+ start: 58
+ length: 5
+ tag_span:
+ start: 23
+ length: 14
+ span:
+ start: 23
+ length: 40
+ tag_span:
+ start: 23
+ length: 14
+ - Block:
+ block_type: Closing
+ name: endfor
+ bits: []
+ children: ~
+ span:
+ start: 69
+ length: 6
+ tag_span:
+ start: 0
+ length: 17
+ span:
+ start: 0
+ length: 75
+ tag_span:
+ start: 0
+ length: 17
+line_offsets:
+ - 0
+errors: []
diff --git a/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__errors__parse_error_recovery.snap b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__errors__parse_error_recovery.snap
index 6567480..dd67046 100644
--- a/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__errors__parse_error_recovery.snap
+++ b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__errors__parse_error_recovery.snap
@@ -36,7 +36,7 @@ nodes:
- name
filters: []
span:
- start: 150
+ start: 152
length: 9
- Text:
content: "
\n \n "
@@ -72,7 +72,7 @@ nodes:
- item
filters: []
span:
- start: 294
+ start: 296
length: 4
- Text:
content: "\n "
@@ -108,17 +108,18 @@ nodes:
start: 48
length: 24
line_offsets:
+ - 0
- 0
- 24
- 44
- - 73
- - 123
- - 156
+ - 79
+ - 131
- 170
- - 228
- - 254
- - 284
- - 299
- - 332
+ - 184
+ - 244
+ - 276
+ - 312
+ - 333
+ - 366
errors:
- UnclosedTag: if
diff --git a/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__errors__parse_error_recovery.snap.new b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__errors__parse_error_recovery.snap.new
new file mode 100644
index 0000000..01b9918
--- /dev/null
+++ b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__errors__parse_error_recovery.snap.new
@@ -0,0 +1,126 @@
+---
+source: crates/djls-template-ast/src/parser.rs
+assertion_line: 677
+expression: ast
+snapshot_kind: text
+---
+nodes:
+ - Text:
+ content: "
\n
Header
\n "
+ span:
+ start: 0
+ length: 48
+ - Block:
+ block_type: Standard
+ name: if
+ bits:
+ - if
+ - user.is_authenticated
+ children:
+ - Text:
+ content: "\n "
+ span:
+ start: 78
+ length: 9
+ - Comment:
+ content: This if is unclosed which does matter
+ span:
+ start: 87
+ length: 41
+ - Text:
+ content: "\n
Welcome "
+ span:
+ start: 130
+ length: 20
+ - Variable:
+ bits:
+ - user
+ - name
+ filters: []
+ span:
+ start: 153
+ length: 9
+ - Text:
+ content: "
\n
\n "
+ span:
+ start: 165
+ length: 31
+ - Comment:
+ content: "This div is unclosed which doesn't matter"
+ span:
+ start: 196
+ length: 45
+ - Text:
+ content: "\n "
+ span:
+ start: 243
+ length: 9
+ - Block:
+ block_type: Standard
+ name: for
+ bits:
+ - for
+ - item
+ - in
+ - items
+ children:
+ - Text:
+ content: "\n "
+ span:
+ start: 275
+ length: 19
+ - Variable:
+ bits:
+ - item
+ filters: []
+ span:
+ start: 297
+ length: 4
+ - Text:
+ content: "\n "
+ span:
+ start: 304
+ length: 16
+ - Block:
+ block_type: Closing
+ name: endfor
+ bits: []
+ children: ~
+ span:
+ start: 320
+ length: 6
+ tag_span:
+ start: 252
+ length: 17
+ span:
+ start: 252
+ length: 74
+ tag_span:
+ start: 252
+ length: 17
+ - Text:
+ content: "\n \n
"
+ span:
+ start: 332
+ length: 40
+ span:
+ start: 48
+ length: 24
+ tag_span:
+ start: 48
+ length: 24
+line_offsets:
+ - 0
+ - 24
+ - 44
+ - 79
+ - 131
+ - 170
+ - 184
+ - 244
+ - 276
+ - 312
+ - 333
+ - 366
+errors:
+ - UnclosedTag: if
diff --git a/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__errors__parse_unclosed_django_for.snap b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__errors__parse_unclosed_django_for.snap
index d9352d2..68ef466 100644
--- a/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__errors__parse_unclosed_django_for.snap
+++ b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__errors__parse_unclosed_django_for.snap
@@ -18,7 +18,7 @@ nodes:
- name
filters: []
span:
- start: 23
+ start: 25
length: 9
span:
start: 0
@@ -28,5 +28,6 @@ nodes:
length: 17
line_offsets:
- 0
+ - 0
errors:
- UnclosedTag: for
diff --git a/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__errors__parse_unclosed_django_for.snap.new b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__errors__parse_unclosed_django_for.snap.new
new file mode 100644
index 0000000..b94c595
--- /dev/null
+++ b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__errors__parse_unclosed_django_for.snap.new
@@ -0,0 +1,34 @@
+---
+source: crates/djls-template-ast/src/parser.rs
+assertion_line: 638
+expression: ast
+snapshot_kind: text
+---
+nodes:
+ - Block:
+ block_type: Standard
+ name: for
+ bits:
+ - for
+ - item
+ - in
+ - items
+ children:
+ - Variable:
+ bits:
+ - item
+ - name
+ filters: []
+ span:
+ start: 26
+ length: 9
+ span:
+ start: 0
+ length: 17
+ tag_span:
+ start: 0
+ length: 17
+line_offsets:
+ - 0
+errors:
+ - UnclosedTag: for
diff --git a/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__errors__parse_unclosed_django_if.snap b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__errors__parse_unclosed_django_if.snap
index 1fb1dfd..92ef3e9 100644
--- a/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__errors__parse_unclosed_django_if.snap
+++ b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__errors__parse_unclosed_django_if.snap
@@ -23,5 +23,6 @@ nodes:
length: 24
line_offsets:
- 0
+ - 0
errors:
- UnclosedTag: if
diff --git a/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__errors__parse_unclosed_django_if.snap.new b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__errors__parse_unclosed_django_if.snap.new
new file mode 100644
index 0000000..532510a
--- /dev/null
+++ b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__errors__parse_unclosed_django_if.snap.new
@@ -0,0 +1,29 @@
+---
+source: crates/djls-template-ast/src/parser.rs
+assertion_line: 628
+expression: ast
+snapshot_kind: text
+---
+nodes:
+ - Block:
+ block_type: Standard
+ name: if
+ bits:
+ - if
+ - user.is_authenticated
+ children:
+ - Text:
+ content: Welcome
+ span:
+ start: 30
+ length: 7
+ span:
+ start: 0
+ length: 24
+ tag_span:
+ start: 0
+ length: 24
+line_offsets:
+ - 0
+errors:
+ - UnclosedTag: if
diff --git a/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__errors__parse_unclosed_html_tag.snap b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__errors__parse_unclosed_html_tag.snap
index 6b42432..ab2ce91 100644
--- a/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__errors__parse_unclosed_html_tag.snap
+++ b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__errors__parse_unclosed_html_tag.snap
@@ -10,4 +10,5 @@ nodes:
length: 5
line_offsets:
- 0
+ - 0
errors: []
diff --git a/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__errors__parse_unclosed_html_tag.snap.new b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__errors__parse_unclosed_html_tag.snap.new
new file mode 100644
index 0000000..e924744
--- /dev/null
+++ b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__errors__parse_unclosed_html_tag.snap.new
@@ -0,0 +1,15 @@
+---
+source: crates/djls-template-ast/src/parser.rs
+assertion_line: 619
+expression: ast
+snapshot_kind: text
+---
+nodes:
+ - Text:
+ content: "
"
+ span:
+ start: 0
+ length: 5
+line_offsets:
+ - 0
+errors: []
diff --git a/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__errors__parse_unclosed_script.snap b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__errors__parse_unclosed_script.snap
index 1e35fbd..457c0f6 100644
--- a/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__errors__parse_unclosed_script.snap
+++ b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__errors__parse_unclosed_script.snap
@@ -10,4 +10,5 @@ nodes:
length: 28
line_offsets:
- 0
+ - 0
errors: []
diff --git a/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__errors__parse_unclosed_script.snap.new b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__errors__parse_unclosed_script.snap.new
new file mode 100644
index 0000000..ae9d2b5
--- /dev/null
+++ b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__errors__parse_unclosed_script.snap.new
@@ -0,0 +1,15 @@
+---
+source: crates/djls-template-ast/src/parser.rs
+assertion_line: 648
+expression: ast
+snapshot_kind: text
+---
+nodes:
+ - Text:
+ content: "\n \n \n \n
\n "
+ span:
+ start: 0
+ length: 463
+ - Block:
+ block_type: Standard
+ name: if
+ bits:
+ - if
+ - user.is_authenticated
+ children:
+ - Text:
+ content: "\n "
+ span:
+ start: 493
+ length: 17
+ - Comment:
+ content: Welcome message
+ span:
+ start: 510
+ length: 19
+ - Text:
+ content: "\n
Welcome, "
+ span:
+ start: 531
+ length: 30
+ - Variable:
+ bits:
+ - user
+ - name
+ filters:
+ - name: title
+ arguments: []
+ span:
+ start: 571
+ length: 5
+ - name: default
+ arguments:
+ - "'Guest'"
+ span:
+ start: 577
+ length: 15
+ span:
+ start: 564
+ length: 31
+ - Text:
+ content: "!
\n "
+ span:
+ start: 598
+ length: 23
+ - Block:
+ block_type: Standard
+ name: if
+ bits:
+ - if
+ - user.is_staff
+ children:
+ - Text:
+ content: "\n Admin\n "
+ span:
+ start: 643
+ length: 56
+ - Block:
+ block_type: Branch
+ name: else
+ bits: []
+ children:
+ - Text:
+ content: "\n User\n "
+ span:
+ start: 709
+ length: 55
+ span:
+ start: 621
+ length: 16
+ tag_span:
+ start: 621
+ length: 16
+ - Block:
+ block_type: Closing
+ name: endif
+ bits: []
+ children: ~
+ span:
+ start: 764
+ length: 5
+ tag_span:
+ start: 621
+ length: 16
+ span:
+ start: 621
+ length: 148
+ tag_span:
+ start: 621
+ length: 16
+ - Text:
+ content: "\n "
+ span:
+ start: 775
+ length: 13
+ - Block:
+ block_type: Closing
+ name: endif
+ bits: []
+ children: ~
+ span:
+ start: 788
+ length: 5
+ tag_span:
+ start: 463
+ length: 24
+ span:
+ start: 463
+ length: 330
+ tag_span:
+ start: 463
+ length: 24
+ - Text:
+ content: "\n \n \n