mirror of
https://github.com/joshuadavidthomas/django-language-server.git
synced 2025-09-10 04:16:30 +00:00
remove variable type
This commit is contained in:
parent
360276af1a
commit
1295247aa9
4 changed files with 44 additions and 68 deletions
|
@ -127,9 +127,6 @@ pub enum Block {
|
|||
tag: Tag,
|
||||
template_name: String,
|
||||
},
|
||||
Variable {
|
||||
tag: Tag,
|
||||
},
|
||||
Closing {
|
||||
tag: Tag,
|
||||
},
|
||||
|
@ -231,21 +228,6 @@ Examples:
|
|||
- `{% include "template.html" %}`
|
||||
- `{% extends "base.html" %}`
|
||||
|
||||
##### `Block::Variable`
|
||||
|
||||
Represents tags that output a value directly.
|
||||
|
||||
```rust
|
||||
Block::Variable {
|
||||
tag: Tag, // The Tag of the variable tag
|
||||
}
|
||||
```
|
||||
|
||||
Examples:
|
||||
|
||||
- `{% cycle %}`
|
||||
- `{% firstof %}`
|
||||
|
||||
##### `Block::Closing`
|
||||
|
||||
Represents closing tags corresponding to opening block tags.
|
||||
|
@ -270,15 +252,21 @@ Tag Specifications (TagSpecs) define how tags are parsed and understood. They al
|
|||
|
||||
```toml
|
||||
[package.module.path.tag_name] # Path where tag is registered, e.g., django.template.defaulttags
|
||||
type = "block" | "inclusion" | "tag" | "variable"
|
||||
type = "block" | "inclusion" | "tag"
|
||||
closing = "closing_tag_name" # For block tags that require a closing tag
|
||||
branches = ["branch_tag_name", ...] # For block tags that support branches
|
||||
|
||||
[[package.module.path.tag_name.args]]
|
||||
name = "argument_name"
|
||||
required = true | false
|
||||
# Arguments can be positional (matched by order) or keyword (matched by name)
|
||||
args = [
|
||||
# Positional argument (position inferred from array index)
|
||||
{ name = "setting", required = true, allowed_values = ["on", "off"] },
|
||||
# Keyword argument
|
||||
{ name = "key", required = false, is_kwarg = true }
|
||||
]
|
||||
```
|
||||
|
||||
The `name` field in args should match the internal name used in Django's node implementation. For example, the `autoescape` tag's argument is stored as `setting` in Django's `AutoEscapeControlNode`.
|
||||
|
||||
### Tag Types
|
||||
|
||||
- `block`: Tags that wrap content and require a closing tag
|
||||
|
@ -301,13 +289,6 @@ required = true | false
|
|||
{% csrf_token %}
|
||||
```
|
||||
|
||||
- `variable`: Tags that output a value directly
|
||||
|
||||
```django
|
||||
{% cycle 'odd' 'even' %}
|
||||
{% firstof var1 var2 var3 %}
|
||||
```
|
||||
|
||||
### Configuration
|
||||
|
||||
- **Built-in TagSpecs**: The parser includes TagSpecs for Django's built-in tags and popular third-party tags.
|
||||
|
@ -322,10 +303,7 @@ required = true | false
|
|||
type = "block"
|
||||
closing = "endif"
|
||||
branches = ["elif", "else"]
|
||||
|
||||
[[django.template.defaulttags.if.args]]
|
||||
name = "condition"
|
||||
required = true
|
||||
args = [{ name = "condition", required = true }]
|
||||
```
|
||||
|
||||
#### Include Tag
|
||||
|
@ -333,19 +311,25 @@ required = true
|
|||
```toml
|
||||
[django.template.defaulttags.includes]
|
||||
type = "inclusion"
|
||||
|
||||
[[django.template.defaulttags.includes.args]]
|
||||
name = "template_name"
|
||||
required = true
|
||||
args = [{ name = "template_name", required = true }]
|
||||
```
|
||||
|
||||
#### Custom Tag
|
||||
#### Autoescape Tag
|
||||
|
||||
```toml
|
||||
[django.template.defaulttags.autoescape]
|
||||
type = "block"
|
||||
closing = "endautoescape"
|
||||
args = [{ name = "setting", required = true, allowed_values = ["on", "off"] }]
|
||||
```
|
||||
|
||||
#### Custom Tag with Kwargs
|
||||
|
||||
```toml
|
||||
[my_module.templatetags.my_tags.my_custom_tag]
|
||||
type = "tag"
|
||||
|
||||
{[my_module.templatetags.my_tags.my_custom_tag.args]]
|
||||
name = "arg1"
|
||||
required = false
|
||||
args = [
|
||||
{ name = "arg1", required = true },
|
||||
{ name = "kwarg1", required = false, is_kwarg = true }
|
||||
]
|
||||
```
|
||||
|
|
|
@ -162,9 +162,6 @@ pub enum Block {
|
|||
tag: Tag,
|
||||
template_name: String,
|
||||
},
|
||||
Variable {
|
||||
tag: Tag,
|
||||
},
|
||||
Closing {
|
||||
tag: Tag,
|
||||
},
|
||||
|
@ -177,7 +174,6 @@ impl Block {
|
|||
| Self::Branch { tag, .. }
|
||||
| Self::Tag { tag }
|
||||
| Self::Inclusion { tag, .. }
|
||||
| Self::Variable { tag }
|
||||
| Self::Closing { tag } => tag,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -110,7 +110,6 @@ impl Parser {
|
|||
Some(spec) => match spec.tag_type {
|
||||
TagType::Block => self.parse_block_tag(tag, spec),
|
||||
TagType::Tag => Ok(Node::Block(Block::Tag { tag })),
|
||||
TagType::Variable => Ok(Node::Block(Block::Variable { tag })),
|
||||
TagType::Inclusion => {
|
||||
let template_name = tag.bits.get(1).cloned().unwrap_or_default();
|
||||
Ok(Node::Block(Block::Inclusion { tag, template_name }))
|
||||
|
|
|
@ -117,11 +117,6 @@ impl TagSpec {
|
|||
let name = prefix.map_or_else(String::new, |p| {
|
||||
p.split('.').last().unwrap_or(p).to_string()
|
||||
});
|
||||
eprintln!(
|
||||
"Found tag spec at '{}', using name '{}'",
|
||||
prefix.unwrap_or(""),
|
||||
name
|
||||
);
|
||||
specs.insert(name, tag_spec);
|
||||
}
|
||||
Err(_) => {
|
||||
|
@ -131,7 +126,6 @@ impl TagSpec {
|
|||
None => key.clone(),
|
||||
Some(p) => format!("{}.{}", p, key),
|
||||
};
|
||||
eprintln!("Recursing into prefix: {}", new_prefix);
|
||||
Self::extract_specs(value, Some(&new_prefix), specs)?;
|
||||
}
|
||||
}
|
||||
|
@ -146,13 +140,16 @@ pub enum TagType {
|
|||
Block,
|
||||
Tag,
|
||||
Inclusion,
|
||||
Variable,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
pub struct ArgSpec {
|
||||
pub name: String,
|
||||
pub required: bool,
|
||||
#[serde(default)]
|
||||
pub allowed_values: Option<Vec<String>>,
|
||||
#[serde(default)]
|
||||
pub is_kwarg: bool,
|
||||
}
|
||||
|
||||
impl ArgSpec {
|
||||
|
@ -179,12 +176,8 @@ mod tests {
|
|||
|
||||
assert!(!specs.0.is_empty(), "Should have loaded at least one spec");
|
||||
|
||||
for (name, spec) in &specs.0 {
|
||||
for name in specs.0.keys() {
|
||||
assert!(!name.is_empty(), "Tag name should not be empty");
|
||||
assert!(
|
||||
spec.tag_type == TagType::Block || spec.tag_type == TagType::Variable,
|
||||
"Tag type should be block or variable"
|
||||
);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -193,31 +186,35 @@ mod tests {
|
|||
fn test_builtin_django_tags() -> Result<(), anyhow::Error> {
|
||||
let specs = TagSpecs::load_builtin_specs()?;
|
||||
|
||||
let expected_tags = ["block", "for", "if"];
|
||||
let missing_tags = [
|
||||
let expected_tags = [
|
||||
"autoescape",
|
||||
"block",
|
||||
"comment",
|
||||
"csrf_token",
|
||||
"cycle",
|
||||
"debug",
|
||||
"extends",
|
||||
"filter",
|
||||
"for",
|
||||
"firstof",
|
||||
"ifchanged",
|
||||
"if",
|
||||
"include",
|
||||
"load",
|
||||
"lorem",
|
||||
"now",
|
||||
"querystring", // 5.1
|
||||
"regroup",
|
||||
"resetcycle",
|
||||
"spaceless",
|
||||
"templatetag",
|
||||
"url",
|
||||
"verbatim",
|
||||
"widthratio",
|
||||
"with",
|
||||
];
|
||||
let missing_tags = [
|
||||
"csrf_token",
|
||||
"ifchanged",
|
||||
"lorem",
|
||||
"querystring", // 5.1
|
||||
"regroup",
|
||||
"resetcycle",
|
||||
"widthratio",
|
||||
];
|
||||
|
||||
for tag in expected_tags {
|
||||
assert!(specs.get(tag).is_some(), "{} tag should be present", tag);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue