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