squawk_syntax/
syntax_node.rs

1// via https://github.com/rust-lang/rust-analyzer/blob/d8887c0758bbd2d5f752d5bd405d4491e90e7ed6/crates/syntax/src/syntax_node.rs
2//
3// Permission is hereby granted, free of charge, to any
4// person obtaining a copy of this software and associated
5// documentation files (the "Software"), to deal in the
6// Software without restriction, including without
7// limitation the rights to use, copy, modify, merge,
8// publish, distribute, sublicense, and/or sell copies of
9// the Software, and to permit persons to whom the Software
10// is furnished to do so, subject to the following
11// conditions:
12//
13// The above copyright notice and this permission notice
14// shall be included in all copies or substantial portions
15// of the Software.
16//
17// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
18// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
19// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
20// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
21// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
22// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
24// IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25// DEALINGS IN THE SOFTWARE.
26
27use rowan::{GreenNode, GreenNodeBuilder, Language, TextSize};
28
29use crate::{SyntaxKind, syntax_error::SyntaxError};
30
31#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
32pub enum Sql {}
33impl Language for Sql {
34    type Kind = SyntaxKind;
35
36    fn kind_from_raw(raw: rowan::SyntaxKind) -> SyntaxKind {
37        SyntaxKind::from(raw.0)
38    }
39
40    fn kind_to_raw(kind: SyntaxKind) -> rowan::SyntaxKind {
41        rowan::SyntaxKind(kind.into())
42    }
43}
44
45pub type SyntaxNode = rowan::SyntaxNode<Sql>;
46pub type SyntaxToken = rowan::SyntaxToken<Sql>;
47pub type SyntaxNodePtr = rowan::ast::SyntaxNodePtr<Sql>;
48// pub type SyntaxElement = rowan::SyntaxElement<Sql>;
49pub type SyntaxNodeChildren = rowan::SyntaxNodeChildren<Sql>;
50// pub type SyntaxElementChildren = rowan::SyntaxElementChildren<Sql>;
51// pub type PreorderWithTokens = rowan::api::PreorderWithTokens<Sql>;
52
53#[derive(Default)]
54pub struct SyntaxTreeBuilder {
55    errors: Vec<SyntaxError>,
56    inner: GreenNodeBuilder<'static>,
57}
58
59impl SyntaxTreeBuilder {
60    pub(crate) fn finish_raw(self) -> (GreenNode, Vec<SyntaxError>) {
61        let green = self.inner.finish();
62        (green, self.errors)
63    }
64
65    // pub fn finish(self) -> Parse<SyntaxNode> {
66    //     let (green, errors) = self.finish_raw();
67    //     // // Disable block validation, see https://github.com/rust-lang/rust-analyzer/pull/10357
68    //     // #[allow(clippy::overly_complex_bool_expr)]
69    //     // if cfg!(debug_assertions) && false {
70    //     //     let node = SyntaxNode::new_root(green.clone());
71    //     //     crate::validation::validate_block_structure(&node);
72    //     // }
73    //     Parse::new(green, errors)
74    // }
75
76    pub fn token(&mut self, kind: SyntaxKind, text: &str) {
77        let kind = Sql::kind_to_raw(kind);
78        self.inner.token(kind, text);
79    }
80
81    pub fn start_node(&mut self, kind: SyntaxKind) {
82        let kind = Sql::kind_to_raw(kind);
83        self.inner.start_node(kind);
84    }
85
86    pub fn finish_node(&mut self) {
87        self.inner.finish_node();
88    }
89
90    pub fn error(&mut self, error: String, text_pos: TextSize) {
91        self.errors
92            .push(SyntaxError::new_at_offset(error, text_pos));
93    }
94}