use ll_sparql_parser::ast::{AstNode, Iri, PrefixDeclaration, Prologue, QueryUnit};
use super::{
Server,
lsp::errors::{ErrorCode, LSPError},
state::ServerState,
};
pub fn namespace_is_declared(
server_state: &ServerState,
document_uri: &str,
namespace: &str,
) -> Result<bool, LSPError> {
Ok(find_all_prefix_declarations(server_state, document_uri)?
.iter()
.any(|node| node.prefix().is_some_and(|prefix| prefix == namespace)))
}
pub fn find_all_uncompacted_iris(
server: &Server,
document_uri: &str,
) -> Result<Vec<Iri>, LSPError> {
let root = server.state.get_cached_parse_tree(document_uri)?.tree;
let query_unit = QueryUnit::cast(root).ok_or(LSPError::new(
ErrorCode::InternalError,
"find_all_uncompacted_uris is not jet supported for update",
))?;
Ok(query_unit
.prologue()
.and_then(|prologue| prologue.syntax().next_sibling())
.or(Some(query_unit.syntax().clone()))
.map(|node| {
node.descendants()
.filter_map(Iri::cast)
.filter(|iri| iri.is_uncompressed())
.collect()
})
.unwrap_or_default())
}
pub(crate) fn find_all_prefix_declarations(
server_state: &ServerState,
document_uri: &str,
) -> Result<Vec<PrefixDeclaration>, LSPError> {
let root = server_state.get_cached_parse_tree(document_uri)?.tree;
Ok(root
.first_child()
.and_then(|child| child.first_child())
.and_then(Prologue::cast)
.map(|prologue| prologue.prefix_declarations())
.unwrap_or_default())
}
#[cfg(test)]
mod tests {
use indoc::indoc;
use crate::server::{
Server,
analysis::{find_all_prefix_declarations, find_all_uncompacted_iris},
lsp::textdocument::TextDocumentItem,
state::ServerState,
};
fn setup_state(text: &str) -> ServerState {
let mut state = ServerState::new();
let document = TextDocumentItem::new("uri", text);
state.add_document(document);
state
}
#[test]
fn test_find_all_uncompacted_iris() {
let mut server = Server::new(|_message| {});
let state = setup_state(indoc!(
"SELECT * {
?a <https://schema.org/name> ?b .
?c <https://schema.org/name> ?d
}"
));
server.state = state;
let uncompacted_iris = find_all_uncompacted_iris(&server, "uri").unwrap();
assert_eq!(
uncompacted_iris
.into_iter()
.map(|iri| iri.raw_iri().unwrap())
.collect::<Vec<_>>(),
vec!["https://schema.org/name", "https://schema.org/name"]
);
}
#[test]
fn declared_namespaces() {
let state = setup_state(indoc!(
"PREFIX wdt: <iri>
PREFIX wd: <iri>
PREFIX wdt: <iri>
SELECT * {}"
));
let declared_namespaces = find_all_prefix_declarations(&state, "uri").unwrap();
assert_eq!(
declared_namespaces
.iter()
.filter_map(|prefix_declaration| prefix_declaration.prefix())
.collect::<Vec<_>>(),
vec!["wdt", "wd", "wdt"]
);
}
}