mirror of
https://github.com/joshuadavidthomas/django-language-server.git
synced 2025-09-27 12:29:30 +00:00
fix parseing of django tags with potential intermediates
This commit is contained in:
parent
a5e42fe7a4
commit
134f3fea54
2 changed files with 141 additions and 4 deletions
|
@ -155,8 +155,18 @@ impl Parser {
|
|||
if tag == end_tag {
|
||||
self.consume()?;
|
||||
break;
|
||||
} else if !tag.starts_with("end") {
|
||||
// For intermediate tags (else, elif, empty, etc.)
|
||||
self.consume()?;
|
||||
// Create a new Tag node for the intermediate tag
|
||||
children.push(Node::Django(DjangoNode::Tag {
|
||||
kind: DjangoTagKind::from_str(&tag)?,
|
||||
bits: vec![tag.clone()],
|
||||
children: Vec::new(),
|
||||
}));
|
||||
} else {
|
||||
return Err(ParserError::ErrorSignal(Signal::ClosingTagFound(tag)));
|
||||
}
|
||||
// If it's not our end tag, keep collecting children
|
||||
}
|
||||
Err(e) => return Err(e),
|
||||
}
|
||||
|
@ -453,16 +463,37 @@ impl Parser {
|
|||
const SYNC_TYPES: &[TokenType] = &[
|
||||
TokenType::DjangoBlock(String::new()),
|
||||
TokenType::HtmlTagOpen(String::new()),
|
||||
TokenType::HtmlTagClose(String::new()), // Added
|
||||
TokenType::HtmlTagVoid(String::new()),
|
||||
TokenType::ScriptTagOpen(String::new()),
|
||||
TokenType::ScriptTagClose(String::new()), // Added
|
||||
TokenType::StyleTagOpen(String::new()),
|
||||
TokenType::StyleTagClose(String::new()), // Added
|
||||
TokenType::Newline,
|
||||
TokenType::Eof,
|
||||
];
|
||||
|
||||
let mut nesting = 0;
|
||||
while !self.is_at_end() {
|
||||
if SYNC_TYPES.contains(self.peek()?.token_type()) {
|
||||
return Ok(());
|
||||
let token = self.peek()?;
|
||||
match token.token_type() {
|
||||
TokenType::HtmlTagOpen(_)
|
||||
| TokenType::ScriptTagOpen(_)
|
||||
| TokenType::StyleTagOpen(_) => {
|
||||
nesting += 1;
|
||||
}
|
||||
TokenType::HtmlTagClose(_)
|
||||
| TokenType::ScriptTagClose(_)
|
||||
| TokenType::StyleTagClose(_) => {
|
||||
nesting -= 1;
|
||||
if nesting < 0 {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
_ if SYNC_TYPES.contains(token.token_type()) && nesting == 0 => {
|
||||
return Ok(());
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
self.consume()?;
|
||||
}
|
||||
|
@ -609,7 +640,7 @@ mod tests {
|
|||
}
|
||||
|
||||
// hangs for some reason
|
||||
// #[test]
|
||||
#[test]
|
||||
fn test_parse_full() {
|
||||
let source = r#"<!DOCTYPE html>
|
||||
<html>
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
---
|
||||
source: crates/djls-ast/src/parser.rs
|
||||
expression: ast
|
||||
---
|
||||
nodes:
|
||||
- Html:
|
||||
Doctype: "!DOCTYPE"
|
||||
- Html:
|
||||
Element:
|
||||
tag_name: html
|
||||
attributes: {}
|
||||
children:
|
||||
- Html:
|
||||
Element:
|
||||
tag_name: head
|
||||
attributes: {}
|
||||
children:
|
||||
- Style:
|
||||
Element:
|
||||
attributes:
|
||||
type:
|
||||
Value: text/css
|
||||
children:
|
||||
- Style:
|
||||
Comment: Style header
|
||||
- Text: ".header "
|
||||
- Text: "{"
|
||||
- Text: "color: blue; }"
|
||||
- Script:
|
||||
Element:
|
||||
attributes:
|
||||
script: Boolean
|
||||
type:
|
||||
Value: text/javascript
|
||||
children:
|
||||
- Script:
|
||||
Comment:
|
||||
content: Init app
|
||||
kind: SingleLine
|
||||
- Text: "const app = "
|
||||
- Text: "{"
|
||||
- Script:
|
||||
Comment:
|
||||
content: Config
|
||||
kind: MultiLine
|
||||
- Text: "debug: true"
|
||||
- Text: "};"
|
||||
- Html:
|
||||
Element:
|
||||
tag_name: body
|
||||
attributes: {}
|
||||
children:
|
||||
- Html:
|
||||
Comment: Header section
|
||||
- Html:
|
||||
Element:
|
||||
tag_name: div
|
||||
attributes:
|
||||
class:
|
||||
Value: header
|
||||
data-value:
|
||||
Value: "123"
|
||||
disabled: Boolean
|
||||
id:
|
||||
Value: main
|
||||
children:
|
||||
- Django:
|
||||
Tag:
|
||||
kind: If
|
||||
bits:
|
||||
- if
|
||||
- user.is_authenticated
|
||||
children:
|
||||
- Django:
|
||||
Comment: Welcome message
|
||||
- Html:
|
||||
Element:
|
||||
tag_name: h1
|
||||
attributes: {}
|
||||
children:
|
||||
- Text: "Welcome, "
|
||||
- Django:
|
||||
Variable:
|
||||
bits:
|
||||
- user
|
||||
- name
|
||||
filters:
|
||||
- name: default
|
||||
arguments:
|
||||
- Guest
|
||||
- name: title
|
||||
arguments: []
|
||||
- Text: "!"
|
||||
- Django:
|
||||
Tag:
|
||||
kind: If
|
||||
bits:
|
||||
- if
|
||||
- user.is_staff
|
||||
children:
|
||||
- Html:
|
||||
Element:
|
||||
tag_name: span
|
||||
attributes: {}
|
||||
children:
|
||||
- Text: Admin
|
Loading…
Add table
Add a link
Reference in a new issue