Skip to main content

emmylua_parser/grammar/lua/
test.rs

1#[cfg(test)]
2mod tests {
3    use crate::{LuaLanguageLevel, LuaParser, parser::ParserConfig};
4
5    macro_rules! assert_ast_eq {
6        ($lua_code:expr, $expected:expr) => {
7            let tree = LuaParser::parse($lua_code, ParserConfig::default());
8            let result = format!("{:#?}", tree.get_red_root()).trim().to_string();
9            let expected = $expected.trim().to_string();
10            assert_eq!(result, expected);
11        };
12        ($lua_code:expr, $expected:expr, $config:expr) => {
13            let tree = LuaParser::parse($lua_code, $config);
14            let result = format!("{:#?}", tree.get_red_root()).trim().to_string();
15            let expected = $expected.trim().to_string();
16            assert_eq!(result, expected);
17        };
18    }
19
20    #[allow(unused)]
21    fn print_ast(lua_code: &str) {
22        let tree = LuaParser::parse(lua_code, ParserConfig::default());
23        println!("{:#?}", tree.get_red_root());
24    }
25
26    #[allow(unused)]
27    fn print_ast_level(lua_code: &str, level: LuaLanguageLevel) {
28        let config = ParserConfig::new(level, None, Default::default(), Default::default(), false);
29        let tree = LuaParser::parse(lua_code, config);
30        println!("{:#?}", tree.get_red_root());
31    }
32
33    #[allow(unused)]
34    fn print_ast_config(lua_code: &str, config: ParserConfig) {
35        let tree = LuaParser::parse(lua_code, config);
36        println!("{:#?}", tree.get_red_root());
37    }
38
39    #[test]
40    fn test_full_lua_syntax() {
41        let code = r#"
42            -- This is a comment
43            local a = 10
44            local b = "string"
45            local c = { key = "value", 1, 2, 3 }
46
47            function foo(x, y)
48                if x > y then
49                    return x
50                else
51                    return y
52                end
53            end
54
55            for i = 1, 10 do
56                print(i)
57            end
58
59            while a > 0 do
60                a = a - 1
61            end
62
63            repeat
64                a = a + 1
65            until a == 10
66
67            local mt = {
68                __index = function(table, key)
69                    return "default"
70                end
71            }
72
73            setmetatable(c, mt)
74
75            local d = c.key
76            local e = c[1]
77        "#;
78
79        let result = r#"
80Syntax(Chunk)@0..770
81  Syntax(Block)@0..770
82    Token(TkEndOfLine)@0..1 "\n"
83    Token(TkWhitespace)@1..13 "            "
84    Syntax(Comment)@13..33
85      Syntax(DocDescription)@13..33
86        Token(TkNormalStart)@13..15 "--"
87        Token(TkWhitespace)@15..16 " "
88        Token(TkDocDetail)@16..33 "This is a comment"
89    Token(TkEndOfLine)@33..34 "\n"
90    Token(TkWhitespace)@34..46 "            "
91    Syntax(LocalStat)@46..58
92      Token(TkLocal)@46..51 "local"
93      Token(TkWhitespace)@51..52 " "
94      Syntax(LocalName)@52..53
95        Token(TkName)@52..53 "a"
96      Token(TkWhitespace)@53..54 " "
97      Token(TkAssign)@54..55 "="
98      Token(TkWhitespace)@55..56 " "
99      Syntax(LiteralExpr)@56..58
100        Token(TkInt)@56..58 "10"
101    Token(TkEndOfLine)@58..59 "\n"
102    Token(TkWhitespace)@59..71 "            "
103    Syntax(LocalStat)@71..89
104      Token(TkLocal)@71..76 "local"
105      Token(TkWhitespace)@76..77 " "
106      Syntax(LocalName)@77..78
107        Token(TkName)@77..78 "b"
108      Token(TkWhitespace)@78..79 " "
109      Token(TkAssign)@79..80 "="
110      Token(TkWhitespace)@80..81 " "
111      Syntax(LiteralExpr)@81..89
112        Token(TkString)@81..89 "\"string\""
113    Token(TkEndOfLine)@89..90 "\n"
114    Token(TkWhitespace)@90..102 "            "
115    Syntax(LocalStat)@102..138
116      Token(TkLocal)@102..107 "local"
117      Token(TkWhitespace)@107..108 " "
118      Syntax(LocalName)@108..109
119        Token(TkName)@108..109 "c"
120      Token(TkWhitespace)@109..110 " "
121      Token(TkAssign)@110..111 "="
122      Token(TkWhitespace)@111..112 " "
123      Syntax(TableObjectExpr)@112..138
124        Token(TkLeftBrace)@112..113 "{"
125        Token(TkWhitespace)@113..114 " "
126        Syntax(TableFieldAssign)@114..127
127          Token(TkName)@114..117 "key"
128          Token(TkWhitespace)@117..118 " "
129          Token(TkAssign)@118..119 "="
130          Token(TkWhitespace)@119..120 " "
131          Syntax(LiteralExpr)@120..127
132            Token(TkString)@120..127 "\"value\""
133        Token(TkComma)@127..128 ","
134        Token(TkWhitespace)@128..129 " "
135        Syntax(TableFieldValue)@129..130
136          Syntax(LiteralExpr)@129..130
137            Token(TkInt)@129..130 "1"
138        Token(TkComma)@130..131 ","
139        Token(TkWhitespace)@131..132 " "
140        Syntax(TableFieldValue)@132..133
141          Syntax(LiteralExpr)@132..133
142            Token(TkInt)@132..133 "2"
143        Token(TkComma)@133..134 ","
144        Token(TkWhitespace)@134..135 " "
145        Syntax(TableFieldValue)@135..136
146          Syntax(LiteralExpr)@135..136
147            Token(TkInt)@135..136 "3"
148        Token(TkWhitespace)@136..137 " "
149        Token(TkRightBrace)@137..138 "}"
150    Token(TkEndOfLine)@138..139 "\n"
151    Token(TkEndOfLine)@139..140 "\n"
152    Token(TkWhitespace)@140..152 "            "
153    Syntax(FuncStat)@152..315
154      Token(TkFunction)@152..160 "function"
155      Token(TkWhitespace)@160..161 " "
156      Syntax(NameExpr)@161..164
157        Token(TkName)@161..164 "foo"
158      Syntax(ClosureExpr)@164..315
159        Syntax(ParamList)@164..170
160          Token(TkLeftParen)@164..165 "("
161          Syntax(ParamName)@165..166
162            Token(TkName)@165..166 "x"
163          Token(TkComma)@166..167 ","
164          Token(TkWhitespace)@167..168 " "
165          Syntax(ParamName)@168..169
166            Token(TkName)@168..169 "y"
167          Token(TkRightParen)@169..170 ")"
168        Syntax(Block)@170..312
169          Token(TkEndOfLine)@170..171 "\n"
170          Token(TkWhitespace)@171..187 "                "
171          Syntax(IfStat)@187..299
172            Token(TkIf)@187..189 "if"
173            Token(TkWhitespace)@189..190 " "
174            Syntax(BinaryExpr)@190..195
175              Syntax(NameExpr)@190..191
176                Token(TkName)@190..191 "x"
177              Token(TkWhitespace)@191..192 " "
178              Token(TkGt)@192..193 ">"
179              Token(TkWhitespace)@193..194 " "
180              Syntax(NameExpr)@194..195
181                Token(TkName)@194..195 "y"
182            Token(TkWhitespace)@195..196 " "
183            Token(TkThen)@196..200 "then"
184            Syntax(Block)@200..246
185              Token(TkEndOfLine)@200..201 "\n"
186              Token(TkWhitespace)@201..221 "                    "
187              Syntax(ReturnStat)@221..229
188                Token(TkReturn)@221..227 "return"
189                Token(TkWhitespace)@227..228 " "
190                Syntax(NameExpr)@228..229
191                  Token(TkName)@228..229 "x"
192              Token(TkEndOfLine)@229..230 "\n"
193              Token(TkWhitespace)@230..246 "                "
194            Syntax(ElseClauseStat)@246..296
195              Token(TkElse)@246..250 "else"
196              Syntax(Block)@250..296
197                Token(TkEndOfLine)@250..251 "\n"
198                Token(TkWhitespace)@251..271 "                    "
199                Syntax(ReturnStat)@271..279
200                  Token(TkReturn)@271..277 "return"
201                  Token(TkWhitespace)@277..278 " "
202                  Syntax(NameExpr)@278..279
203                    Token(TkName)@278..279 "y"
204                Token(TkEndOfLine)@279..280 "\n"
205                Token(TkWhitespace)@280..296 "                "
206            Token(TkEnd)@296..299 "end"
207          Token(TkEndOfLine)@299..300 "\n"
208          Token(TkWhitespace)@300..312 "            "
209        Token(TkEnd)@312..315 "end"
210    Token(TkEndOfLine)@315..316 "\n"
211    Token(TkEndOfLine)@316..317 "\n"
212    Token(TkWhitespace)@317..329 "            "
213    Syntax(ForStat)@329..386
214      Token(TkFor)@329..332 "for"
215      Token(TkWhitespace)@332..333 " "
216      Token(TkName)@333..334 "i"
217      Token(TkWhitespace)@334..335 " "
218      Token(TkAssign)@335..336 "="
219      Token(TkWhitespace)@336..337 " "
220      Syntax(LiteralExpr)@337..338
221        Token(TkInt)@337..338 "1"
222      Token(TkComma)@338..339 ","
223      Token(TkWhitespace)@339..340 " "
224      Syntax(LiteralExpr)@340..342
225        Token(TkInt)@340..342 "10"
226      Token(TkWhitespace)@342..343 " "
227      Token(TkDo)@343..345 "do"
228      Syntax(Block)@345..383
229        Token(TkEndOfLine)@345..346 "\n"
230        Token(TkWhitespace)@346..362 "                "
231        Syntax(CallExprStat)@362..370
232          Syntax(CallExpr)@362..370
233            Syntax(NameExpr)@362..367
234              Token(TkName)@362..367 "print"
235            Syntax(CallArgList)@367..370
236              Token(TkLeftParen)@367..368 "("
237              Syntax(NameExpr)@368..369
238                Token(TkName)@368..369 "i"
239              Token(TkRightParen)@369..370 ")"
240        Token(TkEndOfLine)@370..371 "\n"
241        Token(TkWhitespace)@371..383 "            "
242      Token(TkEnd)@383..386 "end"
243    Token(TkEndOfLine)@386..387 "\n"
244    Token(TkEndOfLine)@387..388 "\n"
245    Token(TkWhitespace)@388..400 "            "
246    Syntax(WhileStat)@400..456
247      Token(TkWhile)@400..405 "while"
248      Token(TkWhitespace)@405..406 " "
249      Syntax(BinaryExpr)@406..411
250        Syntax(NameExpr)@406..407
251          Token(TkName)@406..407 "a"
252        Token(TkWhitespace)@407..408 " "
253        Token(TkGt)@408..409 ">"
254        Token(TkWhitespace)@409..410 " "
255        Syntax(LiteralExpr)@410..411
256          Token(TkInt)@410..411 "0"
257      Token(TkWhitespace)@411..412 " "
258      Token(TkDo)@412..414 "do"
259      Syntax(Block)@414..453
260        Token(TkEndOfLine)@414..415 "\n"
261        Token(TkWhitespace)@415..431 "                "
262        Syntax(AssignStat)@431..440
263          Syntax(NameExpr)@431..432
264            Token(TkName)@431..432 "a"
265          Token(TkWhitespace)@432..433 " "
266          Token(TkAssign)@433..434 "="
267          Token(TkWhitespace)@434..435 " "
268          Syntax(BinaryExpr)@435..440
269            Syntax(NameExpr)@435..436
270              Token(TkName)@435..436 "a"
271            Token(TkWhitespace)@436..437 " "
272            Token(TkMinus)@437..438 "-"
273            Token(TkWhitespace)@438..439 " "
274            Syntax(LiteralExpr)@439..440
275              Token(TkInt)@439..440 "1"
276        Token(TkEndOfLine)@440..441 "\n"
277        Token(TkWhitespace)@441..453 "            "
278      Token(TkEnd)@453..456 "end"
279    Token(TkEndOfLine)@456..457 "\n"
280    Token(TkEndOfLine)@457..458 "\n"
281    Token(TkWhitespace)@458..470 "            "
282    Syntax(RepeatStat)@470..528
283      Token(TkRepeat)@470..476 "repeat"
284      Syntax(Block)@476..515
285        Token(TkEndOfLine)@476..477 "\n"
286        Token(TkWhitespace)@477..493 "                "
287        Syntax(AssignStat)@493..502
288          Syntax(NameExpr)@493..494
289            Token(TkName)@493..494 "a"
290          Token(TkWhitespace)@494..495 " "
291          Token(TkAssign)@495..496 "="
292          Token(TkWhitespace)@496..497 " "
293          Syntax(BinaryExpr)@497..502
294            Syntax(NameExpr)@497..498
295              Token(TkName)@497..498 "a"
296            Token(TkWhitespace)@498..499 " "
297            Token(TkPlus)@499..500 "+"
298            Token(TkWhitespace)@500..501 " "
299            Syntax(LiteralExpr)@501..502
300              Token(TkInt)@501..502 "1"
301        Token(TkEndOfLine)@502..503 "\n"
302        Token(TkWhitespace)@503..515 "            "
303      Token(TkUntil)@515..520 "until"
304      Token(TkWhitespace)@520..521 " "
305      Syntax(BinaryExpr)@521..528
306        Syntax(NameExpr)@521..522
307          Token(TkName)@521..522 "a"
308        Token(TkWhitespace)@522..523 " "
309        Token(TkEq)@523..525 "=="
310        Token(TkWhitespace)@525..526 " "
311        Syntax(LiteralExpr)@526..528
312          Token(TkInt)@526..528 "10"
313    Token(TkEndOfLine)@528..529 "\n"
314    Token(TkEndOfLine)@529..530 "\n"
315    Token(TkWhitespace)@530..542 "            "
316    Syntax(LocalStat)@542..672
317      Token(TkLocal)@542..547 "local"
318      Token(TkWhitespace)@547..548 " "
319      Syntax(LocalName)@548..550
320        Token(TkName)@548..550 "mt"
321      Token(TkWhitespace)@550..551 " "
322      Token(TkAssign)@551..552 "="
323      Token(TkWhitespace)@552..553 " "
324      Syntax(TableObjectExpr)@553..672
325        Token(TkLeftBrace)@553..554 "{"
326        Token(TkEndOfLine)@554..555 "\n"
327        Token(TkWhitespace)@555..571 "                "
328        Syntax(TableFieldAssign)@571..658
329          Token(TkName)@571..578 "__index"
330          Token(TkWhitespace)@578..579 " "
331          Token(TkAssign)@579..580 "="
332          Token(TkWhitespace)@580..581 " "
333          Syntax(ClosureExpr)@581..658
334            Token(TkFunction)@581..589 "function"
335            Syntax(ParamList)@589..601
336              Token(TkLeftParen)@589..590 "("
337              Syntax(ParamName)@590..595
338                Token(TkName)@590..595 "table"
339              Token(TkComma)@595..596 ","
340              Token(TkWhitespace)@596..597 " "
341              Syntax(ParamName)@597..600
342                Token(TkName)@597..600 "key"
343              Token(TkRightParen)@600..601 ")"
344            Syntax(Block)@601..655
345              Token(TkEndOfLine)@601..602 "\n"
346              Token(TkWhitespace)@602..622 "                    "
347              Syntax(ReturnStat)@622..638
348                Token(TkReturn)@622..628 "return"
349                Token(TkWhitespace)@628..629 " "
350                Syntax(LiteralExpr)@629..638
351                  Token(TkString)@629..638 "\"default\""
352              Token(TkEndOfLine)@638..639 "\n"
353              Token(TkWhitespace)@639..655 "                "
354            Token(TkEnd)@655..658 "end"
355        Token(TkEndOfLine)@658..659 "\n"
356        Token(TkWhitespace)@659..671 "            "
357        Token(TkRightBrace)@671..672 "}"
358    Token(TkEndOfLine)@672..673 "\n"
359    Token(TkEndOfLine)@673..674 "\n"
360    Token(TkWhitespace)@674..686 "            "
361    Syntax(CallExprStat)@686..705
362      Syntax(SetmetatableCallExpr)@686..705
363        Syntax(NameExpr)@686..698
364          Token(TkName)@686..698 "setmetatable"
365        Syntax(CallArgList)@698..705
366          Token(TkLeftParen)@698..699 "("
367          Syntax(NameExpr)@699..700
368            Token(TkName)@699..700 "c"
369          Token(TkComma)@700..701 ","
370          Token(TkWhitespace)@701..702 " "
371          Syntax(NameExpr)@702..704
372            Token(TkName)@702..704 "mt"
373          Token(TkRightParen)@704..705 ")"
374    Token(TkEndOfLine)@705..706 "\n"
375    Token(TkEndOfLine)@706..707 "\n"
376    Token(TkWhitespace)@707..719 "            "
377    Syntax(LocalStat)@719..734
378      Token(TkLocal)@719..724 "local"
379      Token(TkWhitespace)@724..725 " "
380      Syntax(LocalName)@725..726
381        Token(TkName)@725..726 "d"
382      Token(TkWhitespace)@726..727 " "
383      Token(TkAssign)@727..728 "="
384      Token(TkWhitespace)@728..729 " "
385      Syntax(IndexExpr)@729..734
386        Syntax(NameExpr)@729..730
387          Token(TkName)@729..730 "c"
388        Token(TkDot)@730..731 "."
389        Token(TkName)@731..734 "key"
390    Token(TkEndOfLine)@734..735 "\n"
391    Token(TkWhitespace)@735..747 "            "
392    Syntax(LocalStat)@747..761
393      Token(TkLocal)@747..752 "local"
394      Token(TkWhitespace)@752..753 " "
395      Syntax(LocalName)@753..754
396        Token(TkName)@753..754 "e"
397      Token(TkWhitespace)@754..755 " "
398      Token(TkAssign)@755..756 "="
399      Token(TkWhitespace)@756..757 " "
400      Syntax(IndexExpr)@757..761
401        Syntax(NameExpr)@757..758
402          Token(TkName)@757..758 "c"
403        Token(TkLeftBracket)@758..759 "["
404        Syntax(LiteralExpr)@759..760
405          Token(TkInt)@759..760 "1"
406        Token(TkRightBracket)@760..761 "]"
407    Token(TkEndOfLine)@761..762 "\n"
408    Token(TkWhitespace)@762..770 "        "
409"#;
410
411        assert_ast_eq!(code, result);
412    }
413
414    #[test]
415    fn test_expr() {
416        let code = r#"
417        local a = 1 + 2 + 3 + 4
418        "#;
419
420        let result = r#"
421Syntax(Chunk)@0..41
422  Syntax(Block)@0..41
423    Token(TkEndOfLine)@0..1 "\n"
424    Token(TkWhitespace)@1..9 "        "
425    Syntax(LocalStat)@9..32
426      Token(TkLocal)@9..14 "local"
427      Token(TkWhitespace)@14..15 " "
428      Syntax(LocalName)@15..16
429        Token(TkName)@15..16 "a"
430      Token(TkWhitespace)@16..17 " "
431      Token(TkAssign)@17..18 "="
432      Token(TkWhitespace)@18..19 " "
433      Syntax(BinaryExpr)@19..32
434        Syntax(BinaryExpr)@19..28
435          Syntax(BinaryExpr)@19..24
436            Syntax(LiteralExpr)@19..20
437              Token(TkInt)@19..20 "1"
438            Token(TkWhitespace)@20..21 " "
439            Token(TkPlus)@21..22 "+"
440            Token(TkWhitespace)@22..23 " "
441            Syntax(LiteralExpr)@23..24
442              Token(TkInt)@23..24 "2"
443          Token(TkWhitespace)@24..25 " "
444          Token(TkPlus)@25..26 "+"
445          Token(TkWhitespace)@26..27 " "
446          Syntax(LiteralExpr)@27..28
447            Token(TkInt)@27..28 "3"
448        Token(TkWhitespace)@28..29 " "
449        Token(TkPlus)@29..30 "+"
450        Token(TkWhitespace)@30..31 " "
451        Syntax(LiteralExpr)@31..32
452          Token(TkInt)@31..32 "4"
453    Token(TkEndOfLine)@32..33 "\n"
454    Token(TkWhitespace)@33..41 "        "
455        "#;
456
457        assert_ast_eq!(code, result);
458    }
459
460    #[test]
461    fn test_assign_stat() {
462        let code = r#"
463        a = 1
464        b, c = 2, 3
465        d, e = 4
466        f, g = 5, 6, 7
467        "#;
468
469        let result = r#"
470Syntax(Chunk)@0..83
471  Syntax(Block)@0..83
472    Token(TkEndOfLine)@0..1 "\n"
473    Token(TkWhitespace)@1..9 "        "
474    Syntax(AssignStat)@9..14
475      Syntax(NameExpr)@9..10
476        Token(TkName)@9..10 "a"
477      Token(TkWhitespace)@10..11 " "
478      Token(TkAssign)@11..12 "="
479      Token(TkWhitespace)@12..13 " "
480      Syntax(LiteralExpr)@13..14
481        Token(TkInt)@13..14 "1"
482    Token(TkEndOfLine)@14..15 "\n"
483    Token(TkWhitespace)@15..23 "        "
484    Syntax(AssignStat)@23..34
485      Syntax(NameExpr)@23..24
486        Token(TkName)@23..24 "b"
487      Token(TkComma)@24..25 ","
488      Token(TkWhitespace)@25..26 " "
489      Syntax(NameExpr)@26..27
490        Token(TkName)@26..27 "c"
491      Token(TkWhitespace)@27..28 " "
492      Token(TkAssign)@28..29 "="
493      Token(TkWhitespace)@29..30 " "
494      Syntax(LiteralExpr)@30..31
495        Token(TkInt)@30..31 "2"
496      Token(TkComma)@31..32 ","
497      Token(TkWhitespace)@32..33 " "
498      Syntax(LiteralExpr)@33..34
499        Token(TkInt)@33..34 "3"
500    Token(TkEndOfLine)@34..35 "\n"
501    Token(TkWhitespace)@35..43 "        "
502    Syntax(AssignStat)@43..51
503      Syntax(NameExpr)@43..44
504        Token(TkName)@43..44 "d"
505      Token(TkComma)@44..45 ","
506      Token(TkWhitespace)@45..46 " "
507      Syntax(NameExpr)@46..47
508        Token(TkName)@46..47 "e"
509      Token(TkWhitespace)@47..48 " "
510      Token(TkAssign)@48..49 "="
511      Token(TkWhitespace)@49..50 " "
512      Syntax(LiteralExpr)@50..51
513        Token(TkInt)@50..51 "4"
514    Token(TkEndOfLine)@51..52 "\n"
515    Token(TkWhitespace)@52..60 "        "
516    Syntax(AssignStat)@60..74
517      Syntax(NameExpr)@60..61
518        Token(TkName)@60..61 "f"
519      Token(TkComma)@61..62 ","
520      Token(TkWhitespace)@62..63 " "
521      Syntax(NameExpr)@63..64
522        Token(TkName)@63..64 "g"
523      Token(TkWhitespace)@64..65 " "
524      Token(TkAssign)@65..66 "="
525      Token(TkWhitespace)@66..67 " "
526      Syntax(LiteralExpr)@67..68
527        Token(TkInt)@67..68 "5"
528      Token(TkComma)@68..69 ","
529      Token(TkWhitespace)@69..70 " "
530      Syntax(LiteralExpr)@70..71
531        Token(TkInt)@70..71 "6"
532      Token(TkComma)@71..72 ","
533      Token(TkWhitespace)@72..73 " "
534      Syntax(LiteralExpr)@73..74
535        Token(TkInt)@73..74 "7"
536    Token(TkEndOfLine)@74..75 "\n"
537    Token(TkWhitespace)@75..83 "        "
538        "#;
539
540        assert_ast_eq!(code, result);
541    }
542
543    #[test]
544    fn test_index_expr() {
545        let code = r#"
546        local t = a.b[c]["1123"]
547        "#;
548
549        let result = r#"
550Syntax(Chunk)@0..42
551  Syntax(Block)@0..42
552    Token(TkEndOfLine)@0..1 "\n"
553    Token(TkWhitespace)@1..9 "        "
554    Syntax(LocalStat)@9..33
555      Token(TkLocal)@9..14 "local"
556      Token(TkWhitespace)@14..15 " "
557      Syntax(LocalName)@15..16
558        Token(TkName)@15..16 "t"
559      Token(TkWhitespace)@16..17 " "
560      Token(TkAssign)@17..18 "="
561      Token(TkWhitespace)@18..19 " "
562      Syntax(IndexExpr)@19..33
563        Syntax(IndexExpr)@19..25
564          Syntax(IndexExpr)@19..22
565            Syntax(NameExpr)@19..20
566              Token(TkName)@19..20 "a"
567            Token(TkDot)@20..21 "."
568            Token(TkName)@21..22 "b"
569          Token(TkLeftBracket)@22..23 "["
570          Syntax(NameExpr)@23..24
571            Token(TkName)@23..24 "c"
572          Token(TkRightBracket)@24..25 "]"
573        Token(TkLeftBracket)@25..26 "["
574        Syntax(LiteralExpr)@26..32
575          Token(TkString)@26..32 "\"1123\""
576        Token(TkRightBracket)@32..33 "]"
577    Token(TkEndOfLine)@33..34 "\n"
578    Token(TkWhitespace)@34..42 "        "
579        "#;
580
581        assert_ast_eq!(code, result);
582    }
583
584    #[test]
585    fn test_call_expr() {
586        let code = r#"
587        local a = foo(1, 2, 3)
588        local c = aaa.bbbb:cccc()
589        require "aaaa.bbbb"
590        call {
591            a = 1,
592            b = 2,
593            c = 3
594        }
595        "#;
596
597        let result = r#"
598Syntax(Chunk)@0..183
599  Syntax(Block)@0..183
600    Token(TkEndOfLine)@0..1 "\n"
601    Token(TkWhitespace)@1..9 "        "
602    Syntax(LocalStat)@9..31
603      Token(TkLocal)@9..14 "local"
604      Token(TkWhitespace)@14..15 " "
605      Syntax(LocalName)@15..16
606        Token(TkName)@15..16 "a"
607      Token(TkWhitespace)@16..17 " "
608      Token(TkAssign)@17..18 "="
609      Token(TkWhitespace)@18..19 " "
610      Syntax(CallExpr)@19..31
611        Syntax(NameExpr)@19..22
612          Token(TkName)@19..22 "foo"
613        Syntax(CallArgList)@22..31
614          Token(TkLeftParen)@22..23 "("
615          Syntax(LiteralExpr)@23..24
616            Token(TkInt)@23..24 "1"
617          Token(TkComma)@24..25 ","
618          Token(TkWhitespace)@25..26 " "
619          Syntax(LiteralExpr)@26..27
620            Token(TkInt)@26..27 "2"
621          Token(TkComma)@27..28 ","
622          Token(TkWhitespace)@28..29 " "
623          Syntax(LiteralExpr)@29..30
624            Token(TkInt)@29..30 "3"
625          Token(TkRightParen)@30..31 ")"
626    Token(TkEndOfLine)@31..32 "\n"
627    Token(TkWhitespace)@32..40 "        "
628    Syntax(LocalStat)@40..65
629      Token(TkLocal)@40..45 "local"
630      Token(TkWhitespace)@45..46 " "
631      Syntax(LocalName)@46..47
632        Token(TkName)@46..47 "c"
633      Token(TkWhitespace)@47..48 " "
634      Token(TkAssign)@48..49 "="
635      Token(TkWhitespace)@49..50 " "
636      Syntax(CallExpr)@50..65
637        Syntax(IndexExpr)@50..63
638          Syntax(IndexExpr)@50..58
639            Syntax(NameExpr)@50..53
640              Token(TkName)@50..53 "aaa"
641            Token(TkDot)@53..54 "."
642            Token(TkName)@54..58 "bbbb"
643          Token(TkColon)@58..59 ":"
644          Token(TkName)@59..63 "cccc"
645        Syntax(CallArgList)@63..65
646          Token(TkLeftParen)@63..64 "("
647          Token(TkRightParen)@64..65 ")"
648    Token(TkEndOfLine)@65..66 "\n"
649    Token(TkWhitespace)@66..74 "        "
650    Syntax(CallExprStat)@74..93
651      Syntax(RequireCallExpr)@74..93
652        Syntax(NameExpr)@74..81
653          Token(TkName)@74..81 "require"
654        Token(TkWhitespace)@81..82 " "
655        Syntax(CallArgList)@82..93
656          Syntax(LiteralExpr)@82..93
657            Token(TkString)@82..93 "\"aaaa.bbbb\""
658    Token(TkEndOfLine)@93..94 "\n"
659    Token(TkWhitespace)@94..102 "        "
660    Syntax(CallExprStat)@102..174
661      Syntax(CallExpr)@102..174
662        Syntax(NameExpr)@102..106
663          Token(TkName)@102..106 "call"
664        Token(TkWhitespace)@106..107 " "
665        Syntax(CallArgList)@107..174
666          Syntax(TableObjectExpr)@107..174
667            Token(TkLeftBrace)@107..108 "{"
668            Token(TkEndOfLine)@108..109 "\n"
669            Token(TkWhitespace)@109..121 "            "
670            Syntax(TableFieldAssign)@121..126
671              Token(TkName)@121..122 "a"
672              Token(TkWhitespace)@122..123 " "
673              Token(TkAssign)@123..124 "="
674              Token(TkWhitespace)@124..125 " "
675              Syntax(LiteralExpr)@125..126
676                Token(TkInt)@125..126 "1"
677            Token(TkComma)@126..127 ","
678            Token(TkEndOfLine)@127..128 "\n"
679            Token(TkWhitespace)@128..140 "            "
680            Syntax(TableFieldAssign)@140..145
681              Token(TkName)@140..141 "b"
682              Token(TkWhitespace)@141..142 " "
683              Token(TkAssign)@142..143 "="
684              Token(TkWhitespace)@143..144 " "
685              Syntax(LiteralExpr)@144..145
686                Token(TkInt)@144..145 "2"
687            Token(TkComma)@145..146 ","
688            Token(TkEndOfLine)@146..147 "\n"
689            Token(TkWhitespace)@147..159 "            "
690            Syntax(TableFieldAssign)@159..164
691              Token(TkName)@159..160 "c"
692              Token(TkWhitespace)@160..161 " "
693              Token(TkAssign)@161..162 "="
694              Token(TkWhitespace)@162..163 " "
695              Syntax(LiteralExpr)@163..164
696                Token(TkInt)@163..164 "3"
697            Token(TkEndOfLine)@164..165 "\n"
698            Token(TkWhitespace)@165..173 "        "
699            Token(TkRightBrace)@173..174 "}"
700    Token(TkEndOfLine)@174..175 "\n"
701    Token(TkWhitespace)@175..183 "        "
702        "#;
703
704        assert_ast_eq!(code, result);
705    }
706
707    #[test]
708    fn test_table_expr() {
709        let code = r#"
710        local t = {
711            a = 1,
712            ["aa"] = 2,
713            [1] = 3
714        }
715        local d = {
716            1,
717            2,
718            3
719        }
720        local c = {}
721        local d = { a = 1, 1 }
722        "#;
723        print_ast(code);
724        let result = r#"
725Syntax(Chunk)@0..228
726  Syntax(Block)@0..228
727    Token(TkEndOfLine)@0..1 "\n"
728    Token(TkWhitespace)@1..9 "        "
729    Syntax(LocalStat)@9..93
730      Token(TkLocal)@9..14 "local"
731      Token(TkWhitespace)@14..15 " "
732      Syntax(LocalName)@15..16
733        Token(TkName)@15..16 "t"
734      Token(TkWhitespace)@16..17 " "
735      Token(TkAssign)@17..18 "="
736      Token(TkWhitespace)@18..19 " "
737      Syntax(TableObjectExpr)@19..93
738        Token(TkLeftBrace)@19..20 "{"
739        Token(TkEndOfLine)@20..21 "\n"
740        Token(TkWhitespace)@21..33 "            "
741        Syntax(TableFieldAssign)@33..38
742          Token(TkName)@33..34 "a"
743          Token(TkWhitespace)@34..35 " "
744          Token(TkAssign)@35..36 "="
745          Token(TkWhitespace)@36..37 " "
746          Syntax(LiteralExpr)@37..38
747            Token(TkInt)@37..38 "1"
748        Token(TkComma)@38..39 ","
749        Token(TkEndOfLine)@39..40 "\n"
750        Token(TkWhitespace)@40..52 "            "
751        Syntax(TableFieldAssign)@52..62
752          Token(TkLeftBracket)@52..53 "["
753          Syntax(LiteralExpr)@53..57
754            Token(TkString)@53..57 "\"aa\""
755          Token(TkRightBracket)@57..58 "]"
756          Token(TkWhitespace)@58..59 " "
757          Token(TkAssign)@59..60 "="
758          Token(TkWhitespace)@60..61 " "
759          Syntax(LiteralExpr)@61..62
760            Token(TkInt)@61..62 "2"
761        Token(TkComma)@62..63 ","
762        Token(TkEndOfLine)@63..64 "\n"
763        Token(TkWhitespace)@64..76 "            "
764        Syntax(TableFieldAssign)@76..83
765          Token(TkLeftBracket)@76..77 "["
766          Syntax(LiteralExpr)@77..78
767            Token(TkInt)@77..78 "1"
768          Token(TkRightBracket)@78..79 "]"
769          Token(TkWhitespace)@79..80 " "
770          Token(TkAssign)@80..81 "="
771          Token(TkWhitespace)@81..82 " "
772          Syntax(LiteralExpr)@82..83
773            Token(TkInt)@82..83 "3"
774        Token(TkEndOfLine)@83..84 "\n"
775        Token(TkWhitespace)@84..92 "        "
776        Token(TkRightBrace)@92..93 "}"
777    Token(TkEndOfLine)@93..94 "\n"
778    Token(TkWhitespace)@94..102 "        "
779    Syntax(LocalStat)@102..167
780      Token(TkLocal)@102..107 "local"
781      Token(TkWhitespace)@107..108 " "
782      Syntax(LocalName)@108..109
783        Token(TkName)@108..109 "d"
784      Token(TkWhitespace)@109..110 " "
785      Token(TkAssign)@110..111 "="
786      Token(TkWhitespace)@111..112 " "
787      Syntax(TableArrayExpr)@112..167
788        Token(TkLeftBrace)@112..113 "{"
789        Token(TkEndOfLine)@113..114 "\n"
790        Token(TkWhitespace)@114..126 "            "
791        Syntax(TableFieldValue)@126..127
792          Syntax(LiteralExpr)@126..127
793            Token(TkInt)@126..127 "1"
794        Token(TkComma)@127..128 ","
795        Token(TkEndOfLine)@128..129 "\n"
796        Token(TkWhitespace)@129..141 "            "
797        Syntax(TableFieldValue)@141..142
798          Syntax(LiteralExpr)@141..142
799            Token(TkInt)@141..142 "2"
800        Token(TkComma)@142..143 ","
801        Token(TkEndOfLine)@143..144 "\n"
802        Token(TkWhitespace)@144..156 "            "
803        Syntax(TableFieldValue)@156..157
804          Syntax(LiteralExpr)@156..157
805            Token(TkInt)@156..157 "3"
806        Token(TkEndOfLine)@157..158 "\n"
807        Token(TkWhitespace)@158..166 "        "
808        Token(TkRightBrace)@166..167 "}"
809    Token(TkEndOfLine)@167..168 "\n"
810    Token(TkWhitespace)@168..176 "        "
811    Syntax(LocalStat)@176..188
812      Token(TkLocal)@176..181 "local"
813      Token(TkWhitespace)@181..182 " "
814      Syntax(LocalName)@182..183
815        Token(TkName)@182..183 "c"
816      Token(TkWhitespace)@183..184 " "
817      Token(TkAssign)@184..185 "="
818      Token(TkWhitespace)@185..186 " "
819      Syntax(TableEmptyExpr)@186..188
820        Token(TkLeftBrace)@186..187 "{"
821        Token(TkRightBrace)@187..188 "}"
822    Token(TkEndOfLine)@188..189 "\n"
823    Token(TkWhitespace)@189..197 "        "
824    Syntax(LocalStat)@197..219
825      Token(TkLocal)@197..202 "local"
826      Token(TkWhitespace)@202..203 " "
827      Syntax(LocalName)@203..204
828        Token(TkName)@203..204 "d"
829      Token(TkWhitespace)@204..205 " "
830      Token(TkAssign)@205..206 "="
831      Token(TkWhitespace)@206..207 " "
832      Syntax(TableObjectExpr)@207..219
833        Token(TkLeftBrace)@207..208 "{"
834        Token(TkWhitespace)@208..209 " "
835        Syntax(TableFieldAssign)@209..214
836          Token(TkName)@209..210 "a"
837          Token(TkWhitespace)@210..211 " "
838          Token(TkAssign)@211..212 "="
839          Token(TkWhitespace)@212..213 " "
840          Syntax(LiteralExpr)@213..214
841            Token(TkInt)@213..214 "1"
842        Token(TkComma)@214..215 ","
843        Token(TkWhitespace)@215..216 " "
844        Syntax(TableFieldValue)@216..217
845          Syntax(LiteralExpr)@216..217
846            Token(TkInt)@216..217 "1"
847        Token(TkWhitespace)@217..218 " "
848        Token(TkRightBrace)@218..219 "}"
849    Token(TkEndOfLine)@219..220 "\n"
850    Token(TkWhitespace)@220..228 "        "
851        "#;
852
853        assert_ast_eq!(code, result);
854    }
855
856    #[test]
857    fn test_if_stat() {
858        let code = r#"
859        if a > 0 then
860            return a
861        elseif a < 0 then
862            return -a
863        else
864            return 0
865        end
866        "#;
867
868        let result = r#"
869Syntax(Chunk)@0..146
870  Syntax(Block)@0..146
871    Token(TkEndOfLine)@0..1 "\n"
872    Token(TkWhitespace)@1..9 "        "
873    Syntax(IfStat)@9..137
874      Token(TkIf)@9..11 "if"
875      Token(TkWhitespace)@11..12 " "
876      Syntax(BinaryExpr)@12..17
877        Syntax(NameExpr)@12..13
878          Token(TkName)@12..13 "a"
879        Token(TkWhitespace)@13..14 " "
880        Token(TkGt)@14..15 ">"
881        Token(TkWhitespace)@15..16 " "
882        Syntax(LiteralExpr)@16..17
883          Token(TkInt)@16..17 "0"
884      Token(TkWhitespace)@17..18 " "
885      Token(TkThen)@18..22 "then"
886      Syntax(Block)@22..52
887        Token(TkEndOfLine)@22..23 "\n"
888        Token(TkWhitespace)@23..35 "            "
889        Syntax(ReturnStat)@35..43
890          Token(TkReturn)@35..41 "return"
891          Token(TkWhitespace)@41..42 " "
892          Syntax(NameExpr)@42..43
893            Token(TkName)@42..43 "a"
894        Token(TkEndOfLine)@43..44 "\n"
895        Token(TkWhitespace)@44..52 "        "
896      Syntax(ElseIfClauseStat)@52..100
897        Token(TkElseIf)@52..58 "elseif"
898        Token(TkWhitespace)@58..59 " "
899        Syntax(BinaryExpr)@59..64
900          Syntax(NameExpr)@59..60
901            Token(TkName)@59..60 "a"
902          Token(TkWhitespace)@60..61 " "
903          Token(TkLt)@61..62 "<"
904          Token(TkWhitespace)@62..63 " "
905          Syntax(LiteralExpr)@63..64
906            Token(TkInt)@63..64 "0"
907        Token(TkWhitespace)@64..65 " "
908        Token(TkThen)@65..69 "then"
909        Syntax(Block)@69..100
910          Token(TkEndOfLine)@69..70 "\n"
911          Token(TkWhitespace)@70..82 "            "
912          Syntax(ReturnStat)@82..91
913            Token(TkReturn)@82..88 "return"
914            Token(TkWhitespace)@88..89 " "
915            Syntax(UnaryExpr)@89..91
916              Token(TkMinus)@89..90 "-"
917              Syntax(NameExpr)@90..91
918                Token(TkName)@90..91 "a"
919          Token(TkEndOfLine)@91..92 "\n"
920          Token(TkWhitespace)@92..100 "        "
921      Syntax(ElseClauseStat)@100..134
922        Token(TkElse)@100..104 "else"
923        Syntax(Block)@104..134
924          Token(TkEndOfLine)@104..105 "\n"
925          Token(TkWhitespace)@105..117 "            "
926          Syntax(ReturnStat)@117..125
927            Token(TkReturn)@117..123 "return"
928            Token(TkWhitespace)@123..124 " "
929            Syntax(LiteralExpr)@124..125
930              Token(TkInt)@124..125 "0"
931          Token(TkEndOfLine)@125..126 "\n"
932          Token(TkWhitespace)@126..134 "        "
933      Token(TkEnd)@134..137 "end"
934    Token(TkEndOfLine)@137..138 "\n"
935    Token(TkWhitespace)@138..146 "        "
936        "#;
937
938        assert_ast_eq!(code, result);
939    }
940
941    #[test]
942    fn test_local_stat() {
943        let code = r#"
944        local a<const>, b<close> = 123, {}
945        "#;
946
947        let result = r#"
948Syntax(Chunk)@0..52
949  Syntax(Block)@0..52
950    Token(TkEndOfLine)@0..1 "\n"
951    Token(TkWhitespace)@1..9 "        "
952    Syntax(LocalStat)@9..43
953      Token(TkLocal)@9..14 "local"
954      Token(TkWhitespace)@14..15 " "
955      Syntax(LocalName)@15..23
956        Token(TkName)@15..16 "a"
957        Syntax(Attribute)@16..23
958          Token(TkLt)@16..17 "<"
959          Token(TkName)@17..22 "const"
960          Token(TkGt)@22..23 ">"
961      Token(TkComma)@23..24 ","
962      Token(TkWhitespace)@24..25 " "
963      Syntax(LocalName)@25..33
964        Token(TkName)@25..26 "b"
965        Syntax(Attribute)@26..33
966          Token(TkLt)@26..27 "<"
967          Token(TkName)@27..32 "close"
968          Token(TkGt)@32..33 ">"
969      Token(TkWhitespace)@33..34 " "
970      Token(TkAssign)@34..35 "="
971      Token(TkWhitespace)@35..36 " "
972      Syntax(LiteralExpr)@36..39
973        Token(TkInt)@36..39 "123"
974      Token(TkComma)@39..40 ","
975      Token(TkWhitespace)@40..41 " "
976      Syntax(TableEmptyExpr)@41..43
977        Token(TkLeftBrace)@41..42 "{"
978        Token(TkRightBrace)@42..43 "}"
979    Token(TkEndOfLine)@43..44 "\n"
980    Token(TkWhitespace)@44..52 "        "
981        "#;
982
983        assert_ast_eq!(code, result);
984    }
985
986    #[test]
987    fn test_func_stat() {
988        let code = r#"
989        function foo(a, b)
990            return a + b
991        end
992        function t.foo(a, b)
993            return a + b
994        end
995        function t:foo(a, b)
996            return a + b
997        end
998        "#;
999
1000        let result = r#"
1001Syntax(Chunk)@0..205
1002  Syntax(Block)@0..205
1003    Token(TkEndOfLine)@0..1 "\n"
1004    Token(TkWhitespace)@1..9 "        "
1005    Syntax(FuncStat)@9..64
1006      Token(TkFunction)@9..17 "function"
1007      Token(TkWhitespace)@17..18 " "
1008      Syntax(NameExpr)@18..21
1009        Token(TkName)@18..21 "foo"
1010      Syntax(ClosureExpr)@21..64
1011        Syntax(ParamList)@21..27
1012          Token(TkLeftParen)@21..22 "("
1013          Syntax(ParamName)@22..23
1014            Token(TkName)@22..23 "a"
1015          Token(TkComma)@23..24 ","
1016          Token(TkWhitespace)@24..25 " "
1017          Syntax(ParamName)@25..26
1018            Token(TkName)@25..26 "b"
1019          Token(TkRightParen)@26..27 ")"
1020        Syntax(Block)@27..61
1021          Token(TkEndOfLine)@27..28 "\n"
1022          Token(TkWhitespace)@28..40 "            "
1023          Syntax(ReturnStat)@40..52
1024            Token(TkReturn)@40..46 "return"
1025            Token(TkWhitespace)@46..47 " "
1026            Syntax(BinaryExpr)@47..52
1027              Syntax(NameExpr)@47..48
1028                Token(TkName)@47..48 "a"
1029              Token(TkWhitespace)@48..49 " "
1030              Token(TkPlus)@49..50 "+"
1031              Token(TkWhitespace)@50..51 " "
1032              Syntax(NameExpr)@51..52
1033                Token(TkName)@51..52 "b"
1034          Token(TkEndOfLine)@52..53 "\n"
1035          Token(TkWhitespace)@53..61 "        "
1036        Token(TkEnd)@61..64 "end"
1037    Token(TkEndOfLine)@64..65 "\n"
1038    Token(TkWhitespace)@65..73 "        "
1039    Syntax(FuncStat)@73..130
1040      Token(TkFunction)@73..81 "function"
1041      Token(TkWhitespace)@81..82 " "
1042      Syntax(IndexExpr)@82..87
1043        Syntax(NameExpr)@82..83
1044          Token(TkName)@82..83 "t"
1045        Token(TkDot)@83..84 "."
1046        Token(TkName)@84..87 "foo"
1047      Syntax(ClosureExpr)@87..130
1048        Syntax(ParamList)@87..93
1049          Token(TkLeftParen)@87..88 "("
1050          Syntax(ParamName)@88..89
1051            Token(TkName)@88..89 "a"
1052          Token(TkComma)@89..90 ","
1053          Token(TkWhitespace)@90..91 " "
1054          Syntax(ParamName)@91..92
1055            Token(TkName)@91..92 "b"
1056          Token(TkRightParen)@92..93 ")"
1057        Syntax(Block)@93..127
1058          Token(TkEndOfLine)@93..94 "\n"
1059          Token(TkWhitespace)@94..106 "            "
1060          Syntax(ReturnStat)@106..118
1061            Token(TkReturn)@106..112 "return"
1062            Token(TkWhitespace)@112..113 " "
1063            Syntax(BinaryExpr)@113..118
1064              Syntax(NameExpr)@113..114
1065                Token(TkName)@113..114 "a"
1066              Token(TkWhitespace)@114..115 " "
1067              Token(TkPlus)@115..116 "+"
1068              Token(TkWhitespace)@116..117 " "
1069              Syntax(NameExpr)@117..118
1070                Token(TkName)@117..118 "b"
1071          Token(TkEndOfLine)@118..119 "\n"
1072          Token(TkWhitespace)@119..127 "        "
1073        Token(TkEnd)@127..130 "end"
1074    Token(TkEndOfLine)@130..131 "\n"
1075    Token(TkWhitespace)@131..139 "        "
1076    Syntax(FuncStat)@139..196
1077      Token(TkFunction)@139..147 "function"
1078      Token(TkWhitespace)@147..148 " "
1079      Syntax(IndexExpr)@148..153
1080        Syntax(NameExpr)@148..149
1081          Token(TkName)@148..149 "t"
1082        Token(TkColon)@149..150 ":"
1083        Token(TkName)@150..153 "foo"
1084      Syntax(ClosureExpr)@153..196
1085        Syntax(ParamList)@153..159
1086          Token(TkLeftParen)@153..154 "("
1087          Syntax(ParamName)@154..155
1088            Token(TkName)@154..155 "a"
1089          Token(TkComma)@155..156 ","
1090          Token(TkWhitespace)@156..157 " "
1091          Syntax(ParamName)@157..158
1092            Token(TkName)@157..158 "b"
1093          Token(TkRightParen)@158..159 ")"
1094        Syntax(Block)@159..193
1095          Token(TkEndOfLine)@159..160 "\n"
1096          Token(TkWhitespace)@160..172 "            "
1097          Syntax(ReturnStat)@172..184
1098            Token(TkReturn)@172..178 "return"
1099            Token(TkWhitespace)@178..179 " "
1100            Syntax(BinaryExpr)@179..184
1101              Syntax(NameExpr)@179..180
1102                Token(TkName)@179..180 "a"
1103              Token(TkWhitespace)@180..181 " "
1104              Token(TkPlus)@181..182 "+"
1105              Token(TkWhitespace)@182..183 " "
1106              Syntax(NameExpr)@183..184
1107                Token(TkName)@183..184 "b"
1108          Token(TkEndOfLine)@184..185 "\n"
1109          Token(TkWhitespace)@185..193 "        "
1110        Token(TkEnd)@193..196 "end"
1111    Token(TkEndOfLine)@196..197 "\n"
1112    Token(TkWhitespace)@197..205 "        "
1113        "#;
1114
1115        assert_ast_eq!(code, result);
1116    }
1117
1118    #[test]
1119    fn test_error_for_completion() {
1120        let code = "a():";
1121        let result = r#"
1122Syntax(Chunk)@0..4
1123  Syntax(Block)@0..4
1124    Syntax(AssignStat)@0..4
1125      Syntax(IndexExpr)@0..4
1126        Syntax(CallExpr)@0..3
1127          Syntax(NameExpr)@0..1
1128            Token(TkName)@0..1 "a"
1129          Syntax(CallArgList)@1..3
1130            Token(TkLeftParen)@1..2 "("
1131            Token(TkRightParen)@2..3 ")"
1132        Token(TkColon)@3..4 ":"
1133        "#;
1134
1135        assert_ast_eq!(code, result);
1136    }
1137
1138    #[test]
1139    fn test_lua55_global_grammar() {
1140        let code = "global a, b;";
1141        let result = r#"
1142Syntax(Chunk)@0..12
1143  Syntax(Block)@0..12
1144    Syntax(GlobalStat)@0..12
1145      Token(TkGlobal)@0..6 "global"
1146      Token(TkWhitespace)@6..7 " "
1147      Syntax(LocalName)@7..8
1148        Token(TkName)@7..8 "a"
1149      Token(TkComma)@8..9 ","
1150      Token(TkWhitespace)@9..10 " "
1151      Syntax(LocalName)@10..11
1152        Token(TkName)@10..11 "b"
1153      Token(TkSemicolon)@11..12 ";"
1154        "#;
1155
1156        assert_ast_eq!(
1157            code,
1158            result,
1159            ParserConfig::with_level(LuaLanguageLevel::Lua55)
1160        );
1161
1162        let code2 = "global <const> a, b<const>";
1163        let result2 = r#"
1164Syntax(Chunk)@0..26
1165  Syntax(Block)@0..26
1166    Syntax(GlobalStat)@0..26
1167      Token(TkGlobal)@0..6 "global"
1168      Token(TkWhitespace)@6..7 " "
1169      Syntax(Attribute)@7..14
1170        Token(TkLt)@7..8 "<"
1171        Token(TkName)@8..13 "const"
1172        Token(TkGt)@13..14 ">"
1173      Token(TkWhitespace)@14..15 " "
1174      Syntax(LocalName)@15..16
1175        Token(TkName)@15..16 "a"
1176      Token(TkComma)@16..17 ","
1177      Token(TkWhitespace)@17..18 " "
1178      Syntax(LocalName)@18..26
1179        Token(TkName)@18..19 "b"
1180        Syntax(Attribute)@19..26
1181          Token(TkLt)@19..20 "<"
1182          Token(TkName)@20..25 "const"
1183          Token(TkGt)@25..26 ">"
1184        "#;
1185
1186        assert_ast_eq!(
1187            code2,
1188            result2,
1189            ParserConfig::with_level(LuaLanguageLevel::Lua55)
1190        );
1191    }
1192
1193    #[test]
1194    fn test_wrong_table_expr() {
1195        let code = r#"
1196        local _A = {
1197            a = ,
1198            b = ,
1199            c = ,
1200        }
1201        "#;
1202        let result = r#"
1203Syntax(Chunk)@0..94
1204  Syntax(Block)@0..94
1205    Token(TkEndOfLine)@0..1 "\n"
1206    Token(TkWhitespace)@1..9 "        "
1207    Syntax(LocalStat)@9..85
1208      Token(TkLocal)@9..14 "local"
1209      Token(TkWhitespace)@14..15 " "
1210      Syntax(LocalName)@15..17
1211        Token(TkName)@15..17 "_A"
1212      Token(TkWhitespace)@17..18 " "
1213      Token(TkAssign)@18..19 "="
1214      Token(TkWhitespace)@19..20 " "
1215      Syntax(TableObjectExpr)@20..85
1216        Token(TkLeftBrace)@20..21 "{"
1217        Token(TkEndOfLine)@21..22 "\n"
1218        Token(TkWhitespace)@22..34 "            "
1219        Syntax(TableFieldAssign)@34..37
1220          Token(TkName)@34..35 "a"
1221          Token(TkWhitespace)@35..36 " "
1222          Token(TkAssign)@36..37 "="
1223        Token(TkWhitespace)@37..38 " "
1224        Token(TkComma)@38..39 ","
1225        Token(TkEndOfLine)@39..40 "\n"
1226        Token(TkWhitespace)@40..52 "            "
1227        Syntax(TableFieldAssign)@52..55
1228          Token(TkName)@52..53 "b"
1229          Token(TkWhitespace)@53..54 " "
1230          Token(TkAssign)@54..55 "="
1231        Token(TkWhitespace)@55..56 " "
1232        Token(TkComma)@56..57 ","
1233        Token(TkEndOfLine)@57..58 "\n"
1234        Token(TkWhitespace)@58..70 "            "
1235        Syntax(TableFieldAssign)@70..73
1236          Token(TkName)@70..71 "c"
1237          Token(TkWhitespace)@71..72 " "
1238          Token(TkAssign)@72..73 "="
1239        Token(TkWhitespace)@73..74 " "
1240        Token(TkComma)@74..75 ","
1241        Token(TkEndOfLine)@75..76 "\n"
1242        Token(TkWhitespace)@76..84 "        "
1243        Token(TkRightBrace)@84..85 "}"
1244    Token(TkEndOfLine)@85..86 "\n"
1245    Token(TkWhitespace)@86..94 "        "
1246        "#;
1247
1248        assert_ast_eq!(code, result);
1249    }
1250
1251    #[test]
1252    fn test_lua55_local_grammar() {
1253        let code = "local <const> a, b<const> = 1, 2";
1254        let result = r#"
1255Syntax(Chunk)@0..32
1256  Syntax(Block)@0..32
1257    Syntax(LocalStat)@0..32
1258      Token(TkLocal)@0..5 "local"
1259      Token(TkWhitespace)@5..6 " "
1260      Syntax(Attribute)@6..13
1261        Token(TkLt)@6..7 "<"
1262        Token(TkName)@7..12 "const"
1263        Token(TkGt)@12..13 ">"
1264      Token(TkWhitespace)@13..14 " "
1265      Syntax(LocalName)@14..15
1266        Token(TkName)@14..15 "a"
1267      Token(TkComma)@15..16 ","
1268      Token(TkWhitespace)@16..17 " "
1269      Syntax(LocalName)@17..25
1270        Token(TkName)@17..18 "b"
1271        Syntax(Attribute)@18..25
1272          Token(TkLt)@18..19 "<"
1273          Token(TkName)@19..24 "const"
1274          Token(TkGt)@24..25 ">"
1275      Token(TkWhitespace)@25..26 " "
1276      Token(TkAssign)@26..27 "="
1277      Token(TkWhitespace)@27..28 " "
1278      Syntax(LiteralExpr)@28..29
1279        Token(TkInt)@28..29 "1"
1280      Token(TkComma)@29..30 ","
1281      Token(TkWhitespace)@30..31 " "
1282      Syntax(LiteralExpr)@31..32
1283        Token(TkInt)@31..32 "2"
1284        "#;
1285
1286        assert_ast_eq!(
1287            code,
1288            result,
1289            ParserConfig::with_level(LuaLanguageLevel::Lua55)
1290        );
1291    }
1292
1293    #[test]
1294    fn test_lua55_named_var_args_grammar() {
1295        let code = r#"
1296        local function foo(a, b, ...c)
1297        end
1298        "#;
1299        let result = r#"
1300Syntax(Chunk)@0..60
1301  Syntax(Block)@0..60
1302    Token(TkEndOfLine)@0..1 "\n"
1303    Token(TkWhitespace)@1..9 "        "
1304    Syntax(LocalFuncStat)@9..51
1305      Token(TkLocal)@9..14 "local"
1306      Token(TkWhitespace)@14..15 " "
1307      Token(TkFunction)@15..23 "function"
1308      Token(TkWhitespace)@23..24 " "
1309      Syntax(LocalName)@24..27
1310        Token(TkName)@24..27 "foo"
1311      Syntax(ClosureExpr)@27..51
1312        Syntax(ParamList)@27..39
1313          Token(TkLeftParen)@27..28 "("
1314          Syntax(ParamName)@28..29
1315            Token(TkName)@28..29 "a"
1316          Token(TkComma)@29..30 ","
1317          Token(TkWhitespace)@30..31 " "
1318          Syntax(ParamName)@31..32
1319            Token(TkName)@31..32 "b"
1320          Token(TkComma)@32..33 ","
1321          Token(TkWhitespace)@33..34 " "
1322          Syntax(ParamName)@34..38
1323            Token(TkDots)@34..37 "..."
1324            Token(TkName)@37..38 "c"
1325          Token(TkRightParen)@38..39 ")"
1326        Token(TkEndOfLine)@39..40 "\n"
1327        Token(TkWhitespace)@40..48 "        "
1328        Token(TkEnd)@48..51 "end"
1329    Token(TkEndOfLine)@51..52 "\n"
1330    Token(TkWhitespace)@52..60 "        "
1331        "#;
1332
1333        assert_ast_eq!(
1334            code,
1335            result,
1336            ParserConfig::with_level(LuaLanguageLevel::Lua55)
1337        );
1338    }
1339
1340    #[test]
1341    fn test_global_const_mul() {
1342        let code = "global <const> *";
1343        let result = r#"
1344Syntax(Chunk)@0..16
1345  Syntax(Block)@0..16
1346    Syntax(GlobalStat)@0..16
1347      Token(TkGlobal)@0..6 "global"
1348      Token(TkWhitespace)@6..7 " "
1349      Syntax(Attribute)@7..14
1350        Token(TkLt)@7..8 "<"
1351        Token(TkName)@8..13 "const"
1352        Token(TkGt)@13..14 ">"
1353      Token(TkWhitespace)@14..15 " "
1354      Token(TkMul)@15..16 "*"
1355        "#;
1356
1357        assert_ast_eq!(
1358            code,
1359            result,
1360            ParserConfig::with_level(LuaLanguageLevel::Lua55)
1361        );
1362    }
1363}