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