Skip to content

Commit 948ce3f

Browse files
remove salsa from the inner workings of the template crate (#259)
1 parent b4f696f commit 948ce3f

File tree

11 files changed

+296
-564
lines changed

11 files changed

+296
-564
lines changed

crates/djls-bench/benches/parser.rs

Lines changed: 7 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -8,56 +8,18 @@ fn main() {
88
}
99

1010
#[divan::bench(args = template_fixtures())]
11-
fn parse_template(bencher: Bencher, fixture: &TemplateFixture) {
12-
let db = std::cell::RefCell::new(Db::new());
13-
14-
let counter = std::cell::Cell::new(0_usize);
15-
16-
bencher
17-
.with_inputs(|| {
18-
let i = counter.get();
19-
counter.set(i + 1);
20-
let path = format!("{}.bench{}", fixture.path.clone(), i);
21-
db.borrow_mut()
22-
.file_with_contents(path.into(), &fixture.source.clone())
23-
})
24-
.bench_local_values(|file| {
25-
let db = db.borrow();
26-
if let Some(nodelist) = djls_templates::parse_template(&*db, file) {
27-
divan::black_box(nodelist.nodelist(&*db).len());
28-
}
29-
});
11+
fn parse_template(fixture: &TemplateFixture) {
12+
let _ = djls_templates::parse_template_impl(&fixture.source);
3013
}
3114

3215
#[divan::bench]
3316
fn parse_all_templates(bencher: Bencher) {
3417
let fixtures = template_fixtures();
35-
let db = std::cell::RefCell::new(Db::new());
36-
37-
let counter = std::cell::Cell::new(0_usize);
38-
39-
bencher
40-
.with_inputs(|| {
41-
let i = counter.get();
42-
counter.set(i + 1);
43-
44-
let mut db = db.borrow_mut();
45-
fixtures
46-
.iter()
47-
.map(|fixture| {
48-
let path = format!("{}.bench{}", fixture.path, i);
49-
db.file_with_contents(path.into(), &fixture.source)
50-
})
51-
.collect::<Vec<_>>()
52-
})
53-
.bench_local_values(|files| {
54-
let db = db.borrow();
55-
for file in files {
56-
if let Some(nodelist) = djls_templates::parse_template(&*db, file) {
57-
divan::black_box(nodelist.nodelist(&*db).len());
58-
}
59-
}
60-
});
18+
bencher.bench_local(move || {
19+
for fixture in fixtures {
20+
let _ = djls_templates::parse_template_impl(&fixture.source);
21+
}
22+
});
6123
}
6224

6325
#[divan::bench(args = template_fixtures())]

crates/djls-semantic/src/blocks/builder.rs

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
use djls_source::Span;
2-
use djls_templates::nodelist::TagBit;
3-
use djls_templates::nodelist::TagName;
42
use djls_templates::tokens::TagDelimiter;
53
use djls_templates::Node;
64

@@ -49,7 +47,7 @@ enum BlockSemanticOp {
4947
pub struct BlockTreeBuilder<'db> {
5048
db: &'db dyn Db,
5149
index: &'db TagIndex,
52-
stack: Vec<TreeFrame<'db>>,
50+
stack: Vec<TreeFrame>,
5351
block_allocs: Vec<(Span, Option<BlockId>)>,
5452
semantic_ops: Vec<BlockSemanticOp>,
5553
}
@@ -136,9 +134,9 @@ impl<'db> BlockTreeBuilder<'db> {
136134
tree
137135
}
138136

139-
fn handle_tag(&mut self, name: TagName<'db>, bits: Vec<TagBit<'db>>, span: Span) {
140-
let tag_name = name.text(self.db);
141-
match self.index.classify(&tag_name) {
137+
fn handle_tag(&mut self, name: &str, bits: &[String], span: Span) {
138+
let tag_name = name;
139+
match self.index.classify(tag_name) {
142140
TagClass::Opener => {
143141
let parent = get_active_segment(&self.stack);
144142

@@ -152,14 +150,14 @@ impl<'db> BlockTreeBuilder<'db> {
152150
// Nested block
153151
self.semantic_ops.push(BlockSemanticOp::AddBranchNode {
154152
target: parent_id,
155-
tag: tag_name.clone(),
153+
tag: tag_name.to_string(),
156154
marker_span: span,
157155
body: container,
158156
kind: BranchKind::Opener,
159157
});
160158
self.semantic_ops.push(BlockSemanticOp::AddBranchNode {
161159
target: container,
162-
tag: tag_name.clone(),
160+
tag: tag_name.to_string(),
163161
marker_span: span,
164162
body: segment,
165163
kind: BranchKind::Segment,
@@ -170,41 +168,41 @@ impl<'db> BlockTreeBuilder<'db> {
170168
.push(BlockSemanticOp::AddRoot { id: container });
171169
self.semantic_ops.push(BlockSemanticOp::AddBranchNode {
172170
target: container,
173-
tag: tag_name.clone(),
171+
tag: tag_name.to_string(),
174172
marker_span: span,
175173
body: segment,
176174
kind: BranchKind::Segment,
177175
});
178176
}
179177

180178
self.stack.push(TreeFrame {
181-
opener_name: tag_name,
182-
opener_bits: bits,
179+
opener_name: tag_name.to_string(),
180+
opener_bits: bits.to_vec(),
183181
opener_span: span,
184182
container_body: container,
185183
segment_body: segment,
186184
parent_body: parent,
187185
});
188186
}
189187
TagClass::Closer { opener_name } => {
190-
self.close_block(&opener_name, &bits, span);
188+
self.close_block(&opener_name, bits, span);
191189
}
192190
TagClass::Intermediate { possible_openers } => {
193-
self.add_intermediate(&tag_name, &possible_openers, span);
191+
self.add_intermediate(tag_name, &possible_openers, span);
194192
}
195193
TagClass::Unknown => {
196194
if let Some(segment) = get_active_segment(&self.stack) {
197195
self.semantic_ops.push(BlockSemanticOp::AddLeafNode {
198196
target: segment,
199-
label: tag_name,
197+
label: tag_name.to_string(),
200198
span,
201199
});
202200
}
203201
}
204202
}
205203
}
206204

207-
fn close_block(&mut self, opener_name: &str, closer_bits: &[TagBit<'db>], span: Span) {
205+
fn close_block(&mut self, opener_name: &str, closer_bits: &[String], span: Span) {
208206
if let Some(frame_idx) = find_frame_from_opener(&self.stack, opener_name) {
209207
// Pop any unclosed blocks above this one
210208
while self.stack.len() > frame_idx + 1 {
@@ -349,7 +347,7 @@ impl<'db> BlockTreeBuilder<'db> {
349347
}
350348
}
351349

352-
type TreeStack<'db> = Vec<TreeFrame<'db>>;
350+
type TreeStack = Vec<TreeFrame>;
353351

354352
/// Get the currently active segment (the innermost block we're in)
355353
fn get_active_segment(stack: &TreeStack) -> Option<BlockId> {
@@ -361,9 +359,9 @@ fn find_frame_from_opener(stack: &TreeStack, opener_name: &str) -> Option<usize>
361359
stack.iter().rposition(|f| f.opener_name == opener_name)
362360
}
363361

364-
struct TreeFrame<'db> {
362+
struct TreeFrame {
365363
opener_name: String,
366-
opener_bits: Vec<TagBit<'db>>,
364+
opener_bits: Vec<String>,
367365
opener_span: Span,
368366
container_body: BlockId,
369367
segment_body: BlockId,
@@ -373,10 +371,10 @@ struct TreeFrame<'db> {
373371
impl<'db> SemanticModel<'db> for BlockTreeBuilder<'db> {
374372
type Model = BlockTree;
375373

376-
fn observe(&mut self, node: Node<'db>) {
374+
fn observe(&mut self, node: Node) {
377375
match node {
378376
Node::Tag { name, bits, span } => {
379-
self.handle_tag(name, bits, span);
377+
self.handle_tag(&name, &bits, span);
380378
}
381379
Node::Comment { span, .. } => {
382380
if let Some(parent) = get_active_segment(&self.stack) {

crates/djls-semantic/src/blocks/grammar.rs

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use djls_templates::nodelist::TagBit;
21
use rustc_hash::FxHashMap;
32

43
use crate::templatetags::TagSpecs;
@@ -52,12 +51,12 @@ impl TagIndex {
5251
.is_some_and(|meta| meta.optional)
5352
}
5453

55-
pub fn validate_close<'db>(
54+
pub fn validate_close(
5655
&self,
5756
opener_name: &str,
58-
opener_bits: &[TagBit<'db>],
59-
closer_bits: &[TagBit<'db>],
60-
db: &'db dyn crate::db::Db,
57+
opener_bits: &[String],
58+
closer_bits: &[String],
59+
_db: &dyn crate::db::Db,
6160
) -> CloseValidation {
6261
let Some(meta) = self.openers.get(opener_name) else {
6362
return CloseValidation::NotABlock;
@@ -69,8 +68,8 @@ impl TagIndex {
6968
}
7069

7170
for match_arg in &meta.match_args {
72-
let opener_val = extract_arg_value(opener_bits, match_arg.position, db);
73-
let closer_val = extract_arg_value(closer_bits, match_arg.position, db);
71+
let opener_val = extract_arg_value(opener_bits, match_arg.position);
72+
let closer_val = extract_arg_value(closer_bits, match_arg.position);
7473

7574
match (opener_val, closer_val, match_arg.required) {
7675
(Some(o), Some(c), _) if o != c => {
@@ -185,13 +184,9 @@ pub enum CloseValidation {
185184
},
186185
}
187186

188-
fn extract_arg_value<'db>(
189-
bits: &[TagBit<'db>],
190-
position: usize,
191-
db: &'db dyn crate::db::Db,
192-
) -> Option<String> {
187+
fn extract_arg_value(bits: &[String], position: usize) -> Option<String> {
193188
if position < bits.len() {
194-
Some(bits[position].text(db).to_string())
189+
Some(bits[position].clone())
195190
} else {
196191
None
197192
}

crates/djls-semantic/src/blocks/tree.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -347,13 +347,13 @@ mod tests {
347347
.iter()
348348
.map(|n| match n {
349349
Node::Tag { name, bits, span } => NodeView::Tag {
350-
name: name.text(&db).to_string(),
351-
bits: bits.iter().map(|b| b.text(&db).to_string()).collect(),
350+
name: name.clone(),
351+
bits: bits.clone(),
352352
span: *span,
353353
},
354354
Node::Variable { var, filters, span } => NodeView::Variable {
355-
var: var.text(&db).to_string(),
356-
filters: filters.iter().map(|f| f.text(&db).to_string()).collect(),
355+
var: var.clone(),
356+
filters: filters.clone(),
357357
span: *span,
358358
},
359359
Node::Comment { content, span } => NodeView::Comment {

crates/djls-semantic/src/traits.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ pub trait SemanticModel<'db> {
2525

2626
/// Observe a single node during traversal and extract semantic information
2727
#[allow(dead_code)] // use is gated behind cfg(test) for now
28-
fn observe(&mut self, node: Node<'db>);
28+
fn observe(&mut self, node: Node);
2929

3030
/// Construct the final semantic model from observed semantics
3131
#[allow(dead_code)] // use is gated behind cfg(test) for now

0 commit comments

Comments
 (0)