Skip to content
This repository was archived by the owner on Dec 29, 2022. It is now read-only.

Commit c165d39

Browse files
committed
Assert we don't get out of order change messages from the client
And that we don't screw it up with race conditions or whatever internally
1 parent 4340c2d commit c165d39

File tree

2 files changed

+24
-4
lines changed

2 files changed

+24
-4
lines changed

src/actions/mod.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,8 @@ pub struct InitActionContext {
125125
// mutating actions can block until the data is ready.
126126
active_build_count: Arc<AtomicUsize>,
127127

128+
prev_changes: Arc<Mutex<HashMap<PathBuf, u64>>>,
129+
128130
config: Arc<Mutex<Config>>,
129131
client_capabilities: Arc<lsp_data::ClientCapabilities>,
130132
/// Whether the server is performing cleanup (after having received
@@ -170,6 +172,7 @@ impl InitActionContext {
170172
current_project,
171173
previous_build_results: Arc::new(Mutex::new(HashMap::new())),
172174
build_queue,
175+
prev_changes: Arc::new(Mutex::new(HashMap::new())),
173176
active_build_count: Arc::new(AtomicUsize::new(0)),
174177
client_capabilities: Arc::new(client_capabilities),
175178
shut_down: Arc::new(AtomicBool::new(false)),
@@ -268,6 +271,18 @@ impl InitActionContext {
268271
self.active_build_count.load(Ordering::SeqCst) == 0
269272
}
270273

274+
fn check_change_version(&self, file_path: &Path, version_num: u64) {
275+
let mut prev_changes = self.prev_changes.lock().unwrap();
276+
let file_path = file_path.to_owned();
277+
278+
if prev_changes.contains_key(&file_path) {
279+
let prev_version = prev_changes[&file_path];
280+
assert!(version_num > prev_version, "Out of order or duplicate change");
281+
}
282+
283+
prev_changes.insert(file_path, version_num);
284+
}
285+
271286
fn convert_pos_to_span(&self, file_path: PathBuf, pos: Position) -> Span {
272287
trace!("convert_pos_to_span: {:?} {:?}", file_path, pos);
273288

src/actions/notifications.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,15 @@ impl BlockingNotificationAction for DidChangeTextDocument {
8282
thread::current().id()
8383
);
8484

85+
if params.content_changes.is_empty() {
86+
return Ok(());
87+
}
88+
8589
let ctx = ctx.inited();
8690
let file_path = parse_file_path!(&params.text_document.uri, "on_change")?;
91+
let version_num = params.text_document.version.unwrap();
92+
93+
ctx.check_change_version(&file_path, version_num);
8794

8895
let changes: Vec<Change> = params
8996
.content_changes
@@ -107,10 +114,8 @@ impl BlockingNotificationAction for DidChangeTextDocument {
107114
ctx.vfs
108115
.on_changes(&changes)
109116
.expect("error committing to VFS");
110-
if !changes.is_empty() {
111-
ctx.build_queue
112-
.mark_file_dirty(file_path, params.text_document.version.unwrap())
113-
}
117+
118+
ctx.build_queue.mark_file_dirty(file_path, version_num);
114119

115120
if !ctx.config.lock().unwrap().build_on_save {
116121
ctx.build_current_project(BuildPriority::Normal, &out);

0 commit comments

Comments
 (0)