Skip to content

Commit 3ea0c89

Browse files
committed
add global shapes
1 parent c5dd419 commit 3ea0c89

6 files changed

Lines changed: 84 additions & 58 deletions

File tree

core/src/components.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ pub struct Open;
5959
#[derive(Component, Debug)]
6060
pub struct Dirty;
6161

62+
/// Indicates that this should be a global entity, linked to all other documents
63+
#[derive(Component, Debug)]
64+
pub struct Global;
65+
6266
/// [`Component`] containing the [`lsp_types::Url`] of the current document.
6367
#[derive(Component, AsRef, Deref, AsMut, DerefMut, Debug)]
6468
pub struct Label(pub crate::lsp_types::Url);

core/src/systems/lov.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ pub fn fetch_lov_properties<C: Client + Resource>(
213213
}
214214

215215
type Sender = futures::channel::mpsc::UnboundedSender<CommandQueue>;
216-
fn spawn_document(
216+
pub fn spawn_document(
217217
url: Url,
218218
content: String,
219219
sender: &Sender,
@@ -248,7 +248,6 @@ fn spawn_document(
248248
extra(e, world);
249249

250250
world.run_schedule(ParseLabel);
251-
drop(_enter);
252251
});
253252

254253
let _ = sender.unbounded_send(command_queue);

core/src/systems/shapes/data.rs

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -67,41 +67,6 @@ impl NeighsRDF for Rdf {
6767
P: srdf::matcher::Matcher<Self::IRI> + Clone,
6868
O: srdf::matcher::Matcher<Self::Term> + Clone,
6969
{
70-
if let Some(p) = predicate.value() {
71-
if p == MyTerm::named_node("http://www.w3.org/ns/shacl#minCount", 0..0) {
72-
tracing::debug!(
73-
"matching mincount {:?} {:?} {:?}",
74-
subject.value().map(|x| x.value),
75-
predicate.value().map(|x| x.value),
76-
object.value().map(|x| x.value)
77-
);
78-
let subject = subject.clone();
79-
let predicate = predicate.clone();
80-
let object = object.clone();
81-
for t in self.triples()?.filter_map(move |t| {
82-
match subject == t.subject && predicate == t.predicate && object == t.object {
83-
true => Some(t),
84-
false => {
85-
tracing::debug!(
86-
" NOT FOUND {:?} {:?} {:?}",
87-
t.subject.value,
88-
t.predicate.value,
89-
t.object.value
90-
);
91-
None
92-
}
93-
}
94-
}) {
95-
tracing::debug!(
96-
" FOUND {:?} {:?} {:?}",
97-
t.subject.value,
98-
t.predicate.value,
99-
t.object.value
100-
);
101-
}
102-
}
103-
}
104-
10570
let triples = self.triples()?.filter_map(move |triple| {
10671
match subject == triple.subject
10772
&& predicate == triple.predicate

core/src/systems/shapes/mod.rs

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ pub fn validate_shapes(
128128
),
129129
(Changed<Triples>, Without<Dirty>, With<Open>),
130130
>,
131-
other: Query<(&Label, &ShaclShapes, &Prefixes)>,
131+
other: Query<(&Label, &ShaclShapes, &Prefixes, Option<&Global>)>,
132132
mut client: ResMut<DiagnosticPublisher>,
133133
res: Res<ServerConfig>,
134134
) {
@@ -138,15 +138,16 @@ pub fn validate_shapes(
138138

139139
for (rope, label, links, item, triples) in &query {
140140
info!("Validate shapes {}", label.as_str());
141-
let other: &Query<(&Label, &ShaclShapes, &Prefixes)> = &other;
141+
let other: &Query<(&Label, &ShaclShapes, &Prefixes, Option<&Global>)> = &other;
142142
let client: &mut DiagnosticPublisher = &mut client;
143143
let mut diagnostics: Vec<crate::lsp_types::Diagnostic> = Vec::new();
144144

145-
for (other_label, schema, prefixes) in other {
146-
if links
147-
.iter()
148-
.find(|link| link.0.as_str().starts_with(other_label.0.as_str()))
149-
.is_none()
145+
for (other_label, schema, prefixes, global) in other {
146+
if global.is_none()
147+
&& links
148+
.iter()
149+
.find(|link| link.0.as_str().starts_with(other_label.0.as_str()))
150+
.is_none()
150151
&& label.0 != other_label.0
151152
{
152153
continue;
@@ -165,12 +166,8 @@ pub fn validate_shapes(
165166
let rdf = Rdf::new(triples);
166167
let ir = schema.ir();
167168
for (_, shape) in ir.iter_with_targets() {
168-
tracing::debug!("shape {}", shape.id());
169169
let results = match shape.validate(&rdf, &mut runner, None, Some(shape), ir) {
170-
Ok(r) => {
171-
tracing::debug!("results {}", r.len());
172-
r
173-
}
170+
Ok(r) => r,
174171
Err(e) => {
175172
tracing::debug!("errors {}", e);
176173
continue;

examples/example.ttl

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,5 @@
33
@prefix ex: <http://example.org/>.
44
@prefix : <http://example.org/>.
55

6-
:MinInclusive a sh:NodeShape;
7-
sh:targetClass :Node;
8-
sh:property [
9-
sh:path :p;
10-
sh:minCount 2;
11-
].
12-
136
<abc> a :Node.
147

lang-turtle/src/lib.rs

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use lov::LocalPrefix;
1818
use lsp_core::{
1919
feature::diagnostics::publish_diagnostics,
2020
lang::{Lang, LangHelper},
21-
lsp_types::{SemanticTokenType, Url},
21+
lsp_types::{SemanticTokenType, TextDocumentItem, Url},
2222
prelude::*,
2323
CreateEvent,
2424
};
@@ -73,7 +73,10 @@ pub fn setup_world<C: Client + ClientSync + Resource + Clone>(world: &mut World)
7373
});
7474

7575
world.schedule_scope(lsp_core::Startup, |_, schedule| {
76-
schedule.add_systems(extract_known_prefixes_from_config::<C>);
76+
schedule.add_systems((
77+
extract_known_prefixes_from_config::<C>,
78+
extract_known_shapes_from_config::<C>,
79+
));
7780
});
7881

7982
setup_parsing(world);
@@ -248,6 +251,71 @@ fn prefix_from_source(url: &Url, source: &str) -> Option<(Cow<'static, str>, Cow
248251
prefix_from_declaration(&triples).or_else(|| prefix_from_prefixes(&turtle, &triples))
249252
}
250253

254+
pub fn extract_known_shapes_from_config<C: Client + ClientSync + Resource + Clone>(
255+
config: Res<ServerConfig>,
256+
client: Res<C>,
257+
fs: Res<Fs>,
258+
sender: Res<CommandSender>,
259+
) {
260+
for on in config.config.local.shapes.iter().cloned() {
261+
let c = client.clone();
262+
let fs = fs.clone();
263+
264+
let sender = sender.0.clone();
265+
266+
let fut = async move {
267+
let Some(files) = find(&on, &fs, &c).await else {
268+
return;
269+
};
270+
271+
for (content, url) in files {
272+
let mut command_queue = CommandQueue::default();
273+
let item = TextDocumentItem {
274+
version: 1,
275+
uri: url.clone(),
276+
language_id: String::from("turtle"),
277+
text: String::new(),
278+
};
279+
280+
let spawn = spawn_or_insert(
281+
url.clone(),
282+
(
283+
RopeC(ropey::Rope::from_str(&content)),
284+
Source(content.clone()),
285+
Label(url.clone()), // this might crash
286+
Wrapped(item),
287+
Types(HashMap::new()),
288+
),
289+
Some("turtle".into()),
290+
(Global,),
291+
);
292+
293+
command_queue.push(move |world: &mut World| {
294+
let span = tracing::span!(tracing::Level::INFO, "span shapes");
295+
let _enter = span.enter();
296+
spawn(world);
297+
world.run_schedule(ParseLabel);
298+
});
299+
300+
let _ = sender.unbounded_send(command_queue);
301+
}
302+
303+
// This is the plan of approach: - add these ontologies to the predefined LOV things - need prefered prefix:
304+
// - filename.ttl -> filename
305+
// - parse and look for things?
306+
// - let the lov things also add prefixes to the prefix thing
307+
// - Profit
308+
309+
// spawn_or_insert(url, bundle, language_id, extra)
310+
// we have the turtle files!
311+
// we have 2 choices now:
312+
// add it to the ecs without links
313+
};
314+
315+
client.spawn(fut);
316+
}
317+
}
318+
251319
pub fn extract_known_prefixes_from_config<C: Client + ClientSync + Resource + Clone>(
252320
config: Res<ServerConfig>,
253321
client: Res<C>,

0 commit comments

Comments
 (0)