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>;
47// pub type SyntaxElement = rowan::SyntaxElement<Sql>;
48pub type SyntaxNodeChildren = rowan::SyntaxNodeChildren<Sql>;
49// pub type SyntaxElementChildren = rowan::SyntaxElementChildren<Sql>;
50// pub type PreorderWithTokens = rowan::api::PreorderWithTokens<Sql>;
51
52#[derive(Default)]
53pub struct SyntaxTreeBuilder {
54 errors: Vec<SyntaxError>,
55 inner: GreenNodeBuilder<'static>,
56}
57
58impl SyntaxTreeBuilder {
59 pub(crate) fn finish_raw(self) -> (GreenNode, Vec<SyntaxError>) {
60 let green = self.inner.finish();
61 (green, self.errors)
62 }
63
64 // pub fn finish(self) -> Parse<SyntaxNode> {
65 // let (green, errors) = self.finish_raw();
66 // // // Disable block validation, see https://github.com/rust-lang/rust-analyzer/pull/10357
67 // // #[allow(clippy::overly_complex_bool_expr)]
68 // // if cfg!(debug_assertions) && false {
69 // // let node = SyntaxNode::new_root(green.clone());
70 // // crate::validation::validate_block_structure(&node);
71 // // }
72 // Parse::new(green, errors)
73 // }
74
75 pub fn token(&mut self, kind: SyntaxKind, text: &str) {
76 let kind = Sql::kind_to_raw(kind);
77 self.inner.token(kind, text);
78 }
79
80 pub fn start_node(&mut self, kind: SyntaxKind) {
81 let kind = Sql::kind_to_raw(kind);
82 self.inner.start_node(kind);
83 }
84
85 pub fn finish_node(&mut self) {
86 self.inner.finish_node();
87 }
88
89 pub fn error(&mut self, error: String, text_pos: TextSize) {
90 self.errors
91 .push(SyntaxError::new_at_offset(error, text_pos));
92 }
93}