Skip to main content

squawk_ide/
location.rs

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    AccessMethod,
14    Aggregate,
15    CaseExpr,
16    Channel,
17    Collation,
18    Column,
19    CommitBegin,
20    CommitEnd,
21    Constraint,
22    Conversion,
23    Cursor,
24    Database,
25    EventTrigger,
26    Extension,
27    ElementTable,
28    ForeignDataWrapper,
29    Function,
30    Index,
31    JsonPath,
32    Label,
33    Language,
34    NamedArgParameter,
35    Operator,
36    OperatorClass,
37    OperatorFamily,
38    Policy,
39    PreparedStatement,
40    Procedure,
41    Property,
42    PropertyGraph,
43    Publication,
44    Role,
45    Rule,
46    Savepoint,
47    Schema,
48    Sequence,
49    Server,
50    Statistics,
51    Subscription,
52    Table,
53    Tablespace,
54    TextSearchConfiguration,
55    TextSearchDictionary,
56    TextSearchParser,
57    TextSearchTemplate,
58    Trigger,
59    Type,
60    View,
61    Window,
62}
63
64#[derive(Clone, Copy, PartialEq, Eq)]
65pub struct Location {
66    pub file: File,
67    pub range: TextRange,
68    pub kind: LocationKind,
69}
70
71impl Location {
72    pub(crate) fn new(file: File, range: TextRange, kind: LocationKind) -> Location {
73        Location { file, range, kind }
74    }
75
76    pub(crate) fn from_node(file: File, node: &SyntaxNode) -> Option<Location> {
77        let kind = classify_def_node(node)?;
78        Some(Location::new(file, node.text_range(), kind))
79    }
80
81    pub(crate) fn to_node(self, db: &dyn Db) -> Option<SyntaxNode> {
82        let tree = parse(db, self.file).tree();
83        match tree.syntax().covering_element(self.range) {
84            rowan::NodeOrToken::Token(token) => token.parent(),
85            rowan::NodeOrToken::Node(node) => Some(node.clone()),
86        }
87    }
88}