Skip to content

Commit e22af33

Browse files
Clear diagnostics when document changes
1 parent 5c25a87 commit e22af33

4 files changed

Lines changed: 53 additions & 10 deletions

File tree

rust/rubydex/src/diagnostic.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::{model::ids::UriId, offset::Offset};
1+
use crate::{model::ids::{DiagnosticId, UriId}, offset::Offset};
22

33
#[derive(Debug)]
44
pub struct Diagnostic {
@@ -26,6 +26,11 @@ impl Diagnostic {
2626
Self::new(diagnostics.code(), uri_id, offset, message, diagnostics.severity())
2727
}
2828

29+
#[must_use]
30+
pub fn id(&self) -> DiagnosticId {
31+
DiagnosticId::from(&format!("{}{}{}", *self.uri_id, self.offset.start(), self.code))
32+
}
33+
2934
#[must_use]
3035
pub fn code(&self) -> u16 {
3136
self.code

rust/rubydex/src/model/document.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::model::ids::{DefinitionId, ReferenceId};
1+
use crate::model::ids::{DefinitionId, DiagnosticId, ReferenceId};
22

33
// Represents a document currently loaded into memory. Identified by its unique URI, it holds the edges to all
44
// definitions and references discovered in it
@@ -8,6 +8,7 @@ pub struct Document {
88
definition_ids: Vec<DefinitionId>,
99
method_reference_ids: Vec<ReferenceId>,
1010
constant_reference_ids: Vec<ReferenceId>,
11+
diagnostic_ids: Vec<DiagnosticId>,
1112
}
1213

1314
impl Document {
@@ -18,6 +19,7 @@ impl Document {
1819
definition_ids: Vec::new(),
1920
method_reference_ids: Vec::new(),
2021
constant_reference_ids: Vec::new(),
22+
diagnostic_ids: Vec::new(),
2123
}
2224
}
2325

@@ -57,6 +59,15 @@ impl Document {
5759
pub fn add_constant_reference(&mut self, reference_id: ReferenceId) {
5860
self.constant_reference_ids.push(reference_id);
5961
}
62+
63+
#[must_use]
64+
pub fn diagnostic_ids(&self) -> &[DiagnosticId] {
65+
&self.diagnostic_ids
66+
}
67+
68+
pub fn add_diagnostic_id(&mut self, diagnostic_id: DiagnosticId) {
69+
self.diagnostic_ids.push(diagnostic_id);
70+
}
6071
}
6172

6273
#[cfg(test)]

rust/rubydex/src/model/graph.rs

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::model::declaration::Declaration;
77
use crate::model::definitions::Definition;
88
use crate::model::document::Document;
99
use crate::model::identity_maps::IdentityHashMap;
10-
use crate::model::ids::{DeclarationId, DefinitionId, NameId, ReferenceId, StringId, UriId};
10+
use crate::model::ids::{DeclarationId, DefinitionId, DiagnosticId, NameId, ReferenceId, StringId, UriId};
1111
use crate::model::name::{NameRef, ResolvedName};
1212
// use crate::model::integrity::IntegrityChecker;
1313
use crate::model::references::{ConstantReference, MethodRef};
@@ -38,8 +38,7 @@ pub struct Graph {
3838
constant_references: IdentityHashMap<ReferenceId, ConstantReference>,
3939
// Map of method references that still need to be resolved
4040
method_references: IdentityHashMap<ReferenceId, MethodRef>,
41-
42-
diagnostics: Vec<Diagnostic>,
41+
diagnostics: IdentityHashMap<DiagnosticId, Diagnostic>,
4342
}
4443

4544
impl Graph {
@@ -54,7 +53,7 @@ impl Graph {
5453
names: IdentityHashMap::default(),
5554
constant_references: IdentityHashMap::default(),
5655
method_references: IdentityHashMap::default(),
57-
diagnostics: Vec::new(),
56+
diagnostics: IdentityHashMap::default(),
5857
}
5958
}
6059

@@ -162,8 +161,8 @@ impl Graph {
162161
}
163162

164163
#[must_use]
165-
pub fn diagnostics(&self) -> &Vec<Diagnostic> {
166-
&self.diagnostics
164+
pub fn diagnostics(&self) -> Vec<&Diagnostic> {
165+
self.diagnostics.values().collect()
167166
}
168167

169168
/// # Panics
@@ -266,16 +265,20 @@ impl Graph {
266265
/// Merges everything in `other` into this Graph. This method is meant to merge all graph representations from
267266
/// different threads, but not meant to handle updates to the existing global representation
268267
pub fn extend(&mut self, local_graph: LocalGraph) {
269-
let (uri_id, document, definitions, strings, names, constant_references, method_references, diagnostics) =
268+
let (uri_id, mut document, definitions, strings, names, constant_references, method_references, diagnostics) =
270269
local_graph.into_parts();
271270

271+
for diagnostic in diagnostics {
272+
document.add_diagnostic_id(diagnostic.id());
273+
self.diagnostics.insert(diagnostic.id(), diagnostic);
274+
}
275+
272276
self.documents.insert(uri_id, document);
273277
self.definitions.extend(definitions);
274278
self.strings.extend(strings);
275279
self.names.extend(names);
276280
self.constant_references.extend(constant_references);
277281
self.method_references.extend(method_references);
278-
self.diagnostics.extend(diagnostics);
279282
}
280283

281284
/// Updates the global representation with the information contained in `other`, handling deletions, insertions and
@@ -296,6 +299,10 @@ impl Graph {
296299
return;
297300
};
298301

302+
for diagnostic_id in document.diagnostic_ids() {
303+
self.diagnostics.remove(diagnostic_id);
304+
}
305+
299306
let mut write_lock = self.declarations.write().unwrap();
300307

301308
// TODO: Remove method references from method declarations once method inference is implemented
@@ -616,6 +623,21 @@ mod tests {
616623
context.graph().assert_integrity();
617624
}
618625

626+
#[test]
627+
fn updating_index_with_deleted_diagnostics() {
628+
let mut context = GraphTest::new();
629+
630+
context.index_uri("file:///foo.rb", "class Foo");
631+
assert!(!context.graph().diagnostics().is_empty());
632+
let document = context.graph().documents().get(&UriId::from("file:///foo.rb")).unwrap();
633+
assert!(!document.diagnostic_ids().is_empty());
634+
635+
context.index_uri("file:///foo.rb", "class Foo; end");
636+
assert!(context.graph().diagnostics().is_empty());
637+
let document = context.graph().documents().get(&UriId::from("file:///foo.rb")).unwrap();
638+
assert!(document.diagnostic_ids().is_empty());
639+
}
640+
619641
#[test]
620642
fn updating_index_with_new_definitions() {
621643
let mut context = GraphTest::new();

rust/rubydex/src/model/ids.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,8 @@ pub type ReferenceId = Id<ReferenceMarker>;
3030
pub struct NameMarker;
3131
/// `NameId` represents an ID for any constant name that we find as part of a reference or definition
3232
pub type NameId = Id<NameMarker>;
33+
34+
#[derive(PartialEq, Eq, Debug, Clone, Copy)]
35+
pub struct DiagnosticMarker;
36+
/// `DiagnosticId` represents the ID of a diagnostic found in a specific file
37+
pub type DiagnosticId = Id<DiagnosticMarker>;

0 commit comments

Comments
 (0)