Skip to content

Commit 4b99118

Browse files
wip
1 parent 4d340f9 commit 4b99118

6 files changed

Lines changed: 45 additions & 106 deletions

File tree

crates/djls-project/src/python.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -652,14 +652,14 @@ mod tests {
652652
self.fs.clone()
653653
}
654654

655-
fn intern_file(&mut self, path: &Utf8Path) -> (File, bool) {
655+
fn track_file(&mut self, path: &Utf8Path) -> File {
656656
if let Some(entry) = self.files.get(path) {
657-
return (*entry, true);
657+
return *entry;
658658
}
659659

660660
let file = File::new(self, path.to_owned(), 0);
661661
self.files.insert(path.to_owned(), file);
662-
(file, false)
662+
file
663663
}
664664

665665
fn get_file(&self, path: &Utf8Path) -> Option<File> {

crates/djls-server/src/db.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -123,14 +123,14 @@ impl WorkspaceDb for DjangoDatabase {
123123
self.fs.clone()
124124
}
125125

126-
fn intern_file(&mut self, path: &Utf8Path) -> (File, bool) {
126+
fn track_file(&mut self, path: &Utf8Path) -> File {
127127
if let Some(entry) = self.files.get(path) {
128-
return (*entry, true);
128+
return *entry;
129129
}
130130

131131
let file = File::new(self, path.to_owned(), 0);
132132
self.files.insert(path.to_owned(), file);
133-
(file, false)
133+
file
134134
}
135135

136136
fn get_file(&self, path: &Utf8Path) -> Option<File> {

crates/djls-server/src/session.rs

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ use djls_source::File;
1010
use djls_source::FileKind;
1111
use djls_source::PositionEncoding;
1212
use djls_workspace::paths;
13+
use djls_workspace::Db as WorkspaceDb;
1314
use djls_workspace::TextDocument;
1415
use djls_workspace::Workspace;
15-
use djls_workspace::WorkspaceFileEvent;
1616
use tower_lsp_server::lsp_types;
1717
use url::Url;
1818

@@ -137,8 +137,8 @@ impl Session {
137137
/// the database or invalidates it if it already exists.
138138
/// For template files, immediately triggers parsing and validation.
139139
pub fn open_document(&mut self, url: &Url, document: TextDocument) {
140-
if let Some(event) = self.workspace.open_document(&mut self.db, url, document) {
141-
self.handle_file_event(&event);
140+
if let Some(file) = self.workspace.open_document(&mut self.db, url, document) {
141+
self.handle_file(file);
142142
}
143143
}
144144

@@ -152,20 +152,20 @@ impl Session {
152152
changes: Vec<lsp_types::TextDocumentContentChangeEvent>,
153153
version: i32,
154154
) {
155-
if let Some(event) = self.workspace.update_document(
155+
if let Some(file) = self.workspace.update_document(
156156
&mut self.db,
157157
url,
158158
changes,
159159
version,
160160
self.position_encoding,
161161
) {
162-
self.handle_file_event(&event);
162+
self.handle_file(file);
163163
}
164164
}
165165

166166
pub fn save_document(&mut self, url: &Url) -> Option<TextDocument> {
167-
if let Some(event) = self.workspace.save_document(&mut self.db, url) {
168-
self.handle_file_event(&event);
167+
if let Some(file) = self.workspace.save_document(&mut self.db, url) {
168+
self.handle_file(file);
169169
}
170170

171171
self.workspace.get_document(url)
@@ -187,20 +187,13 @@ impl Session {
187187

188188
/// Get or create a file in the database.
189189
pub fn get_or_create_file(&mut self, path: &Utf8PathBuf) -> File {
190-
self.workspace
191-
.track_file(&mut self.db, path.as_path())
192-
.file()
190+
self.db.track_file(path.as_path())
193191
}
194192

195-
/// Warm template caches and semantic diagnostics for the file event.
196-
///
197-
/// By invoking the tracked `parse_template`/`validate_nodelist` queries here
198-
/// we ensure Salsa records the dependency on the newly updated [`File`]
199-
/// while the accumulators gather diagnostics for later consumption.
200-
fn handle_file_event(&self, event: &WorkspaceFileEvent) {
201-
if FileKind::from(event.path()) == FileKind::Template {
202-
let nodelist = djls_templates::parse_template(&self.db, event.file());
203-
if let Some(nodelist) = nodelist {
193+
/// Warm template caches and semantic diagnostics for the updated file.
194+
fn handle_file(&self, file: File) {
195+
if FileKind::from(file.path(&self.db)) == FileKind::Template {
196+
if let Some(nodelist) = djls_templates::parse_template(&self.db, file) {
204197
djls_semantic::validate_nodelist(&self.db, nodelist);
205198
}
206199
}

crates/djls-workspace/src/db.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,12 @@ pub trait Db: SourceDb {
3535
/// Get the file system for reading files.
3636
fn fs(&self) -> Arc<dyn FileSystem>;
3737

38-
/// Get or create a tracked file for the given path.
39-
fn intern_file(&mut self, path: &Utf8Path) -> (File, bool);
40-
4138
/// Look up a tracked file if it exists.
4239
fn get_file(&self, path: &Utf8Path) -> Option<File>;
4340

41+
/// Get or create a tracked file for the given path.
42+
fn track_file(&mut self, path: &Utf8Path) -> File;
43+
4444
/// Bump the revision for a tracked file to invalidate dependent queries.
4545
fn touch_file(&mut self, file: File) {
4646
let current_rev = file.revision(self);

crates/djls-workspace/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,3 @@ pub use files::FileSystem;
2525
pub use files::InMemoryFileSystem;
2626
pub use language::LanguageId;
2727
pub use workspace::Workspace;
28-
pub use workspace::WorkspaceFileEvent;

crates/djls-workspace/src/workspace.rs

Lines changed: 24 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
//! state (open documents) while the database observes it through the overlay.
77
use std::sync::Arc;
88

9-
use camino::Utf8Path;
10-
use camino::Utf8PathBuf;
119
use djls_source::File;
1210
use djls_source::PositionEncoding;
1311
use tower_lsp_server::lsp_types::TextDocumentContentChangeEvent;
@@ -21,28 +19,6 @@ use crate::files::OsFileSystem;
2119
use crate::files::OverlayFileSystem;
2220
use crate::paths;
2321

24-
/// Result of a workspace operation that affected a tracked file.
25-
#[derive(Clone)]
26-
pub enum WorkspaceFileEvent {
27-
Created { file: File, path: Utf8PathBuf },
28-
Updated { file: File, path: Utf8PathBuf },
29-
}
30-
31-
impl WorkspaceFileEvent {
32-
#[must_use]
33-
pub fn file(&self) -> File {
34-
match self {
35-
Self::Created { file, .. } | Self::Updated { file, .. } => *file,
36-
}
37-
}
38-
39-
#[must_use]
40-
pub fn path(&self) -> &Utf8Path {
41-
match self {
42-
Self::Created { path, .. } | Self::Updated { path, .. } => path.as_path(),
43-
}
44-
}
45-
}
4622
/// Workspace facade that manages buffers and file system.
4723
///
4824
/// This struct provides a unified interface for managing document buffers
@@ -83,13 +59,19 @@ impl Workspace {
8359
&self.buffers
8460
}
8561

62+
/// Get a document from the buffer if it's open.
63+
#[must_use]
64+
pub fn get_document(&self, url: &Url) -> Option<TextDocument> {
65+
self.buffers.get(url)
66+
}
67+
8668
/// Open a document in the workspace and ensure a corresponding Salsa file exists.
8769
pub fn open_document(
8870
&mut self,
8971
db: &mut dyn Db,
9072
url: &Url,
9173
document: TextDocument,
92-
) -> Option<WorkspaceFileEvent> {
74+
) -> Option<File> {
9375
self.buffers.open(url.clone(), document);
9476
self.ensure_and_touch(db, url)
9577
}
@@ -102,7 +84,7 @@ impl Workspace {
10284
changes: Vec<TextDocumentContentChangeEvent>,
10385
version: i32,
10486
encoding: PositionEncoding,
105-
) -> Option<WorkspaceFileEvent> {
87+
) -> Option<File> {
10688
if let Some(mut document) = self.buffers.get(url) {
10789
document.update(changes, version, encoding);
10890
self.buffers.update(url.clone(), document);
@@ -120,25 +102,8 @@ impl Workspace {
120102
self.ensure_and_touch(db, url)
121103
}
122104

123-
/// Ensure a file is tracked in Salsa and report its state.
124-
pub fn track_file(&self, db: &mut dyn Db, path: &Utf8Path) -> WorkspaceFileEvent {
125-
let path_buf = path.to_owned();
126-
let (file, existed) = db.intern_file(path);
127-
if existed {
128-
WorkspaceFileEvent::Updated {
129-
file,
130-
path: path_buf,
131-
}
132-
} else {
133-
WorkspaceFileEvent::Created {
134-
file,
135-
path: path_buf,
136-
}
137-
}
138-
}
139-
140105
/// Touch the tracked file when the client saves the document.
141-
pub fn save_document(&mut self, db: &mut dyn Db, url: &Url) -> Option<WorkspaceFileEvent> {
106+
pub fn save_document(&mut self, db: &mut dyn Db, url: &Url) -> Option<File> {
142107
self.ensure_and_touch(db, url)
143108
}
144109

@@ -155,21 +120,11 @@ impl Workspace {
155120
closed
156121
}
157122

158-
/// Get a document from the buffer if it's open.
159-
#[must_use]
160-
pub fn get_document(&self, url: &Url) -> Option<TextDocument> {
161-
self.buffers.get(url)
162-
}
163-
164-
pub fn ensure_and_touch(&self, db: &mut dyn Db, url: &Url) -> Option<WorkspaceFileEvent> {
165-
self.ensure_file_for_url(db, url).inspect(|event| {
166-
db.touch_file(event.file());
167-
})
168-
}
169-
170-
fn ensure_file_for_url(&self, db: &mut dyn Db, url: &Url) -> Option<WorkspaceFileEvent> {
123+
fn ensure_and_touch(&self, db: &mut dyn Db, url: &Url) -> Option<File> {
171124
let path = paths::url_to_path(url)?;
172-
Some(self.track_file(db, path.as_path()))
125+
let file = db.track_file(path.as_path());
126+
db.touch_file(file);
127+
Some(file)
173128
}
174129
}
175130

@@ -399,14 +354,14 @@ mod tests {
399354
self.fs.clone()
400355
}
401356

402-
fn intern_file(&mut self, path: &Utf8Path) -> (File, bool) {
357+
fn track_file(&mut self, path: &Utf8Path) -> File {
403358
if let Some(entry) = self.files.get(path) {
404-
return (*entry, true);
359+
return *entry;
405360
}
406361

407362
let file = File::new(self, path.to_owned(), 0);
408363
self.files.insert(path.to_owned(), file);
409-
(file, false)
364+
file
410365
}
411366

412367
fn get_file(&self, path: &Utf8Path) -> Option<File> {
@@ -421,14 +376,9 @@ mod tests {
421376
let url = Url::parse("file:///test.py").unwrap();
422377

423378
let document = TextDocument::new("print('hello')".to_string(), 1, LanguageId::Python);
424-
let event = workspace.open_document(&mut db, &url, document).unwrap();
425-
426-
match event {
427-
WorkspaceFileEvent::Created { ref path, .. } => {
428-
assert_eq!(path.file_name(), Some("test.py"));
429-
}
430-
WorkspaceFileEvent::Updated { .. } => panic!("expected created event"),
431-
}
379+
let file = workspace.open_document(&mut db, &url, document).unwrap();
380+
let path = file.path(&db);
381+
assert_eq!(path.file_name(), Some("test.py"));
432382
assert!(workspace.buffers.get(&url).is_some());
433383
}
434384

@@ -446,11 +396,11 @@ mod tests {
446396
range_length: None,
447397
text: "updated".to_string(),
448398
}];
449-
let event = workspace
399+
let file = workspace
450400
.update_document(&mut db, &url, changes, 2, PositionEncoding::Utf16)
451401
.unwrap();
452402

453-
assert!(matches!(event, WorkspaceFileEvent::Updated { .. }));
403+
assert_eq!(file.path(&db).file_name(), Some("test.py"));
454404
let buffer = workspace.buffers.get(&url).unwrap();
455405
assert_eq!(buffer.content(), "updated");
456406
assert_eq!(buffer.version(), 2);
@@ -502,10 +452,9 @@ mod tests {
502452
let url = Url::from_file_path(file_path.as_std_path()).unwrap();
503453

504454
let document = TextDocument::new("line1\nline2".to_string(), 1, LanguageId::HtmlDjango);
505-
let event = workspace
455+
let file = workspace
506456
.open_document(&mut db, &url, document.clone())
507457
.unwrap();
508-
let file = event.file();
509458

510459
let source = file.source(&db);
511460
assert_eq!(source.as_str(), document.content());
@@ -532,8 +481,7 @@ mod tests {
532481
let url = Url::from_file_path(file_path.as_std_path()).unwrap();
533482

534483
let document = TextDocument::new("initial".to_string(), 1, LanguageId::Python);
535-
let event = workspace.open_document(&mut db, &url, document).unwrap();
536-
let file = event.file();
484+
let file = workspace.open_document(&mut db, &url, document).unwrap();
537485

538486
let changes = vec![TextDocumentContentChangeEvent {
539487
range: None,
@@ -559,8 +507,7 @@ mod tests {
559507
let url = Url::from_file_path(file_path.as_std_path()).unwrap();
560508

561509
let document = TextDocument::new("buffer content".to_string(), 1, LanguageId::Python);
562-
let event = workspace.open_document(&mut db, &url, document).unwrap();
563-
let file = event.file();
510+
let file = workspace.open_document(&mut db, &url, document).unwrap();
564511

565512
assert_eq!(file.source(&db).as_str(), "buffer content");
566513

0 commit comments

Comments
 (0)