1use luau_lexer::prelude::{Lexer, ParseError, Symbol, Token, TokenType};
4use std::ops::{Deref, DerefMut};
5
6use crate::types::{
7 GetRange, GetRangeError, List, ListItem, Parse, ParseWithArgs, Print, Range, TryParse,
8};
9
10impl<T> List<T> {
11 #[inline]
13 pub const fn new() -> Self {
14 Self { items: Vec::new() }
15 }
16
17 fn parse<C: FnMut(Token, &mut Lexer) -> Option<T>>(
19 mut token: Token,
20 lexer: &mut Lexer,
21 mut parse: C,
22 ) -> Option<Self> {
23 let mut items = Vec::new();
24 let mut state = lexer.save_state();
25
26 while let Some(item) = parse(token, lexer) {
27 maybe_next_token!(lexer, maybe_comma, TokenType::Symbol(Symbol::Comma));
28 state = lexer.save_state();
29
30 if let Some(comma) = maybe_comma {
31 items.push(ListItem::Trailing {
32 item,
33 separator: comma,
34 });
35 } else {
36 items.push(ListItem::NonTrailing(item));
37
38 break;
39 }
40
41 token = lexer.next_token();
42 }
43
44 lexer.set_state(state);
45
46 Some(Self { items })
47 }
48}
49
50impl<T> Default for List<T> {
51 #[inline]
52 fn default() -> Self {
53 Self::new()
54 }
55}
56
57impl<T: Parse> Parse for List<T> {
58 #[inline]
59 fn parse(token: Token, lexer: &mut Lexer, errors: &mut Vec<ParseError>) -> Option<Self> {
60 Self::parse(token, lexer, |token, lexer| T::parse(token, lexer, errors))
61 }
62}
63impl<T: Parse> TryParse for List<T> {}
64
65impl<A: Clone, T: ParseWithArgs<A>> ParseWithArgs<A> for List<T> {
66 #[inline]
67 fn parse_with(
68 token: Token,
69 lexer: &mut Lexer,
70 errors: &mut Vec<ParseError>,
71 args: A,
72 ) -> Option<Self> {
73 Self::parse(token, lexer, |token, lexer| {
74 T::parse_with(token, lexer, errors, args.clone())
75 })
76 }
77}
78
79impl<T> Deref for List<T> {
80 type Target = Vec<ListItem<T>>;
81
82 fn deref(&self) -> &Self::Target {
83 &self.items
84 }
85}
86impl<T> DerefMut for List<T> {
87 fn deref_mut(&mut self) -> &mut Self::Target {
88 &mut self.items
89 }
90}
91
92impl<T> Deref for ListItem<T> {
93 type Target = T;
94
95 fn deref(&self) -> &Self::Target {
96 match self {
97 ListItem::Trailing { item, .. } => item,
98 ListItem::NonTrailing(item) => item,
99 }
100 }
101}
102impl<T> DerefMut for ListItem<T> {
103 fn deref_mut(&mut self) -> &mut Self::Target {
104 match self {
105 ListItem::Trailing { item, .. } => item,
106 ListItem::NonTrailing(item) => item,
107 }
108 }
109}
110
111impl<T: GetRange> GetRange for List<T> {
112 fn get_range(&self) -> Result<Range, GetRangeError> {
113 (**self).get_range()
114 }
115}
116
117impl<T: GetRange> GetRange for ListItem<T> {
118 fn get_range(&self) -> Result<Range, GetRangeError> {
119 match self {
120 ListItem::Trailing { item, separator } => Ok(Range::new(
121 item.get_range()?.start,
122 separator.get_range()?.end,
123 )),
124 ListItem::NonTrailing(item) => item.get_range(),
125 }
126 }
127}
128
129impl<T: Print> Print for List<T> {
130 #[inline]
131 fn print(&self) -> String {
132 self.items.print()
133 }
134
135 #[inline]
136 fn print_final_trivia(&self) -> String {
137 self.items.print_final_trivia()
138 }
139
140 #[inline]
141 fn print_without_final_trivia(&self) -> String {
142 self.items.print_without_final_trivia()
143 }
144}
145
146impl<T: Print> Print for ListItem<T> {
147 #[inline]
148 fn print(&self) -> String {
149 match self {
150 Self::Trailing { item, separator } => {
151 item.print_without_final_trivia() + &separator.print()
152 }
153 Self::NonTrailing(item) => item.print(),
154 }
155 }
156
157 #[inline]
158 fn print_final_trivia(&self) -> String {
159 match self {
160 ListItem::Trailing { separator, .. } => separator.print_final_trivia(),
161 ListItem::NonTrailing(item) => item.print_final_trivia(),
162 }
163 }
164
165 #[inline]
166 fn print_without_final_trivia(&self) -> String {
167 match self {
168 ListItem::Trailing { item, separator } => {
169 item.print_without_final_trivia() + &separator.print_without_final_trivia()
170 }
171 ListItem::NonTrailing(item) => item.print_without_final_trivia(),
172 }
173 }
174}