Skip to content
This repository was archived by the owner on Sep 9, 2025. It is now read-only.

Commit cd09f9d

Browse files
oppiliappanHendrik van Antwerpen
authored andcommitted
address review comments
- refactor serde module - rename InvalidNodeID error variant - better variable names in loops - reduce error handling code in `load_files` - delete old serialization code - serialize Position::containing_line and Position::trimmed_line
1 parent 48dbe52 commit cd09f9d

File tree

7 files changed

+461
-284
lines changed

7 files changed

+461
-284
lines changed

lsp-positions/src/lib.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,9 @@ pub struct Position {
5353
pub column: Offset,
5454
/// The UTF-8 byte indexes (within the file) of the start and end of the line containing the
5555
/// character
56-
#[cfg_attr(feature = "serde", serde(skip))]
5756
pub containing_line: Range<usize>,
5857
/// The UTF-8 byte indexes (within the file) of the start and end of the line containing the
5958
/// character, with any leading and trailing whitespace removed
60-
#[cfg_attr(feature = "serde", serde(skip))]
6159
pub trimmed_line: Range<usize>,
6260
}
6361

stack-graphs/src/json.rs

Lines changed: 1 addition & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
// Please see the LICENSE-APACHE or LICENSE-MIT files in this distribution for license details.
66
// ------------------------------------------------------------------------------------------------
77

8-
use itertools::Itertools;
98
use lsp_positions::Offset;
109
use lsp_positions::Position;
1110
use lsp_positions::Span;
@@ -35,60 +34,14 @@ use crate::partial::PartialScopedSymbol;
3534
use crate::partial::PartialSymbolStack;
3635
use crate::partial::ScopeStackVariable;
3736
use crate::partial::SymbolStackVariable;
37+
use crate::serde::ImplicationFilter;
3838
pub use crate::serde::{Filter, NoFilter};
3939
use crate::stitching::Database;
4040

4141
#[derive(Debug, Error)]
4242
#[error(transparent)]
4343
pub struct JsonError(#[from] serde_json::error::Error);
4444

45-
/// Filter implementation that enforces all implications of another filter.
46-
/// For example, that nodes frome excluded files are not included, etc.
47-
pub(crate) struct ImplicationFilter<'a>(pub &'a dyn Filter);
48-
49-
impl Filter for ImplicationFilter<'_> {
50-
fn include_file(&self, graph: &StackGraph, file: &Handle<File>) -> bool {
51-
self.0.include_file(graph, file)
52-
}
53-
54-
fn include_node(&self, graph: &StackGraph, node: &Handle<Node>) -> bool {
55-
graph[*node]
56-
.id()
57-
.file()
58-
.map_or(true, |f| self.include_file(graph, &f))
59-
&& self.0.include_node(graph, node)
60-
}
61-
62-
fn include_edge(&self, graph: &StackGraph, source: &Handle<Node>, sink: &Handle<Node>) -> bool {
63-
self.include_node(graph, source)
64-
&& self.include_node(graph, sink)
65-
&& self.0.include_edge(graph, source, sink)
66-
}
67-
68-
fn include_partial_path(
69-
&self,
70-
graph: &StackGraph,
71-
paths: &PartialPaths,
72-
path: &PartialPath,
73-
) -> bool {
74-
let super_ok = self.0.include_partial_path(graph, paths, path);
75-
if !super_ok {
76-
return false;
77-
}
78-
let all_included_edges = path
79-
.edges
80-
.iter_unordered(paths)
81-
.map(|e| graph.node_for_id(e.source_node_id).unwrap())
82-
.chain(std::iter::once(path.end_node))
83-
.tuple_windows()
84-
.all(|(source, sink)| self.include_edge(graph, &source, &sink));
85-
if !all_included_edges {
86-
return false;
87-
}
88-
true
89-
}
90-
}
91-
9245
//-----------------------------------------------------------------------------
9346
// InStackGraph
9447

@@ -107,61 +60,6 @@ impl<'a, T> InStackGraph<'a, T> {
10760
}
10861
}
10962

110-
//-----------------------------------------------------------------------------
111-
// StackGraph
112-
113-
impl<'a> StackGraph {
114-
pub fn to_json(&'a self, f: &'a dyn Filter) -> JsonStackGraph {
115-
JsonStackGraph(self, f)
116-
}
117-
118-
pub fn to_serializable(&self) -> crate::serde::StackGraph {
119-
self.to_serializable_filter(&NoFilter)
120-
}
121-
122-
pub fn to_serializable_filter(&self, f: &'a dyn Filter) -> crate::serde::StackGraph {
123-
crate::serde::StackGraph::from_graph_filter(self, f)
124-
}
125-
}
126-
127-
pub struct JsonStackGraph<'a>(&'a StackGraph, &'a dyn Filter);
128-
129-
impl<'a> JsonStackGraph<'a> {
130-
pub fn to_value(&self) -> Result<Value, JsonError> {
131-
Ok(serde_json::to_value(self)?)
132-
}
133-
134-
pub fn to_string(&self) -> Result<String, JsonError> {
135-
Ok(serde_json::to_string(self)?)
136-
}
137-
138-
pub fn to_string_pretty(&self) -> Result<String, JsonError> {
139-
Ok(serde_json::to_string_pretty(self)?)
140-
}
141-
}
142-
143-
impl Serialize for JsonStackGraph<'_> {
144-
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
145-
where
146-
S: Serializer,
147-
{
148-
let mut ser = serializer.serialize_struct("stack_graph", 2)?;
149-
ser.serialize_field(
150-
"files",
151-
&InStackGraph(self.0, &Files, &ImplicationFilter(self.1)),
152-
)?;
153-
ser.serialize_field(
154-
"nodes",
155-
&InStackGraph(self.0, &Nodes, &ImplicationFilter(self.1)),
156-
)?;
157-
ser.serialize_field(
158-
"edges",
159-
&InStackGraph(self.0, &Edges, &ImplicationFilter(self.1)),
160-
)?;
161-
ser.end()
162-
}
163-
}
164-
16563
//-----------------------------------------------------------------------------
16664
// Files
16765

