1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
use super::Token;
use df_ls_diagnostics::DiagnosticsInfo;
use df_ls_lexical_analysis::TreeCursor;
mod td_allow_empty;
mod td_any;
mod td_arg_n;
mod td_bang_arg_n;
mod td_bang_arg_n_seq;
mod td_bool;
mod td_char;
mod td_choose;
mod td_clamp;
mod td_df_char;
mod td_df_raw_file;
mod td_int;
mod td_option;
mod td_pipe_arguments;
mod td_reference;
mod td_reference_to;
mod td_string;
mod td_token;
mod td_token_argument;
mod td_tuple;
mod td_vec;
#[derive(Clone, Debug)]
pub enum LoopControl {
DoNothing,
Break,
Continue,
ErrBreak,
}
impl Default for LoopControl {
fn default() -> Self {
LoopControl::DoNothing
}
}
pub trait TokenDeserialize: Sized
where
Self: Default,
{
fn deserialize_tokens(
cursor: &mut TreeCursor,
source: &str,
diagnostics: &mut DiagnosticsInfo,
) -> Result<Box<Self>, ()> {
let mut new_self = Box::new(Self::default());
loop {
let node = cursor.node();
// If we reach the limit, stop parsing the file further.
if diagnostics.check_message_limit_reached() {
crate::mark_rest_of_file_as_unchecked(cursor, diagnostics, &node);
break;
}
match node.kind().as_ref() {
"token" => {
match Self::deserialize_general_token(cursor, source, diagnostics, new_self) {
(LoopControl::DoNothing, new_self_result) => {
// Do nothing
new_self = new_self_result;
}
(LoopControl::Break, new_self_result) => {
new_self = new_self_result;
break;
}
(LoopControl::Continue, new_self_result) => {
new_self = new_self_result;
// Only go to next sibling if there is one, if none: break.
// We have reached the end of the file, so have to go up the stack
let new_node = cursor.node();
if new_node.next_sibling().is_none() {
cursor.goto_parent();
break;
}
// If node did not change: break
// This will prevent infinite loops
if new_node == node {
break;
}
continue;
}
(LoopControl::ErrBreak, _new_self_result) => {
return Err(());
}
}
}
"comment" => {
// Just consume `comment` and move on to next token.
if Token::consume_token(cursor).is_err() {
break;
}
}
"ERROR" => {
// Can safely be ignored. Diagnostics already added by Lexical Analysis.
if Token::consume_token(cursor).is_err() {
break;
}
}
"EOF" => break,
others => {
log::error!("Found an unknown node of kind: {}", others);
break;
}
}
// If node did not change: break
// This will prevent infinite loops
let new_node = cursor.node();
if new_node == node {
break;
}
}
Ok(new_self)
}
fn deserialize_general_token(
cursor: &mut TreeCursor,
source: &str,
diagnostics: &mut DiagnosticsInfo,
new_self: Box<Self>,
) -> (LoopControl, Box<Self>);
fn get_allowed_tokens() -> Option<Vec<String>>;
/// Should return `Continue` in most cases,
/// `DoNothing` in case of String, i32, Tuples and type likes that
fn get_vec_loopcontrol() -> LoopControl {
LoopControl::Continue
}
}