swls_core/systems/properties/
systems.rs1use std::{borrow::Cow, collections::HashSet};
2
3use bevy_ecs::prelude::*;
4use completion::{CompletionRequest, SimpleCompletion};
5use hover::HoverRequest;
6use tracing::{instrument, trace};
7
8use crate::{
9 lsp_types::{CompletionItemKind, TextEdit},
10 prelude::*,
11};
12
13#[instrument(skip(query, resource))]
14pub fn complete_class(
15 mut query: Query<(
16 &TokenComponent,
17 &TripleComponent,
18 &Prefixes,
19 &Types,
20 &mut CompletionRequest,
21 )>,
22 hierarchy: Res<TypeHierarchy<'static>>,
23 resource: Res<Ontologies>,
24) {
25 for (token, triple, prefixes, types, mut request) in &mut query {
26 if triple.triple.predicate.value == "http://www.w3.org/1999/02/22-rdf-syntax-ns#type"
27 && triple.target == TripleTarget::Object
28 {
29 let tts = types.get(&triple.triple.subject.value);
30
31 let superclasses: HashSet<_> = tts
32 .iter()
33 .flat_map(|x| x.iter())
34 .flat_map(|t| hierarchy.iter_superclass(*t))
35 .collect();
36
37 for class in resource.classes.values() {
38 let to_beat = prefixes
39 .shorten(&class.term.value)
40 .map(|x| Cow::Owned(x))
41 .unwrap_or(class.term.value.clone());
42
43 if to_beat.starts_with(&token.text) {
44 let mut completion = SimpleCompletion::new(
45 CompletionItemKind::CLASS,
46 format!("{}", to_beat),
47 TextEdit {
48 range: token.range.clone(),
49 new_text: to_beat.to_string(),
50 },
51 )
52 .label_description(class.full_title())
53 .documentation(class.full_docs(&hierarchy, &prefixes));
54
55 if superclasses.contains(class.term.as_str()) {
56 completion.kind = CompletionItemKind::INTERFACE;
57 request.push(completion.sort_text(format!("0{}", to_beat)));
58 } else {
59 request.push(completion.sort_text(format!("1{}", to_beat)));
60 }
61 }
62 }
63 }
64 }
65}
66
67pub fn hover_class(
68 mut query: Query<(&TokenComponent, &Prefixes, &mut HoverRequest)>,
69 hierarchy: Res<TypeHierarchy<'static>>,
70 resource: Res<Ontologies>,
71) {
72 for (token, prefixes, mut request) in &mut query {
73 if let Some(target) = prefixes.expand(token.token.value()) {
74 for class in resource.classes.values() {
75 if class.term.value == target {
76 request.0.push(format!(
77 "## {}\n\n{}",
78 class.full_title(),
79 class.full_docs(&hierarchy, &prefixes)
80 ));
81 }
82 }
83 }
84 }
85}
86
87#[instrument(skip(query, hierarchy, resource, config))]
88pub fn complete_properties(
89 mut query: Query<(
90 &TokenComponent,
91 &TripleComponent,
92 &Prefixes,
93 &Label,
94 &Types,
95 &mut CompletionRequest,
96 )>,
97 hierarchy: Res<TypeHierarchy<'static>>,
98 resource: Res<Ontologies>,
99 config: Res<ServerConfig>,
100) {
101 for (token, triple, prefixes, _this_label, types, mut request) in &mut query {
102 if triple.target == TripleTarget::Predicate {
103 let tts = types.get(&triple.triple.subject.value);
104
105 if let Some(tts) = tts.as_ref() {
106 trace!("Types for {}", triple.triple.subject.value);
107 for t in *tts {
108 trace!(
109 "{} {}",
110 triple.triple.subject.value,
111 hierarchy.type_name(*t)
112 );
113 }
114 } else {
115 trace!("No types for {}", triple.triple.subject.value);
116 }
117
118 let subclasses: HashSet<_> = tts
119 .iter()
120 .flat_map(|x| x.iter())
121 .flat_map(|t| hierarchy.iter_subclass(*t))
122 .collect();
123
124 for property in resource.properties.values() {
125 let correct_domain = property
126 .domains
127 .iter()
128 .any(|domain| subclasses.contains(domain.as_str()));
129
130 if !subclasses.is_empty()
131 && config
132 .config
133 .local
134 .completion
135 .correct_domain_required(&property.term.value)
136 && !correct_domain
137 {
138 continue;
139 }
140
141 let to_beat = prefixes
142 .shorten(&property.term.value)
143 .map(|x| Cow::Owned(x))
144 .unwrap_or(property.term.value.clone());
145
146 if to_beat.starts_with(&token.text) {
147 let mut completion = SimpleCompletion::new(
148 CompletionItemKind::ENUM_MEMBER,
149 format!("{}", to_beat),
150 TextEdit {
151 range: token.range.clone(),
152 new_text: to_beat.to_string(),
153 },
154 )
155 .label_description(&property.full_title())
156 .documentation(&property.full_docs(&prefixes));
157
158 if correct_domain {
159 completion.kind = CompletionItemKind::FIELD;
160 request.push(completion.sort_text(format!("0{}", to_beat)));
161 } else {
162 request.push(completion.sort_text(format!("1{}", to_beat)));
163 }
164 }
165 }
166 }
167 }
168}
169
170#[instrument(skip(query, resource))]
171pub fn hover_property(
172 mut query: Query<(
173 &TokenComponent,
174 &Prefixes,
175 &DocumentLinks,
176 &mut HoverRequest,
177 )>,
178 resource: Res<Ontologies>,
179) {
180 for (token, prefixes, _links, mut request) in &mut query {
181 if let Some(target) = prefixes.expand(token.token.value()) {
182 for c in resource
183 .properties
184 .values()
185 .filter(|c| c.term.value == target)
186 {
187 request
188 .0
189 .push(format!("## {}\n\n{}", c.full_title(), c.full_docs(&prefixes)));
190 }
191 }
192 }
193}