Skip to main content

swls_core/feature/
references.rs

1use crate::lsp_types::Location;
2use bevy_ecs::{
3    component::Component,
4    schedule::{IntoScheduleConfigs, Schedule, ScheduleLabel},
5    world::World,
6};
7
8pub use crate::util::{token::get_current_token, triple::get_current_triple};
9
10/// [`Component`] indicating that the current document is currently handling a References request.
11#[derive(Component, Debug, Default)]
12pub struct ReferencesRequest(pub Vec<Location>);
13
14/// [`ScheduleLabel`] related to the Parse schedule
15#[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_token,
22        get_current_triple.after(get_current_token),
23        system::add_references.after(get_current_triple),
24    ));
25    world.add_schedule(references);
26}
27
28mod system {
29    use bevy_ecs::prelude::*;
30    use references::ReferencesRequest;
31    use sophia_api::term::TermKind;
32
33    use crate::{prelude::*, util::token_to_location};
34
35    pub fn add_references(
36        mut query: Query<(
37            &TokenComponent,
38            &TripleComponent,
39            &Tokens,
40            &Label,
41            &RopeC,
42            &Prefixes,
43            &mut ReferencesRequest,
44        )>,
45        project: Query<(&Tokens, &RopeC, &Label, &Prefixes)>,
46    ) {
47        for (token, triple, tokens, label, rope, prefixes, mut req) in &mut query {
48            let target = triple.kind();
49            tracing::info!("Found {} with kind {:?}", token.text, target);
50            let expanded = prefixes.expand(&token.token);
51            if target == TermKind::Iri {
52                for (tokens, rope, label, prefixes) in &project {
53                    req.0.extend(
54                        tokens
55                            .iter()
56                            .filter(|x| prefixes.expand(&x) == expanded)
57                            .flat_map(|t| token_to_location(t.span(), label, &rope)),
58                    );
59                }
60            } else if target == TermKind::BlankNode {
61                // Blank node is constrained to current
62                // document
63                req.0.extend(
64                    tokens
65                        .iter()
66                        .filter(|x| x.value() == token.token.value())
67                        .flat_map(|t| token_to_location(t.span(), label, &rope)),
68                );
69            }
70        }
71    }
72}