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}