This commit is contained in:
Josh Thomas 2025-01-04 23:54:42 -06:00
parent 3ebf698a07
commit 9d65db2a3a
21 changed files with 998 additions and 6 deletions

View file

@ -162,7 +162,7 @@ impl Parser {
bits, bits,
children: Some(branch_children), children: Some(branch_children),
span: branch_span, span: branch_span,
tag_span: tag_span.clone(), tag_span,
}); });
} }
let closing_token = self.peek_previous()?; let closing_token = self.peek_previous()?;
@ -171,7 +171,6 @@ impl Parser {
_ => 0, _ => 0,
}; };
total_length = (closing_token.start().unwrap_or(0) + closing_content) total_length = (closing_token.start().unwrap_or(0) + closing_content)
as usize
- start_pos as usize; - start_pos as usize;
children.push(Node::Block { children.push(Node::Block {
block_type: BlockType::Closing, block_type: BlockType::Closing,
@ -182,7 +181,7 @@ impl Parser {
closing_token.start().unwrap_or(0) as u32, closing_token.start().unwrap_or(0) as u32,
closing_content as u16, closing_content as u16,
), ),
tag_span: tag_span.clone(), tag_span,
}); });
found_closing_tag = true; found_closing_tag = true;
break; break;
@ -199,7 +198,7 @@ impl Parser {
bits, bits,
children: Some(branch_children), children: Some(branch_children),
span: branch_span, span: branch_span,
tag_span: tag_span.clone(), tag_span,
}); });
} }
// Create new branch node // Create new branch node
@ -227,7 +226,7 @@ impl Parser {
bits: bits.clone(), bits: bits.clone(),
children: Some(children.clone()), children: Some(children.clone()),
span: Span::new(start_pos, total_length as u16), span: Span::new(start_pos, total_length as u16),
tag_span: tag_span.clone(), tag_span,
}; };
return Err(ParserError::Ast(AstError::UnexpectedTag(tag), Some(node))); return Err(ParserError::Ast(AstError::UnexpectedTag(tag), Some(node)));
} }
@ -268,6 +267,9 @@ impl Parser {
let parts: Vec<&str> = s.split('|').collect(); let parts: Vec<&str> = s.split('|').collect();
let bits: Vec<String> = parts[0].trim().split('.').map(String::from).collect(); let bits: Vec<String> = parts[0].trim().split('.').map(String::from).collect();
// Track position in the string for filter spans
let mut current_pos = parts[0].len() + 1; // +1 for the pipe
let filters: Vec<DjangoFilter> = parts[1..] let filters: Vec<DjangoFilter> = parts[1..]
.iter() .iter()
.map(|filter_str| { .map(|filter_str| {
@ -284,7 +286,11 @@ impl Parser {
Vec::new() Vec::new()
}; };
DjangoFilter::new(name, arguments) let filter_span =
Span::new(start_pos + current_pos as u32, filter_str.len() as u16);
current_pos += filter_str.len() + 1; // +1 for the pipe
DjangoFilter::new(name, arguments, filter_span)
}) })
.collect(); .collect();

View file

@ -0,0 +1,19 @@
---
source: crates/djls-template-ast/src/parser.rs
assertion_line: 605
expression: ast
snapshot_kind: text
---
nodes:
- Text:
content: "<!-- HTML comment -->"
span:
start: 0
length: 21
- Comment:
content: Django comment
span:
start: 21
length: 18
line_offsets: []
errors: []

View file

@ -0,0 +1,75 @@
---
source: crates/djls-template-ast/src/parser.rs
assertion_line: 524
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: []
errors: []

View file

@ -0,0 +1,58 @@
---
source: crates/djls-template-ast/src/parser.rs
assertion_line: 515
expression: ast
snapshot_kind: text
---
nodes:
- Block:
block_type: Standard
name: for
bits:
- for
- item
- in
- items
children:
- Variable:
bits:
- item
filters: []
span:
start: 23
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: []
errors: []

View file

@ -0,0 +1,38 @@
---
source: crates/djls-template-ast/src/parser.rs
assertion_line: 506
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: []
errors: []

View file

@ -0,0 +1,22 @@
---
source: crates/djls-template-ast/src/parser.rs
assertion_line: 488
expression: ast
snapshot_kind: text
---
nodes:
- Variable:
bits:
- user
- name
filters:
- name: title
arguments: []
span:
start: 10
length: 5
span:
start: 0
length: 15
line_offsets: []
errors: []

View file

@ -0,0 +1,32 @@
---
source: crates/djls-template-ast/src/parser.rs
assertion_line: 497
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: 0
length: 35
line_offsets: []
errors: []

View file

@ -0,0 +1,256 @@
---
source: crates/djls-template-ast/src/parser.rs
assertion_line: 555
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: 44
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: 168
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: []
errors: []

View file

@ -0,0 +1,67 @@
---
source: crates/djls-template-ast/src/parser.rs
assertion_line: 534
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: 43
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: []
errors: []

