1use rowan::TextRange;
2use salsa::Database as Db;
3use squawk_syntax::SyntaxNode;
4use squawk_syntax::ast::AstNode;
5
6use crate::{
7 classify::classify_def_node,
8 db::{File, parse},
9};
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12pub enum LocationKind {
13 Aggregate,
14 CaseExpr,
15 Channel,
16 Column,
17 CommitBegin,
18 CommitEnd,
19 Cursor,
20 Database,
21 EventTrigger,
22 Extension,
23 Function,
24 Index,
25 NamedArgParameter,
26 Policy,
27 PreparedStatement,
28 Procedure,
29 PropertyGraph,
30 Role,
31 Schema,
32 Sequence,
33 Server,
34 Table,
35 Tablespace,
36 Trigger,
37 Type,
38 View,
39 Window,
40}
41
42#[derive(Clone, Copy, PartialEq, Eq)]
43pub struct Location {
44 pub file: File,
45 pub range: TextRange,
46 pub kind: LocationKind,
47}
48
49impl Location {
50 pub(crate) fn new(file: File, range: TextRange, kind: LocationKind) -> Location {
51 Location { file, range, kind }
52 }
53
54 pub(crate) fn from_node(file: File, node: &SyntaxNode) -> Option<Location> {
55 let kind = classify_def_node(node)?;
56 Some(Location::new(file, node.text_range(), kind))
57 }
58
59 pub(crate) fn to_node(self, db: &dyn Db) -> Option<SyntaxNode> {
60 let tree = parse(db, self.file).tree();
61 match tree.syntax().covering_element(self.range) {
62 rowan::NodeOrToken::Token(token) => token.parent(),
63 rowan::NodeOrToken::Node(node) => Some(node.clone()),
64 }
65 }
66}