stack-graphs/src/serde/filter.rs

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
use crate::{
2+
arena::Handle,
3+
graph::{File, Node, StackGraph},
4+
partial::{PartialPath, PartialPaths},
5+
};
6+
use itertools::Itertools;
7+
8+
pub trait Filter {
9+
/// Return whether elements for the given file must be included.
10+
fn include_file(&self, graph: &StackGraph, file: &Handle<File>) -> bool;
11+
12+
/// Return whether the given node must be included.
13+
/// Nodes of excluded files are always excluded.
14+
fn include_node(&self, graph: &StackGraph, node: &Handle<Node>) -> bool;
15+
16+
/// Return whether the given edge must be included.
17+
/// Edges via excluded nodes are always excluded.
18+
fn include_edge(&self, graph: &StackGraph, source: &Handle<Node>, sink: &Handle<Node>) -> bool;
19+
20+
/// Return whether the given path must be included.
21+
/// Paths via excluded nodes or edges are always excluded.
22+
fn include_partial_path(
23+
&self,
24+
graph: &StackGraph,
25+
paths: &PartialPaths,
26+
path: &PartialPath,
27+
) -> bool;
28+
}
29+
30+
impl<F> Filter for F
31+
where
32+
F: Fn(&StackGraph, &Handle<File>) -> bool,
33+
{
34+
fn include_file(&self, graph: &StackGraph, file: &Handle<File>) -> bool {
35+
self(graph, file)
36+
}
37+
38+
fn include_node(&self, _graph: &StackGraph, _node: &Handle<Node>) -> bool {
39+
true
40+
}
41+
42+
fn include_edge(
43+
&self,
44+
_graph: &StackGraph,
45+
_source: &Handle<Node>,
46+
_sink: &Handle<Node>,
47+
) -> bool {
48+
true
49+
}
50+
51+
fn include_partial_path(
52+
&self,
53+
_graph: &StackGraph,
54+
_paths: &PartialPaths,
55+
_path: &PartialPath,
56+
) -> bool {
57+
true
58+
}
59+
}
60+
61+
// Filter implementation that includes everything.
62+
pub struct NoFilter;
63+
64+
impl Filter for NoFilter {
65+
fn include_file(&self, _graph: &StackGraph, _file: &Handle<File>) -> bool {
66+
true
67+
}
68+
69+
fn include_node(&self, _graph: &StackGraph, _node: &Handle<Node>) -> bool {
70+
true
71+
}
72+
73+
fn include_edge(
74+
&self,
75+
_graph: &StackGraph,
76+
_source: &Handle<Node>,
77+
_sink: &Handle<Node>,
78+
) -> bool {
79+
true
80+
}
81+
82+
fn include_partial_path(
83+
&self,
84+
_graph: &StackGraph,
85+
_paths: &PartialPaths,
86+
_path: &PartialPath,
87+
) -> bool {
88+
true
89+
}
90+
}
91+
92+
/// Filter implementation that enforces all implications of another filter.
93+
/// For example, that nodes frome excluded files are not included, etc.
94+
pub(crate) struct ImplicationFilter<'a>(pub &'a dyn Filter);
95+
96+
impl Filter for ImplicationFilter<'_> {
97+
fn include_file(&self, graph: &StackGraph, file: &Handle<File>) -> bool {
98+
self.0.include_file(graph, file)
99+
}
100+
101+
fn include_node(&self, graph: &StackGraph, node: &Handle<Node>) -> bool {
102+
graph[*node]
103+
.id()
104+
.file()
105+
.map_or(true, |f| self.include_file(graph, &f))
106+
&& self.0.include_node(graph, node)
107+
}
108+
109+
fn include_edge(&self, graph: &StackGraph, source: &Handle<Node>, sink: &Handle<Node>) -> bool {
110+
self.include_node(graph, source)
111+
&& self.include_node(graph, sink)
112+
&& self.0.include_edge(graph, source, sink)
113+
}
114+
115+
fn include_partial_path(
116+
&self,
117+
graph: &StackGraph,
118+
paths: &PartialPaths,
119+
path: &PartialPath,
120+
) -> bool {
121+
let super_ok = self.0.include_partial_path(graph, paths, path);
122+
if !super_ok {
123+
return false;
124+
}
125+
let all_included_edges = path
126+
.edges
127+
.iter_unordered(paths)
128+
.map(|e| graph.node_for_id(e.source_node_id).unwrap())
129+
.chain(std::iter::once(path.end_node))
130+
.tuple_windows()
131+
.all(|(source, sink)| self.include_edge(graph, &source, &sink));
132+
if !all_included_edges {
133+
return false;
134+
}
135+
true
136+
}
137+
}

0 commit comments

Comments
 (0)