View file

@ -0,0 +1,114 @@
---
source: crates/djls-template-ast/src/parser.rs
assertion_line: 681
expression: ast
snapshot_kind: text
---
nodes:
- Text:
content: "<div class=\"container\">\n <h1>Header</h1>\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 <p>Welcome "
span:
start: 130
length: 20
- Variable:
bits:
- user
- name
filters: []
span:
start: 150
length: 9
- Text:
content: "</p>\n <div>\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>"
span:
start: 275
length: 19
- Variable:
bits:
- item
filters: []
span:
start: 294
length: 4
- Text:
content: "</span>\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 <footer>Page Footer</footer>\n</div>"
span:
start: 332
length: 40
span:
start: 48
length: 24
tag_span:
start: 48
length: 24
line_offsets: []
errors:
- UnclosedTag: if

View file

@ -0,0 +1,33 @@
---
source: crates/djls-template-ast/src/parser.rs
assertion_line: 639
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: 23
length: 9
span:
start: 0
length: 17
tag_span:
start: 0
length: 17
line_offsets: []
errors:
- UnclosedTag: for

View file

@ -0,0 +1,28 @@
---
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: []
errors:
- UnclosedTag: if

View file

@ -0,0 +1,14 @@
---
source: crates/djls-template-ast/src/parser.rs
assertion_line: 618
expression: ast
snapshot_kind: text
---
nodes:
- Text:
content: "<div>"
span:
start: 0
length: 5
line_offsets: []
errors: []

View file

@ -0,0 +1,14 @@
---
source: crates/djls-template-ast/src/parser.rs
assertion_line: 650
expression: ast
snapshot_kind: text
---
nodes:
- Text:
content: "<script>console.log('test');"
span:
start: 0
length: 28
line_offsets: []
errors: []

View file

@ -0,0 +1,14 @@
---
source: crates/djls-template-ast/src/parser.rs
assertion_line: 660
expression: ast
snapshot_kind: text
---
nodes:
- Text:
content: "<style>body { color: blue; "
span:
start: 0
length: 27
line_offsets: []
errors: []

View file

@ -0,0 +1,132 @@
---
source: crates/djls-template-ast/src/parser.rs
assertion_line: 725
expression: ast
snapshot_kind: text
---
nodes:
- Text:
content: "<!DOCTYPE html>\n<html>\n <head>\n <style type=\"text/css\">\n /* Style header */\n .header { color: blue; }\n </style>\n <script type=\"text/javascript\">\n // Init app\n const app = {\n /* Config */\n debug: true\n };\n </script>\n </head>\n <body>\n <!-- Header section -->\n <div class=\"header\" id=\"main\" data-value=\"123\" disabled>\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 <h1>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: 561
length: 31
- Text:
content: "!</h1>\n "
span:
start: 598
length: 23
- Block:
block_type: Standard
name: if
bits:
- if
- user.is_staff
children:
- Text:
content: "\n <span>Admin</span>\n "
span:
start: 643
length: 56
- Block:
block_type: Branch
name: else
bits: []
children:
- Text:
content: "\n <span>User</span>\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 </div>\n </body>\n</html>"
span:
start: 799
length: 35
line_offsets: []
errors: []

View file

@ -0,0 +1,14 @@
---
source: crates/djls-template-ast/src/parser.rs
assertion_line: 457
expression: ast
snapshot_kind: text
---
nodes:
- Text:
content: "<!DOCTYPE html>"
span:
start: 0
length: 15
line_offsets: []
errors: []

View file

@ -0,0 +1,14 @@
---
source: crates/djls-template-ast/src/parser.rs
assertion_line: 466
expression: ast
snapshot_kind: text
---
nodes:
- Text:
content: "<div class=\"container\">Hello</div>"
span:
start: 0
length: 34
line_offsets: []
errors: []

View file

@ -0,0 +1,14 @@
---
source: crates/djls-template-ast/src/parser.rs
assertion_line: 475
expression: ast
snapshot_kind: text
---
nodes:
- Text:
content: "<input type=\"text\" />"
span:
start: 0
length: 21
line_offsets: []
errors: []

View file

@ -0,0 +1,14 @@
---
source: crates/djls-template-ast/src/parser.rs
assertion_line: 574
expression: ast
snapshot_kind: text
---
nodes:
- Text:
content: "<script type=\"text/javascript\">\n // Single line comment\n const x = 1;\n /* Multi-line\n comment */\n console.log(x);\n</script>"
span:
start: 0
length: 142
line_offsets: []
errors: []

View file

@ -0,0 +1,14 @@
---
source: crates/djls-template-ast/src/parser.rs
assertion_line: 592
expression: ast
snapshot_kind: text
---
nodes:
- Text:
content: "<style type=\"text/css\">\n /* Header styles */\n .header {\n color: blue;\n }\n</style>"
span:
start: 0
length: 97
line_offsets: []
errors: []