swls_core/feature/
references.rs1use bevy_ecs::{
2 component::Component,
3 schedule::{IntoScheduleConfigs, Schedule, ScheduleLabel},
4 world::World,
5};
6
7use crate::lsp_types::Location;
8pub use crate::util::triple::get_current_triple;
9
10#[derive(Component, Debug, Default)]
12pub struct ReferencesRequest(pub Vec<Location>);
13
14#[derive(ScheduleLabel, Clone, Eq, PartialEq, Debug, Hash)]
16pub struct Label;
17
18pub fn setup_schedule(world: &mut World) {
19 let mut references = Schedule::new(Label);
20 references.add_systems((
21 get_current_triple,
22 system::add_references.after(get_current_triple),
23 ));
24 world.add_schedule(references);
25}
26
27mod system {
28 use bevy_ecs::prelude::*;
29 use references::ReferencesRequest;
30 use sophia_api::{quad::Quad as _, term::TermKind};
31
32 use crate::{prelude::*, util::token_to_location};
33
34 pub fn add_references(
35 mut query: Query<(
36 &TripleComponent,
37 &Triples,
38 &Label,
39 &RopeC,
40 &mut ReferencesRequest,
41 )>,
42 project: Query<(&Triples, &RopeC, &Label)>,
43 ) {
44 for (triple, triples, label, rope, mut req) in &mut query {
45 let target = triple.kind();
46 let Some(term) = triple.term() else { continue };
47 tracing::debug!("Found term '{}' with kind {:?}", term.value, target);
48
49 if target == TermKind::Iri {
50 for (proj_triples, proj_rope, proj_label) in &project {
51 req.0.extend(
52 proj_triples
53 .0
54 .iter()
55 .flat_map(|q| [q.s(), q.p(), q.o()])
56 .filter(|t| t == &term)
57 .flat_map(|t| token_to_location(&t.span, proj_label, proj_rope)),
58 );
59 }
60 } else if target == TermKind::BlankNode || target == TermKind::Variable {
61 req.0.extend(
63 triples
64 .0
65 .iter()
66 .flat_map(|q| [q.s(), q.p(), q.o()])
67 .filter(|t| t == &term)
68 .flat_map(|t| token_to_location(&t.span, label, rope)),
69 );
70 }
71 }
72 }
73}