lsp_core/feature/
references.rs

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