rbs 1.6.2 → 1.7.0.beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +0 -4
  3. data/.gitignore +1 -0
  4. data/CHANGELOG.md +6 -0
  5. data/Gemfile +1 -0
  6. data/Rakefile +7 -22
  7. data/core/kernel.rbs +4 -4
  8. data/core/trace_point.rbs +1 -1
  9. data/ext/rbs/extension/constants.c +140 -0
  10. data/ext/rbs/extension/constants.h +72 -0
  11. data/ext/rbs/extension/extconf.rb +3 -0
  12. data/ext/rbs/extension/lexer.c +1070 -0
  13. data/ext/rbs/extension/lexer.h +145 -0
  14. data/ext/rbs/extension/location.c +295 -0
  15. data/ext/rbs/extension/location.h +59 -0
  16. data/ext/rbs/extension/main.c +9 -0
  17. data/ext/rbs/extension/parser.c +2418 -0
  18. data/ext/rbs/extension/parser.h +23 -0
  19. data/ext/rbs/extension/parserstate.c +313 -0
  20. data/ext/rbs/extension/parserstate.h +141 -0
  21. data/ext/rbs/extension/rbs_extension.h +40 -0
  22. data/ext/rbs/extension/ruby_objs.c +585 -0
  23. data/ext/rbs/extension/ruby_objs.h +46 -0
  24. data/ext/rbs/extension/unescape.c +65 -0
  25. data/goodcheck.yml +1 -1
  26. data/lib/rbs/ast/comment.rb +0 -12
  27. data/lib/rbs/buffer.rb +4 -0
  28. data/lib/rbs/cli.rb +5 -8
  29. data/lib/rbs/collection/sources/git.rb +18 -3
  30. data/lib/rbs/errors.rb +14 -1
  31. data/lib/rbs/location.rb +221 -217
  32. data/lib/rbs/location_aux.rb +108 -0
  33. data/lib/rbs/locator.rb +10 -7
  34. data/lib/rbs/parser_aux.rb +24 -0
  35. data/lib/rbs/types.rb +2 -3
  36. data/lib/rbs/version.rb +1 -1
  37. data/lib/rbs/writer.rb +4 -2
  38. data/lib/rbs.rb +3 -7
  39. data/rbs.gemspec +2 -1
  40. data/sig/ancestor_builder.rbs +2 -2
  41. data/sig/annotation.rbs +2 -2
  42. data/sig/comment.rbs +7 -7
  43. data/sig/constant_table.rbs +1 -1
  44. data/sig/declarations.rbs +9 -9
  45. data/sig/definition.rbs +1 -1
  46. data/sig/definition_builder.rbs +2 -2
  47. data/sig/errors.rbs +30 -25
  48. data/sig/location.rbs +42 -79
  49. data/sig/locator.rbs +2 -2
  50. data/sig/members.rbs +7 -7
  51. data/sig/method_types.rbs +3 -3
  52. data/sig/parser.rbs +11 -21
  53. data/sig/types.rbs +45 -27
  54. data/sig/writer.rbs +1 -1
  55. data/stdlib/json/0/json.rbs +3 -3
  56. metadata +24 -6
  57. data/lib/rbs/parser.rb +0 -3614
@@ -0,0 +1,9 @@
1
+ #include "rbs_extension.h"
2
+
3
+ void
4
+ Init_extension(void)
5
+ {
6
+ rbs__init_constants();
7
+ rbs__init_location();
8
+ rbs__init_parser();
9
+ }
@@ -0,0 +1,2418 @@
1
+ #include "rbs_extension.h"
2
+
3
+ #define INTERN_TOKEN(parserstate, tok) \
4
+ rb_intern3(\
5
+ peek_token(parserstate->lexstate, tok),\
6
+ token_bytes(tok),\
7
+ rb_enc_get(parserstate->lexstate->string)\
8
+ )
9
+
10
+ #define KEYWORD_CASES \
11
+ case kBOOL:\
12
+ case kBOT: \
13
+ case kCLASS: \
14
+ case kFALSE: \
15
+ case kINSTANCE: \
16
+ case kINTERFACE: \
17
+ case kNIL: \
18
+ case kSELF: \
19
+ case kSINGLETON: \
20
+ case kTOP: \
21
+ case kTRUE: \
22
+ case kVOID: \
23
+ case kTYPE: \
24
+ case kUNCHECKED: \
25
+ case kIN: \
26
+ case kOUT: \
27
+ case kEND: \
28
+ case kDEF: \
29
+ case kINCLUDE: \
30
+ case kEXTEND: \
31
+ case kPREPEND: \
32
+ case kALIAS: \
33
+ case kMODULE: \
34
+ case kATTRREADER: \
35
+ case kATTRWRITER: \
36
+ case kATTRACCESSOR: \
37
+ case kPUBLIC: \
38
+ case kPRIVATE: \
39
+ case kUNTYPED: \
40
+ /* nop */
41
+
42
+ typedef struct {
43
+ VALUE required_positionals;
44
+ VALUE optional_positionals;
45
+ VALUE rest_positionals;
46
+ VALUE trailing_positionals;
47
+ VALUE required_keywords;
48
+ VALUE optional_keywords;
49
+ VALUE rest_keywords;
50
+ } method_params;
51
+
52
+ // /**
53
+ // * Returns RBS::Location object of `current_token` of a parser state.
54
+ // *
55
+ // * @param state
56
+ // * @return New RBS::Location object.
57
+ // * */
58
+ static VALUE rbs_location_current_token(parserstate *state) {
59
+ return rbs_location_pp(
60
+ state->buffer,
61
+ &state->current_token.range.start,
62
+ &state->current_token.range.end
63
+ );
64
+ }
65
+
66
+ static VALUE parse_optional(parserstate *state);
67
+ static VALUE parse_simple(parserstate *state);
68
+
69
+ static VALUE string_of_loc(parserstate *state, position start, position end) {
70
+ return rb_enc_str_new(
71
+ RSTRING_PTR(state->lexstate->string) + start.byte_pos,
72
+ end.byte_pos - start.byte_pos,
73
+ rb_enc_get(state->lexstate->string)
74
+ );
75
+ }
76
+
77
+ /**
78
+ * Raises RuntimeError with "Unexpected error " messsage.
79
+ * */
80
+ static NORETURN(void) rbs_abort() {
81
+ rb_raise(
82
+ rb_eRuntimeError,
83
+ "Unexpected error"
84
+ );
85
+ }
86
+
87
+ NORETURN(void) raise_syntax_error(parserstate *state, token tok, const char *fmt, ...) {
88
+ va_list args;
89
+ va_start(args, fmt);
90
+ VALUE message = rb_vsprintf(fmt, args);
91
+ va_end(args);
92
+
93
+ VALUE location = rbs_new_location(state->buffer, tok.range);
94
+ VALUE type = rb_str_new_cstr(token_type_str(tok.type));
95
+
96
+ VALUE error = rb_funcall(
97
+ RBS_ParsingError,
98
+ rb_intern("new"),
99
+ 3,
100
+ location,
101
+ message,
102
+ type
103
+ );
104
+
105
+ rb_exc_raise(error);
106
+ }
107
+
108
+ typedef enum {
109
+ CLASS_NAME = 1,
110
+ INTERFACE_NAME = 2,
111
+ ALIAS_NAME = 4
112
+ } TypeNameKind;
113
+
114
+ void parser_advance_no_gap(parserstate *state) {
115
+ if (state->current_token.range.end.byte_pos == state->next_token.range.start.byte_pos) {
116
+ parser_advance(state);
117
+ } else {
118
+ raise_syntax_error(
119
+ state,
120
+ state->next_token,
121
+ "unexpected token"
122
+ );
123
+ }
124
+ }
125
+
126
+ /*
127
+ type_name ::= {`::`} (tUIDENT `::`)* <tXIDENT>
128
+ | {(tUIDENT `::`)*} <tXIDENT>
129
+ | {<tXIDENT>}
130
+ */
131
+ VALUE parse_type_name(parserstate *state, TypeNameKind kind, range *rg) {
132
+ VALUE absolute = Qfalse;
133
+ VALUE path = rb_ary_new();
134
+ VALUE namespace;
135
+
136
+ if (rg) {
137
+ rg->start = state->current_token.range.start;
138
+ }
139
+
140
+ if (state->current_token.type == pCOLON2) {
141
+ absolute = Qtrue;
142
+ parser_advance_no_gap(state);
143
+ }
144
+
145
+ while (
146
+ state->current_token.type == tUIDENT
147
+ && state->next_token.type == pCOLON2
148
+ && state->current_token.range.end.byte_pos == state->next_token.range.start.byte_pos
149
+ && state->next_token.range.end.byte_pos == state->next_token2.range.start.byte_pos
150
+ ) {
151
+ rb_ary_push(path, ID2SYM(INTERN_TOKEN(state, state->current_token)));
152
+
153
+ parser_advance(state);
154
+ parser_advance(state);
155
+ }
156
+ namespace = rbs_namespace(path, absolute);
157
+
158
+ switch (state->current_token.type) {
159
+ case tLIDENT:
160
+ if (kind & ALIAS_NAME) goto success;
161
+ goto error;
162
+ case tULIDENT:
163
+ if (kind & INTERFACE_NAME) goto success;
164
+ goto error;
165
+ case tUIDENT:
166
+ if (kind & CLASS_NAME) goto success;
167
+ goto error;
168
+ default:
169
+ goto error;
170
+ }
171
+
172
+ success: {
173
+ if (rg) {
174
+ rg->end = state->current_token.range.end;
175
+ }
176
+
177
+ return rbs_type_name(namespace, ID2SYM(INTERN_TOKEN(state, state->current_token)));
178
+ }
179
+
180
+ error: {
181
+ VALUE ids = rb_ary_new();
182
+ if (kind & ALIAS_NAME) {
183
+ rb_ary_push(ids, rb_str_new_literal("alias name"));
184
+ }
185
+ if (kind & INTERFACE_NAME) {
186
+ rb_ary_push(ids, rb_str_new_literal("interface name"));
187
+ }
188
+ if (kind & CLASS_NAME) {
189
+ rb_ary_push(ids, rb_str_new_literal("class/module/constant name"));
190
+ }
191
+
192
+ VALUE string = rb_funcall(ids, rb_intern("join"), 1, rb_str_new_cstr(", "));
193
+
194
+ raise_syntax_error(
195
+ state,
196
+ state->current_token,
197
+ "expected one of %"PRIsVALUE,
198
+ string
199
+ );
200
+ }
201
+ }
202
+
203
+ /*
204
+ type_list ::= {} type `,` ... <`,`> eol
205
+ | {} type `,` ... `,` <type> eol
206
+ */
207
+ static VALUE parse_type_list(parserstate *state, enum TokenType eol, VALUE types) {
208
+ while (true) {
209
+ rb_ary_push(types, parse_type(state));
210
+
211
+ if (state->next_token.type == pCOMMA) {
212
+ parser_advance(state);
213
+
214
+ if (state->next_token.type == eol) {
215
+ break;
216
+ }
217
+ } else {
218
+ if (state->next_token.type == eol) {
219
+ break;
220
+ } else {
221
+ raise_syntax_error(
222
+ state,
223
+ state->next_token,
224
+ "comma delimited type list is expected"
225
+ );
226
+ }
227
+ }
228
+ }
229
+
230
+ return types;
231
+ }
232
+
233
+ static bool is_keyword_token(enum TokenType type) {
234
+ switch (type)
235
+ {
236
+ case tLIDENT:
237
+ case tUIDENT:
238
+ case tULIDENT:
239
+ case tULLIDENT:
240
+ case tQIDENT:
241
+ case tBANGIDENT:
242
+ KEYWORD_CASES
243
+ return true;
244
+ default:
245
+ return false;
246
+ }
247
+ }
248
+
249
+ /*
250
+ function_param ::= {} <type>
251
+ | {} type <param>
252
+ */
253
+ static VALUE parse_function_param(parserstate *state) {
254
+ range type_range;
255
+
256
+ type_range.start = state->next_token.range.start;
257
+ VALUE type = parse_type(state);
258
+ type_range.end = state->current_token.range.end;
259
+
260
+ if (state->next_token.type == pCOMMA || state->next_token.type == pRPAREN) {
261
+ range param_range = type_range;
262
+
263
+ VALUE location = rbs_new_location(state->buffer, param_range);
264
+ rbs_loc *loc = rbs_check_location(location);
265
+ rbs_loc_add_optional_child(loc, rb_intern("name"), NULL_RANGE);
266
+
267
+ return rbs_function_param(type, Qnil, location);
268
+ } else {
269
+ range name_range = state->next_token.range;
270
+ range param_range;
271
+
272
+ parser_advance(state);
273
+ param_range.start = type_range.start;
274
+ param_range.end = name_range.end;
275
+
276
+ VALUE name = ID2SYM(INTERN_TOKEN(state, state->current_token));
277
+ VALUE location = rbs_new_location(state->buffer, param_range);
278
+ rbs_loc *loc = rbs_check_location(location);
279
+ rbs_loc_add_optional_child(loc, rb_intern("name"), name_range);
280
+
281
+ return rbs_function_param(type, name, location);
282
+ }
283
+ }
284
+
285
+ static ID intern_token_start_end(parserstate *state, token start_token, token end_token) {
286
+ return rb_intern3(
287
+ peek_token(state->lexstate, start_token),
288
+ end_token.range.end.byte_pos - start_token.range.start.byte_pos,
289
+ rb_enc_get(state->lexstate->string)
290
+ );
291
+ }
292
+
293
+ /*
294
+ keyword_key ::= {} <keyword> `:`
295
+ | {} keyword <`?`> `:`
296
+ */
297
+ static VALUE parse_keyword_key(parserstate *state) {
298
+ VALUE key;
299
+
300
+ parser_advance(state);
301
+
302
+ if (state->next_token.type == pQUESTION) {
303
+ key = ID2SYM(intern_token_start_end(state, state->current_token, state->next_token));
304
+ parser_advance(state);
305
+ } else {
306
+ key = ID2SYM(INTERN_TOKEN(state, state->current_token));
307
+ }
308
+
309
+ return key;
310
+ }
311
+
312
+ /*
313
+ keyword ::= {} keyword `:` <function_param>
314
+ */
315
+ static void parse_keyword(parserstate *state, VALUE keywords) {
316
+ VALUE key;
317
+ VALUE param;
318
+
319
+ key = parse_keyword_key(state);
320
+ parser_advance_assert(state, pCOLON);
321
+ param = parse_function_param(state);
322
+
323
+ rb_hash_aset(keywords, key, param);
324
+
325
+ return;
326
+ }
327
+
328
+ /*
329
+ Returns true if keyword is given.
330
+
331
+ is_keyword === {} KEYWORD `:`
332
+ */
333
+ static bool is_keyword(parserstate *state) {
334
+ if (is_keyword_token(state->next_token.type)) {
335
+ if (state->next_token2.type == pCOLON && state->next_token.range.end.byte_pos == state->next_token2.range.start.byte_pos) {
336
+ return true;
337
+ }
338
+
339
+ if (state->next_token2.type == pQUESTION
340
+ && state->next_token3.type == pCOLON
341
+ && state->next_token.range.end.byte_pos == state->next_token2.range.start.byte_pos
342
+ && state->next_token2.range.end.byte_pos == state->next_token3.range.start.byte_pos) {
343
+ return true;
344
+ }
345
+ }
346
+
347
+ return false;
348
+ }
349
+
350
+ /*
351
+ params ::= {} `)`
352
+ | <required_params> `)`
353
+ | <required_params> `,` `)`
354
+
355
+ required_params ::= {} function_param `,` <required_params>
356
+ | {} <function_param>
357
+ | {} <optional_params>
358
+
359
+ optional_params ::= {} `?` function_param `,` <optional_params>
360
+ | {} `?` <function_param>
361
+ | {} <rest_params>
362
+
363
+ rest_params ::= {} `*` function_param `,` <trailing_params>
364
+ | {} `*` <function_param>
365
+ | {} <trailing_params>
366
+
367
+ trailing_params ::= {} function_param `,` <trailing_params>
368
+ | {} <function_param>
369
+ | {} <keywords>
370
+
371
+ keywords ::= {} required_keyword `,` <keywords>
372
+ | {} `?` optional_keyword `,` <keywords>
373
+ | {} `**` function_param `,` <keywords>
374
+ | {} <required_keyword>
375
+ | {} `?` <optional_keyword>
376
+ | {} `**` <function_param>
377
+ */
378
+ static void parse_params(parserstate *state, method_params *params) {
379
+ if (state->next_token.type == pRPAREN) {
380
+ return;
381
+ }
382
+
383
+ while (true) {
384
+ VALUE param;
385
+
386
+ switch (state->next_token.type) {
387
+ case pQUESTION:
388
+ goto PARSE_OPTIONAL_PARAMS;
389
+ case pSTAR:
390
+ goto PARSE_REST_PARAM;
391
+ case pSTAR2:
392
+ goto PARSE_KEYWORDS;
393
+ case pRPAREN:
394
+ goto EOP;
395
+
396
+ default:
397
+ if (is_keyword(state)) {
398
+ goto PARSE_KEYWORDS;
399
+ }
400
+
401
+ param = parse_function_param(state);
402
+ rb_ary_push(params->required_positionals, param);
403
+
404
+ break;
405
+ }
406
+
407
+ if (!parser_advance_if(state, pCOMMA)) {
408
+ goto EOP;
409
+ }
410
+ }
411
+
412
+ PARSE_OPTIONAL_PARAMS:
413
+ while (true) {
414
+ VALUE param;
415
+
416
+ switch (state->next_token.type) {
417
+ case pQUESTION:
418
+ parser_advance(state);
419
+
420
+ if (is_keyword(state)) {
421
+ parse_keyword(state, params->optional_keywords);
422
+ parser_advance_if(state, pCOMMA);
423
+ goto PARSE_KEYWORDS;
424
+ }
425
+
426
+ param = parse_function_param(state);
427
+ rb_ary_push(params->optional_positionals, param);
428
+
429
+ break;
430
+ default:
431
+ goto PARSE_REST_PARAM;
432
+ }
433
+
434
+ if (!parser_advance_if(state, pCOMMA)) {
435
+ goto EOP;
436
+ }
437
+ }
438
+
439
+ PARSE_REST_PARAM:
440
+ if (state->next_token.type == pSTAR) {
441
+ parser_advance(state);
442
+ params->rest_positionals = parse_function_param(state);
443
+
444
+ if (!parser_advance_if(state, pCOMMA)) {
445
+ goto EOP;
446
+ }
447
+ }
448
+ goto PARSE_TRAILING_PARAMS;
449
+
450
+ PARSE_TRAILING_PARAMS:
451
+ while (true) {
452
+ VALUE param;
453
+
454
+ switch (state->next_token.type) {
455
+ case pQUESTION:
456
+ goto PARSE_KEYWORDS;
457
+ case pSTAR:
458
+ goto EOP;
459
+ case pSTAR2:
460
+ goto PARSE_KEYWORDS;
461
+ case pRPAREN:
462
+ goto EOP;
463
+
464
+ default:
465
+ if (is_keyword(state)) {
466
+ goto PARSE_KEYWORDS;
467
+ }
468
+
469
+ param = parse_function_param(state);
470
+ rb_ary_push(params->trailing_positionals, param);
471
+
472
+ break;
473
+ }
474
+
475
+ if (!parser_advance_if(state, pCOMMA)) {
476
+ goto EOP;
477
+ }
478
+ }
479
+
480
+ PARSE_KEYWORDS:
481
+ while (true) {
482
+ switch (state->next_token.type) {
483
+ case pQUESTION:
484
+ parser_advance(state);
485
+ if (is_keyword(state)) {
486
+ parse_keyword(state, params->optional_keywords);
487
+ } else {
488
+ raise_syntax_error(
489
+ state,
490
+ state->next_token,
491
+ "optional keyword argument type is expected"
492
+ );
493
+ }
494
+ break;
495
+
496
+ case pSTAR2:
497
+ parser_advance(state);
498
+ params->rest_keywords = parse_function_param(state);
499
+ break;
500
+
501
+ case tUIDENT:
502
+ case tLIDENT:
503
+ case tULIDENT:
504
+ case tULLIDENT:
505
+ case tBANGIDENT:
506
+ KEYWORD_CASES
507
+ if (is_keyword(state)) {
508
+ parse_keyword(state, params->required_keywords);
509
+ } else {
510
+ raise_syntax_error(
511
+ state,
512
+ state->next_token,
513
+ "required keyword argument type is expected"
514
+ );
515
+ }
516
+ break;
517
+
518
+ default:
519
+ goto EOP;
520
+ }
521
+
522
+ if (!parser_advance_if(state, pCOMMA)) {
523
+ goto EOP;
524
+ }
525
+ }
526
+
527
+ EOP:
528
+ if (state->next_token.type != pRPAREN) {
529
+ raise_syntax_error(
530
+ state,
531
+ state->next_token,
532
+ "unexpected token for method type parameters"
533
+ );
534
+ }
535
+
536
+ return;
537
+ }
538
+
539
+ /*
540
+ optinal ::= {} <simple_type>
541
+ | {} simple_type <`?`>
542
+ */
543
+ static VALUE parse_optional(parserstate *state) {
544
+ range rg;
545
+ rg.start = state->next_token.range.start;
546
+ VALUE type = parse_simple(state);
547
+
548
+ if (state->next_token.type == pQUESTION) {
549
+ parser_advance(state);
550
+ rg.end = state->current_token.range.end;
551
+ VALUE location = rbs_new_location(state->buffer, rg);
552
+ return rbs_optional(type, location);
553
+ } else {
554
+ return type;
555
+ }
556
+ }
557
+
558
+ static void initialize_method_params(method_params *params){
559
+ params->required_positionals = rb_ary_new();
560
+ params->optional_positionals = rb_ary_new();
561
+ params->rest_positionals = Qnil;
562
+ params->trailing_positionals = rb_ary_new();
563
+ params->required_keywords = rb_hash_new();
564
+ params->optional_keywords = rb_hash_new();
565
+ params->rest_keywords = Qnil;
566
+ }
567
+
568
+ /*
569
+ function ::= {} `(` params `)` `{` `(` params `)` `->` optional `}` `->` <optional>
570
+ | {} `(` params `)` `->` <optional>
571
+ | {} `{` `(` params `)` `->` optional `}` `->` <optional>
572
+ | {} `{` `->` optional `}` `->` <optional>
573
+ | {} `->` <optional>
574
+ */
575
+ static void parse_function(parserstate *state, VALUE *function, VALUE *block) {
576
+ method_params params;
577
+ initialize_method_params(&params);
578
+
579
+ if (state->next_token.type == pLPAREN) {
580
+ parser_advance(state);
581
+ parse_params(state, &params);
582
+ parser_advance_assert(state, pRPAREN);
583
+ }
584
+
585
+ VALUE required = Qtrue;
586
+ if (state->next_token.type == pQUESTION && state->next_token2.type == pLBRACE) {
587
+ // Optional block
588
+ required = Qfalse;
589
+ parser_advance(state);
590
+ }
591
+ if (state->next_token.type == pLBRACE) {
592
+ parser_advance(state);
593
+
594
+ method_params block_params;
595
+ initialize_method_params(&block_params);
596
+
597
+ if (state->next_token.type == pLPAREN) {
598
+ parser_advance(state);
599
+ parse_params(state, &block_params);
600
+ parser_advance_assert(state, pRPAREN);
601
+ }
602
+
603
+ parser_advance_assert(state, pARROW);
604
+ VALUE block_return_type = parse_optional(state);
605
+
606
+ *block = rbs_block(
607
+ rbs_function(
608
+ block_params.required_positionals,
609
+ block_params.optional_positionals,
610
+ block_params.rest_positionals,
611
+ block_params.trailing_positionals,
612
+ block_params.required_keywords,
613
+ block_params.optional_keywords,
614
+ block_params.rest_keywords,
615
+ block_return_type
616
+ ),
617
+ required
618
+ );
619
+
620
+ parser_advance_assert(state, pRBRACE);
621
+ }
622
+
623
+ parser_advance_assert(state, pARROW);
624
+ VALUE type = parse_optional(state);
625
+
626
+ *function = rbs_function(
627
+ params.required_positionals,
628
+ params.optional_positionals,
629
+ params.rest_positionals,
630
+ params.trailing_positionals,
631
+ params.required_keywords,
632
+ params.optional_keywords,
633
+ params.rest_keywords,
634
+ type
635
+ );
636
+ }
637
+
638
+ /*
639
+ proc_type ::= {`^`} <function>
640
+ */
641
+ static VALUE parse_proc_type(parserstate *state) {
642
+ position start = state->current_token.range.start;
643
+ VALUE function = Qnil;
644
+ VALUE block = Qnil;
645
+ parse_function(state, &function, &block);
646
+ position end = state->current_token.range.end;
647
+ VALUE loc = rbs_location_pp(state->buffer, &start, &end);
648
+
649
+ return rbs_proc(function, block, loc);
650
+ }
651
+
652
+ /**
653
+ * ... `{` ... `}` ...
654
+ * > >
655
+ * */
656
+ /*
657
+ record_attributes ::= {`{`} record_attribute... <record_attribute> `}`
658
+
659
+ record_attribute ::= {} keyword_token `:` <type>
660
+ | {} literal_type `=>` <type>
661
+ */
662
+ VALUE parse_record_attributes(parserstate *state) {
663
+ VALUE hash = rb_hash_new();
664
+
665
+ while (true) {
666
+ VALUE key;
667
+ VALUE type;
668
+
669
+ if (is_keyword(state)) {
670
+ // { foo: type } syntax
671
+ key = parse_keyword_key(state);
672
+ parser_advance_assert(state, pCOLON);
673
+ } else {
674
+ // { key => type } syntax
675
+ switch (state->next_token.type) {
676
+ case tSYMBOL:
677
+ case tSQSYMBOL:
678
+ case tDQSYMBOL:
679
+ case tSQSTRING:
680
+ case tDQSTRING:
681
+ case tINTEGER:
682
+ case kTRUE:
683
+ case kFALSE:
684
+ key = rb_funcall(parse_type(state), rb_intern("literal"), 0);
685
+ break;
686
+ default:
687
+ rbs_abort();
688
+ }
689
+ parser_advance_assert(state, pFATARROW);
690
+ }
691
+ type = parse_type(state);
692
+ rb_hash_aset(hash, key, type);
693
+
694
+ if (parser_advance_if(state, pCOMMA)) {
695
+ if (state->next_token.type == pRBRACE) {
696
+ break;
697
+ }
698
+ } else {
699
+ break;
700
+ }
701
+ }
702
+
703
+ return hash;
704
+ }
705
+
706
+ /*
707
+ symbol ::= {<tSYMBOL>}
708
+ */
709
+ static VALUE parse_symbol(parserstate *state) {
710
+ VALUE string = state->lexstate->string;
711
+ rb_encoding *enc = rb_enc_get(string);
712
+
713
+ int offset_bytes = rb_enc_codelen(':', enc);
714
+ int bytes = token_bytes(state->current_token) - offset_bytes;
715
+
716
+ VALUE literal;
717
+
718
+ switch (state->current_token.type)
719
+ {
720
+ case tSYMBOL: {
721
+ char *buffer = peek_token(state->lexstate, state->current_token);
722
+ literal = ID2SYM(rb_intern3(buffer+offset_bytes, bytes, enc));
723
+ break;
724
+ }
725
+ case tDQSYMBOL:
726
+ case tSQSYMBOL: {
727
+ literal = rb_funcall(
728
+ rbs_unquote_string(state, state->current_token.range, offset_bytes),
729
+ rb_intern("to_sym"),
730
+ 0
731
+ );
732
+ break;
733
+ }
734
+ default:
735
+ rbs_abort();
736
+ }
737
+
738
+ return rbs_literal(
739
+ literal,
740
+ rbs_location_current_token(state)
741
+ );
742
+ }
743
+
744
+ /*
745
+ simple ::= {} `(` type <`)`>
746
+ | {} <base type>
747
+ | {} <type_name>
748
+ | {} class_instance `[` type_list <`]`>
749
+ | {} `singleton` `(` type_name <`)`>
750
+ | {} `[` type_list <`]`>
751
+ | {} `{` record_attributes <`}`>
752
+ | {} `^` <function>
753
+ */
754
+ static VALUE parse_simple(parserstate *state) {
755
+ parser_advance(state);
756
+
757
+ switch (state->current_token.type) {
758
+ case pLPAREN: {
759
+ VALUE type = parse_type(state);
760
+ parser_advance_assert(state, pRPAREN);
761
+ return type;
762
+ }
763
+ case kBOOL:
764
+ return rbs_base_type(RBS_Types_Bases_Bool, rbs_location_current_token(state));
765
+ case kBOT:
766
+ return rbs_base_type(RBS_Types_Bases_Bottom, rbs_location_current_token(state));
767
+ case kCLASS:
768
+ return rbs_base_type(RBS_Types_Bases_Class, rbs_location_current_token(state));
769
+ case kINSTANCE:
770
+ return rbs_base_type(RBS_Types_Bases_Instance, rbs_location_current_token(state));
771
+ case kNIL:
772
+ return rbs_base_type(RBS_Types_Bases_Nil, rbs_location_current_token(state));
773
+ case kSELF:
774
+ return rbs_base_type(RBS_Types_Bases_Self, rbs_location_current_token(state));
775
+ case kTOP:
776
+ return rbs_base_type(RBS_Types_Bases_Top, rbs_location_current_token(state));
777
+ case kVOID:
778
+ return rbs_base_type(RBS_Types_Bases_Void, rbs_location_current_token(state));
779
+ case kUNTYPED:
780
+ return rbs_base_type(RBS_Types_Bases_Any, rbs_location_current_token(state));
781
+ case tINTEGER: {
782
+ VALUE literal = rb_funcall(
783
+ string_of_loc(state, state->current_token.range.start, state->current_token.range.end),
784
+ rb_intern("to_i"),
785
+ 0
786
+ );
787
+ return rbs_literal(
788
+ literal,
789
+ rbs_location_current_token(state)
790
+ );
791
+ }
792
+ case kTRUE:
793
+ return rbs_literal(Qtrue, rbs_location_current_token(state));
794
+ case kFALSE:
795
+ return rbs_literal(Qfalse, rbs_location_current_token(state));
796
+ case tSQSTRING:
797
+ case tDQSTRING: {
798
+ VALUE literal = rbs_unquote_string(state, state->current_token.range, 0);
799
+ return rbs_literal(
800
+ literal,
801
+ rbs_location_current_token(state)
802
+ );
803
+ }
804
+ case tSYMBOL:
805
+ case tSQSYMBOL:
806
+ case tDQSYMBOL: {
807
+ return parse_symbol(state);
808
+ }
809
+ case tUIDENT: {
810
+ ID name = INTERN_TOKEN(state, state->current_token);
811
+ if (parser_typevar_member(state, name)) {
812
+ return rbs_variable(ID2SYM(name), rbs_location_current_token(state));
813
+ }
814
+ // fallthrough for type name
815
+ }
816
+ case tULIDENT:
817
+ // fallthrough
818
+ case pCOLON2: {
819
+ range name_range;
820
+ range args_range;
821
+ range type_range;
822
+
823
+ VALUE typename = parse_type_name(state, INTERFACE_NAME | CLASS_NAME | ALIAS_NAME, &name_range);
824
+ VALUE types = rb_ary_new();
825
+
826
+ TypeNameKind kind;
827
+ if (state->current_token.type == tUIDENT) {
828
+ kind = CLASS_NAME;
829
+ } else if (state->current_token.type == tULIDENT) {
830
+ kind = INTERFACE_NAME;
831
+ } else if (state->current_token.type == tLIDENT) {
832
+ kind = ALIAS_NAME;
833
+ } else {
834
+ rbs_abort();
835
+ }
836
+
837
+ if (state->next_token.type == pLBRACKET) {
838
+ parser_advance(state);
839
+ args_range.start = state->current_token.range.start;
840
+ parse_type_list(state, pRBRACKET, types);
841
+ parser_advance_assert(state, pRBRACKET);
842
+ args_range.end = state->current_token.range.end;
843
+ } else {
844
+ args_range = NULL_RANGE;
845
+ }
846
+
847
+ type_range.start = name_range.start;
848
+ type_range.end = nonnull_pos_or(args_range.end, name_range.end);
849
+
850
+ VALUE location = rbs_new_location(state->buffer, type_range);
851
+ rbs_loc *loc = rbs_check_location(location);
852
+ rbs_loc_add_required_child(loc, rb_intern("name"), name_range);
853
+ rbs_loc_add_optional_child(loc, rb_intern("args"), args_range);
854
+
855
+ if (kind == CLASS_NAME) {
856
+ return rbs_class_instance(typename, types, location);
857
+ } else if (kind == INTERFACE_NAME) {
858
+ return rbs_interface(typename, types, location);
859
+ } else if (kind == ALIAS_NAME) {
860
+ return rbs_alias(typename, location);
861
+ } else {
862
+ return Qnil;
863
+ }
864
+ }
865
+ case tLIDENT: {
866
+ VALUE location = rbs_location_current_token(state);
867
+ rbs_loc *loc = rbs_check_location(location);
868
+ rbs_loc_add_required_child(loc, rb_intern("name"), state->current_token.range);
869
+ rbs_loc_add_optional_child(loc, rb_intern("args"), NULL_RANGE);
870
+ VALUE typename = parse_type_name(state, ALIAS_NAME, NULL);
871
+ return rbs_alias(typename, location);
872
+ }
873
+ case kSINGLETON: {
874
+ range name_range;
875
+ range type_range;
876
+
877
+ type_range.start = state->current_token.range.start;
878
+ parser_advance_assert(state, pLPAREN);
879
+ parser_advance(state);
880
+
881
+ VALUE typename = parse_type_name(state, CLASS_NAME, &name_range);
882
+
883
+ parser_advance_assert(state, pRPAREN);
884
+ type_range.end = state->current_token.range.end;
885
+
886
+ VALUE location = rbs_new_location(state->buffer, type_range);
887
+ rbs_loc *loc = rbs_check_location(location);
888
+ rbs_loc_add_required_child(loc, rb_intern("name"), name_range);
889
+
890
+ return rbs_class_singleton(typename, location);
891
+ }
892
+ case pLBRACKET: {
893
+ range rg;
894
+ rg.start = state->current_token.range.start;
895
+ VALUE types = rb_ary_new();
896
+ if (state->next_token.type != pRBRACKET) {
897
+ parse_type_list(state, pRBRACKET, types);
898
+ }
899
+ parser_advance_assert(state, pRBRACKET);
900
+ rg.end = state->current_token.range.end;
901
+
902
+ return rbs_tuple(types, rbs_new_location(state->buffer, rg));
903
+ }
904
+ case pLBRACE: {
905
+ position start = state->current_token.range.start;
906
+ VALUE fields = parse_record_attributes(state);
907
+ parser_advance_assert(state, pRBRACE);
908
+ position end = state->current_token.range.end;
909
+ VALUE location = rbs_location_pp(state->buffer, &start, &end);
910
+ return rbs_record(fields, location);
911
+ }
912
+ case pHAT: {
913
+ return parse_proc_type(state);
914
+ }
915
+ default:
916
+ raise_syntax_error(
917
+ state,
918
+ state->current_token,
919
+ "unexpected token for simple type"
920
+ );
921
+ }
922
+ }
923
+
924
+ /*
925
+ intersection ::= {} optional `&` ... '&' <optional>
926
+ | {} <optional>
927
+ */
928
+ static VALUE parse_intersection(parserstate *state) {
929
+ range rg;
930
+
931
+ rg.start = state->next_token.range.start;
932
+ VALUE type = parse_optional(state);
933
+ VALUE intersection_types = rb_ary_new();
934
+
935
+ rb_ary_push(intersection_types, type);
936
+ while (state->next_token.type == pAMP) {
937
+ parser_advance(state);
938
+ rb_ary_push(intersection_types, parse_optional(state));
939
+ }
940
+
941
+ rg.end = state->current_token.range.end;
942
+
943
+ if (rb_array_len(intersection_types) > 1) {
944
+ VALUE location = rbs_new_location(state->buffer, rg);
945
+ type = rbs_intersection(intersection_types, location);
946
+ }
947
+
948
+ return type;
949
+ }
950
+
951
+ /*
952
+ union ::= {} intersection '|' ... '|' <intersection>
953
+ | {} <intersection>
954
+ */
955
+ VALUE parse_type(parserstate *state) {
956
+ range rg;
957
+
958
+ rg.start = state->next_token.range.start;
959
+ VALUE type = parse_intersection(state);
960
+ VALUE union_types = rb_ary_new();
961
+
962
+ rb_ary_push(union_types, type);
963
+ while (state->next_token.type == pBAR) {
964
+ parser_advance(state);
965
+ rb_ary_push(union_types, parse_intersection(state));
966
+ }
967
+
968
+ rg.end = state->current_token.range.end;
969
+
970
+ if (rb_array_len(union_types) > 1) {
971
+ VALUE location = rbs_new_location(state->buffer, rg);
972
+ type = rbs_union(union_types, location);
973
+ }
974
+
975
+ return type;
976
+ }
977
+
978
+ /*
979
+ method_type ::= {} `[` type_vars `]` <function>
980
+ | {} <function>
981
+ */
982
+ VALUE parse_method_type(parserstate *state) {
983
+ VALUE function = Qnil;
984
+ VALUE block = Qnil;
985
+ id_table *table = parser_push_typevar_table(state, false);
986
+
987
+ position start = state->next_token.range.start;
988
+
989
+ if (state->next_token.type == pLBRACKET) {
990
+ parser_advance(state);
991
+
992
+ while (true) {
993
+ parser_advance_assert(state, tUIDENT);
994
+ ID name = INTERN_TOKEN(state, state->current_token);
995
+ parser_insert_typevar(state, name);
996
+
997
+ if (state->next_token.type == pCOMMA) {
998
+ parser_advance(state);
999
+ if (state->next_token.type == pRBRACKET) {
1000
+ break;
1001
+ }
1002
+ } else {
1003
+ break;
1004
+ }
1005
+ }
1006
+
1007
+ parser_advance_assert(state, pRBRACKET);
1008
+ }
1009
+
1010
+ parse_function(state, &function, &block);
1011
+
1012
+ position end = state->current_token.range.end;
1013
+
1014
+ VALUE type_params = rb_ary_new();
1015
+ for (size_t i = 0; i < table->count; i++) {
1016
+ rb_ary_push(type_params, ID2SYM(table->ids[i]));
1017
+ }
1018
+
1019
+ parser_pop_typevar_table(state);
1020
+
1021
+ return rbs_method_type(
1022
+ type_params,
1023
+ function,
1024
+ block,
1025
+ rbs_location_pp(state->buffer, &start, &end)
1026
+ );
1027
+ }
1028
+
1029
+ /*
1030
+ global_decl ::= {tGIDENT} `:` <type>
1031
+ */
1032
+ VALUE parse_global_decl(parserstate *state) {
1033
+ range decl_range;
1034
+ range name_range, colon_range;
1035
+
1036
+ VALUE typename;
1037
+ VALUE type;
1038
+ VALUE location;
1039
+ VALUE comment;
1040
+
1041
+ rbs_loc *loc;
1042
+
1043
+ decl_range.start = state->current_token.range.start;
1044
+ comment = get_comment(state, decl_range.start.line);
1045
+
1046
+ name_range = state->current_token.range;
1047
+ typename = ID2SYM(INTERN_TOKEN(state, state->current_token));
1048
+
1049
+ parser_advance_assert(state, pCOLON);
1050
+ colon_range = state->current_token.range;
1051
+
1052
+ type = parse_type(state);
1053
+ decl_range.end = state->current_token.range.end;
1054
+
1055
+ location = rbs_new_location(state->buffer, decl_range);
1056
+ loc = rbs_check_location(location);
1057
+ rbs_loc_add_required_child(loc, rb_intern("name"), name_range);
1058
+ rbs_loc_add_required_child(loc, rb_intern("colon"), colon_range);
1059
+
1060
+ return rbs_ast_decl_global(typename, type, location, comment);
1061
+ }
1062
+
1063
+ /*
1064
+ const_decl ::= {const_name} `:` <type>
1065
+ */
1066
+ VALUE parse_const_decl(parserstate *state) {
1067
+ range decl_range;
1068
+ range name_range, colon_range;
1069
+
1070
+ VALUE typename;
1071
+ VALUE type;
1072
+ VALUE location;
1073
+ VALUE comment;
1074
+
1075
+ rbs_loc *loc;
1076
+
1077
+ decl_range.start = state->current_token.range.start;
1078
+ comment = get_comment(state, decl_range.start.line);
1079
+
1080
+ typename = parse_type_name(state, CLASS_NAME, &name_range);
1081
+
1082
+ parser_advance_assert(state, pCOLON);
1083
+ colon_range = state->current_token.range;
1084
+
1085
+ type = parse_type(state);
1086
+ decl_range.end = state->current_token.range.end;
1087
+
1088
+ location = rbs_new_location(state->buffer, decl_range);
1089
+ loc = rbs_check_location(location);
1090
+ rbs_loc_add_required_child(loc, rb_intern("name"), name_range);
1091
+ rbs_loc_add_required_child(loc, rb_intern("colon"), colon_range);
1092
+
1093
+ return rbs_ast_decl_constant(typename, type, location, comment);
1094
+ }
1095
+
1096
+ /*
1097
+ type_decl ::= {kTYPE} alias_name `=` <type>
1098
+ */
1099
+ VALUE parse_type_decl(parserstate *state, position comment_pos, VALUE annotations) {
1100
+ range decl_range;
1101
+ range keyword_range, name_range, eq_range;
1102
+
1103
+ decl_range.start = state->current_token.range.start;
1104
+ comment_pos = nonnull_pos_or(comment_pos, decl_range.start);
1105
+
1106
+ keyword_range = state->current_token.range;
1107
+
1108
+ parser_advance(state);
1109
+ VALUE typename = parse_type_name(state, ALIAS_NAME, &name_range);
1110
+
1111
+ parser_advance_assert(state, pEQ);
1112
+ eq_range = state->current_token.range;
1113
+
1114
+ VALUE type = parse_type(state);
1115
+ decl_range.end = state->current_token.range.end;
1116
+
1117
+ VALUE location = rbs_new_location(state->buffer, decl_range);
1118
+ rbs_loc *loc = rbs_check_location(location);
1119
+ rbs_loc_add_required_child(loc, rb_intern("keyword"), keyword_range);
1120
+ rbs_loc_add_required_child(loc, rb_intern("name"), name_range);
1121
+ rbs_loc_add_required_child(loc, rb_intern("eq"), eq_range);
1122
+
1123
+ return rbs_ast_decl_alias(
1124
+ typename,
1125
+ type,
1126
+ annotations,
1127
+ location,
1128
+ get_comment(state, comment_pos.line)
1129
+ );
1130
+ }
1131
+
1132
+ /*
1133
+ annotation ::= {<tANNOTATION>}
1134
+ */
1135
+ VALUE parse_annotation(parserstate *state) {
1136
+ VALUE content = rb_funcall(state->buffer, rb_intern("content"), 0);
1137
+ rb_encoding *enc = rb_enc_get(content);
1138
+
1139
+ range rg = state->current_token.range;
1140
+
1141
+ int offset_bytes = rb_enc_codelen('%', enc) + rb_enc_codelen('a', enc);
1142
+
1143
+ unsigned int open_char = rb_enc_mbc_to_codepoint(
1144
+ RSTRING_PTR(state->lexstate->string) + rg.start.byte_pos + offset_bytes,
1145
+ RSTRING_END(state->lexstate->string),
1146
+ enc
1147
+ );
1148
+
1149
+ unsigned int close_char;
1150
+
1151
+ switch (open_char) {
1152
+ case '{':
1153
+ close_char = '}';
1154
+ break;
1155
+ case '(':
1156
+ close_char = ')';
1157
+ break;
1158
+ case '[':
1159
+ close_char = ']';
1160
+ break;
1161
+ case '<':
1162
+ close_char = '>';
1163
+ break;
1164
+ case '|':
1165
+ close_char = '|';
1166
+ break;
1167
+ default:
1168
+ rbs_abort();
1169
+ }
1170
+
1171
+ int open_bytes = rb_enc_codelen(open_char, enc);
1172
+ int close_bytes = rb_enc_codelen(close_char, enc);
1173
+
1174
+ char *buffer = RSTRING_PTR(state->lexstate->string) + rg.start.byte_pos + offset_bytes + open_bytes;
1175
+ VALUE string = rb_enc_str_new(
1176
+ buffer,
1177
+ rg.end.byte_pos - rg.start.byte_pos - offset_bytes - open_bytes - close_bytes,
1178
+ enc
1179
+ );
1180
+ rb_funcall(string, rb_intern("strip!"), 0);
1181
+
1182
+ VALUE location = rbs_location_current_token(state);
1183
+
1184
+ return rbs_ast_annotation(string, location);
1185
+ }
1186
+
1187
+ /*
1188
+ module_type_params ::= {} `[` module_type_param `,` ... <`]`>
1189
+ | {<>}
1190
+
1191
+ module_type_param ::= kUNCHECKED? (kIN|kOUT|) tUIDENT
1192
+ */
1193
+ VALUE parse_module_type_params(parserstate *state, range *rg) {
1194
+ VALUE params = rbs_ast_decl_module_type_params();
1195
+
1196
+ if (state->next_token.type == pLBRACKET) {
1197
+ parser_advance(state);
1198
+
1199
+ rg->start = state->current_token.range.start;
1200
+
1201
+ while (true) {
1202
+ VALUE name;
1203
+ VALUE unchecked = Qfalse;
1204
+ VALUE variance = ID2SYM(rb_intern("invariant"));
1205
+
1206
+ range param_range = NULL_RANGE;
1207
+ range name_range;
1208
+ range variance_range = NULL_RANGE;
1209
+ range unchecked_range = NULL_RANGE;
1210
+
1211
+ param_range.start = state->next_token.range.start;
1212
+
1213
+ if (state->next_token.type == kUNCHECKED) {
1214
+ unchecked = Qtrue;
1215
+ parser_advance(state);
1216
+ unchecked_range = state->current_token.range;
1217
+ }
1218
+
1219
+ if (state->next_token.type == kIN || state->next_token.type == kOUT) {
1220
+ switch (state->next_token.type) {
1221
+ case kIN:
1222
+ variance = ID2SYM(rb_intern("contravariant"));
1223
+ break;
1224
+ case kOUT:
1225
+ variance = ID2SYM(rb_intern("covariant"));
1226
+ break;
1227
+ default:
1228
+ rbs_abort();
1229
+ }
1230
+
1231
+ parser_advance(state);
1232
+ variance_range = state->current_token.range;
1233
+ }
1234
+
1235
+ parser_advance_assert(state, tUIDENT);
1236
+ name_range = state->current_token.range;
1237
+ param_range.end = state->current_token.range.end;
1238
+
1239
+ ID id = INTERN_TOKEN(state, state->current_token);
1240
+ name = ID2SYM(id);
1241
+
1242
+ parser_insert_typevar(state, id);
1243
+
1244
+ VALUE location = rbs_new_location(state->buffer, param_range);
1245
+ rbs_loc *loc = rbs_check_location(location);
1246
+ rbs_loc_add_required_child(loc, rb_intern("name"), name_range);
1247
+ rbs_loc_add_optional_child(loc, rb_intern("variance"), variance_range);
1248
+ rbs_loc_add_optional_child(loc, rb_intern("unchecked"), unchecked_range);
1249
+
1250
+ VALUE param = rbs_ast_decl_module_type_params_param(name, variance, unchecked, location);
1251
+ rb_funcall(params, rb_intern("add"), 1, param);
1252
+
1253
+ if (state->next_token.type == pCOMMA) {
1254
+ parser_advance(state);
1255
+ }
1256
+
1257
+ if (state->next_token.type == pRBRACKET) {
1258
+ break;
1259
+ }
1260
+ }
1261
+
1262
+ parser_advance_assert(state, pRBRACKET);
1263
+ rg->end = state->current_token.range.end;
1264
+ } else {
1265
+ *rg = NULL_RANGE;
1266
+ }
1267
+
1268
+ return params;
1269
+ }
1270
+
1271
+ /*
1272
+ annotations ::= {} annotation ... <annotation>
1273
+ | {<>}
1274
+ */
1275
+ void parse_annotations(parserstate *state, VALUE annotations, position *annot_pos) {
1276
+ *annot_pos = NullPosition;
1277
+
1278
+ while (true) {
1279
+ if (state->next_token.type == tANNOTATION) {
1280
+ parser_advance(state);
1281
+
1282
+ if (null_position_p((*annot_pos))) {
1283
+ *annot_pos = state->current_token.range.start;
1284
+ }
1285
+
1286
+ rb_ary_push(annotations, parse_annotation(state));
1287
+ } else {
1288
+ break;
1289
+ }
1290
+ }
1291
+ }
1292
+
1293
+ /*
1294
+ method_name ::= {} <IDENT | keyword>
1295
+ | {} (IDENT | keyword)~<`?`>
1296
+ */
1297
+ VALUE parse_method_name(parserstate *state, range *range) {
1298
+ parser_advance(state);
1299
+
1300
+ switch (state->current_token.type)
1301
+ {
1302
+ case tUIDENT:
1303
+ case tLIDENT:
1304
+ case tULIDENT:
1305
+ case tULLIDENT:
1306
+ KEYWORD_CASES
1307
+ if (state->next_token.type == pQUESTION && state->current_token.range.end.byte_pos == state->next_token.range.start.byte_pos) {
1308
+ range->start = state->current_token.range.start;
1309
+ range->end = state->next_token.range.end;
1310
+ parser_advance(state);
1311
+
1312
+ ID id = rb_intern3(
1313
+ RSTRING_PTR(state->lexstate->string) + range->start.byte_pos,
1314
+ range->end.byte_pos - range->start.byte_pos,
1315
+ rb_enc_get(state->lexstate->string)
1316
+ );
1317
+
1318
+ return ID2SYM(id);
1319
+ } else {
1320
+ *range = state->current_token.range;
1321
+ return ID2SYM(INTERN_TOKEN(state, state->current_token));
1322
+ }
1323
+
1324
+ case tBANGIDENT:
1325
+ case tEQIDENT:
1326
+ *range = state->current_token.range;
1327
+ return ID2SYM(INTERN_TOKEN(state, state->current_token));
1328
+
1329
+ case tQIDENT:
1330
+ return rb_to_symbol(rbs_unquote_string(state, state->current_token.range, 0));
1331
+
1332
+ case pBAR:
1333
+ case pHAT:
1334
+ case pAMP:
1335
+ case pSTAR:
1336
+ case pSTAR2:
1337
+ case pLT:
1338
+ case tOPERATOR:
1339
+ *range = state->current_token.range;
1340
+ return ID2SYM(INTERN_TOKEN(state, state->current_token));
1341
+
1342
+ default:
1343
+ raise_syntax_error(
1344
+ state,
1345
+ state->current_token,
1346
+ "unexpected token for method name"
1347
+ );
1348
+ }
1349
+ }
1350
+
1351
+ typedef enum {
1352
+ INSTANCE_KIND,
1353
+ SINGLETON_KIND,
1354
+ INSTANCE_SINGLETON_KIND
1355
+ } InstanceSingletonKind;
1356
+
1357
+ /*
1358
+ instance_singleton_kind ::= {<>}
1359
+ | {} kSELF <`.`>
1360
+ | {} kSELF~`?` <`.`>
1361
+
1362
+ @param allow_selfq `true` to accept `self?` kind.
1363
+ */
1364
+ InstanceSingletonKind parse_instance_singleton_kind(parserstate *state, bool allow_selfq, range *rg) {
1365
+ InstanceSingletonKind kind = INSTANCE_KIND;
1366
+
1367
+ if (state->next_token.type == kSELF) {
1368
+ range self_range = state->next_token.range;
1369
+
1370
+ if (state->next_token2.type == pDOT) {
1371
+ parser_advance(state);
1372
+ parser_advance(state);
1373
+ kind = SINGLETON_KIND;
1374
+ rg->start = self_range.start;
1375
+ rg->end = state->current_token.range.end;
1376
+ } else if (
1377
+ state->next_token2.type == pQUESTION
1378
+ && state->next_token.range.end.char_pos == state->next_token2.range.start.char_pos
1379
+ && state->next_token3.type == pDOT
1380
+ && allow_selfq) {
1381
+ parser_advance(state);
1382
+ parser_advance(state);
1383
+ parser_advance(state);
1384
+ kind = INSTANCE_SINGLETON_KIND;
1385
+ rg->start = self_range.start;
1386
+ rg->end = state->current_token.range.end;
1387
+ }
1388
+ } else {
1389
+ *rg = NULL_RANGE;
1390
+ }
1391
+
1392
+ return kind;
1393
+ }
1394
+
1395
+ /**
1396
+ * def_member ::= {kDEF} method_name `:` <method_types>
1397
+ *
1398
+ * method_types ::= {} <method_type>
1399
+ * | {} <`...`>
1400
+ * | {} method_type `|` <method_types>
1401
+ *
1402
+ * @param instance_only `true` to reject singleton method definition.
1403
+ * @param accept_overload `true` to accept overloading (...) definition.
1404
+ * */
1405
+ VALUE parse_member_def(parserstate *state, bool instance_only, bool accept_overload, position comment_pos, VALUE annotations) {
1406
+ range member_range;
1407
+ range keyword_range;
1408
+ range name_range;
1409
+ range kind_range;
1410
+ range overload_range = NULL_RANGE;
1411
+
1412
+ keyword_range = state->current_token.range;
1413
+ member_range.start = keyword_range.start;
1414
+
1415
+ comment_pos = nonnull_pos_or(comment_pos, keyword_range.start);
1416
+ VALUE comment = get_comment(state, comment_pos.line);
1417
+
1418
+ InstanceSingletonKind kind;
1419
+ if (instance_only) {
1420
+ kind_range = NULL_RANGE;
1421
+ kind = INSTANCE_KIND;
1422
+ } else {
1423
+ kind = parse_instance_singleton_kind(state, true, &kind_range);
1424
+ }
1425
+
1426
+ VALUE name = parse_method_name(state, &name_range);
1427
+ VALUE method_types = rb_ary_new();
1428
+ VALUE overload = Qfalse;
1429
+
1430
+ parser_advance_assert(state, pCOLON);
1431
+
1432
+ parser_push_typevar_table(state, kind != INSTANCE_KIND);
1433
+
1434
+ bool loop = true;
1435
+ while (loop) {
1436
+ switch (state->next_token.type) {
1437
+ case pLPAREN:
1438
+ case pARROW:
1439
+ case pLBRACE:
1440
+ case pLBRACKET:
1441
+ case pQUESTION:
1442
+ rb_ary_push(method_types, parse_method_type(state));
1443
+ member_range.end = state->current_token.range.end;
1444
+ break;
1445
+
1446
+ case pDOT3:
1447
+ if (accept_overload) {
1448
+ overload = Qtrue;
1449
+ parser_advance(state);
1450
+ loop = false;
1451
+ overload_range = state->current_token.range;
1452
+ break;
1453
+ } else {
1454
+ raise_syntax_error(
1455
+ state,
1456
+ state->next_token,
1457
+ "unexpected overloading method definition"
1458
+ );
1459
+ }
1460
+
1461
+ default:
1462
+ raise_syntax_error(
1463
+ state,
1464
+ state->next_token,
1465
+ "unexpected token for method type"
1466
+ );
1467
+ }
1468
+
1469
+ if (state->next_token.type == pBAR) {
1470
+ parser_advance(state);
1471
+ } else {
1472
+ loop = false;
1473
+ }
1474
+ }
1475
+
1476
+ parser_pop_typevar_table(state);
1477
+
1478
+ VALUE k;
1479
+ switch (kind) {
1480
+ case INSTANCE_KIND:
1481
+ k = ID2SYM(rb_intern("instance"));
1482
+ break;
1483
+ case SINGLETON_KIND:
1484
+ k = ID2SYM(rb_intern("singleton"));
1485
+ break;
1486
+ case INSTANCE_SINGLETON_KIND:
1487
+ k = ID2SYM(rb_intern("singleton_instance"));
1488
+ break;
1489
+ }
1490
+
1491
+ VALUE location = rbs_new_location(state->buffer, member_range);
1492
+ rbs_loc *loc = rbs_check_location(location);
1493
+ rbs_loc_add_required_child(loc, rb_intern("keyword"), keyword_range);
1494
+ rbs_loc_add_required_child(loc, rb_intern("name"), name_range);
1495
+ rbs_loc_add_optional_child(loc, rb_intern("kind"), kind_range);
1496
+ rbs_loc_add_optional_child(loc, rb_intern("overload"), overload_range);
1497
+
1498
+ return rbs_ast_members_method_definition(
1499
+ name,
1500
+ k,
1501
+ method_types,
1502
+ annotations,
1503
+ location,
1504
+ comment,
1505
+ overload
1506
+ );
1507
+ }
1508
+
1509
+ /**
1510
+ * class_instance_name ::= {} <class_name>
1511
+ * | {} class_name `[` type args <`]`>
1512
+ *
1513
+ * @param kind
1514
+ * */
1515
+ void class_instance_name(parserstate *state, TypeNameKind kind, VALUE *name, VALUE args, range *name_range, range *args_range) {
1516
+ parser_advance(state);
1517
+
1518
+ *name = parse_type_name(state, kind, name_range);
1519
+
1520
+ if (state->next_token.type == pLBRACKET) {
1521
+ parser_advance(state);
1522
+ args_range->start = state->current_token.range.start;
1523
+ parse_type_list(state, pRBRACKET, args);
1524
+ parser_advance_assert(state, pRBRACKET);
1525
+ args_range->end = state->current_token.range.end;
1526
+ } else {
1527
+ *args_range = NULL_RANGE;
1528
+ }
1529
+ }
1530
+
1531
+ /**
1532
+ * mixin_member ::= {kINCLUDE} <class_instance_name>
1533
+ * | {kPREPEND} <class_instance_name>
1534
+ * | {kEXTEND} <class_instance_name>
1535
+ *
1536
+ * @param from_interface `true` when the member is in an interface.
1537
+ * */
1538
+ VALUE parse_mixin_member(parserstate *state, bool from_interface, position comment_pos, VALUE annotations) {
1539
+ range member_range;
1540
+ range name_range;
1541
+ range keyword_range;
1542
+ range args_range = NULL_RANGE;
1543
+ bool reset_typevar_scope;
1544
+
1545
+ member_range.start = state->current_token.range.start;
1546
+ comment_pos = nonnull_pos_or(comment_pos, member_range.start);
1547
+
1548
+ keyword_range = state->current_token.range;
1549
+
1550
+ VALUE klass = Qnil;
1551
+ switch (state->current_token.type)
1552
+ {
1553
+ case kINCLUDE:
1554
+ klass = RBS_AST_Members_Include;
1555
+ reset_typevar_scope = false;
1556
+ break;
1557
+ case kEXTEND:
1558
+ klass = RBS_AST_Members_Extend;
1559
+ reset_typevar_scope = true;
1560
+ break;
1561
+ case kPREPEND:
1562
+ klass = RBS_AST_Members_Prepend;
1563
+ reset_typevar_scope = false;
1564
+ break;
1565
+ default:
1566
+ rbs_abort();
1567
+ }
1568
+
1569
+ if (from_interface) {
1570
+ if (state->current_token.type != kINCLUDE) {
1571
+ raise_syntax_error(
1572
+ state,
1573
+ state->current_token,
1574
+ "unexpected mixin in interface declaration"
1575
+ );
1576
+ }
1577
+ }
1578
+
1579
+ parser_push_typevar_table(state, reset_typevar_scope);
1580
+
1581
+ VALUE name;
1582
+ VALUE args = rb_ary_new();
1583
+ class_instance_name(
1584
+ state,
1585
+ from_interface ? INTERFACE_NAME : (INTERFACE_NAME | CLASS_NAME),
1586
+ &name, args, &name_range, &args_range
1587
+ );
1588
+
1589
+ parser_pop_typevar_table(state);
1590
+
1591
+ member_range.end = state->current_token.range.end;
1592
+
1593
+ VALUE location = rbs_new_location(state->buffer, member_range);
1594
+ rbs_loc *loc = rbs_check_location(location);
1595
+ rbs_loc_add_required_child(loc, rb_intern("name"), name_range);
1596
+ rbs_loc_add_required_child(loc, rb_intern("keyword"), keyword_range);
1597
+ rbs_loc_add_optional_child(loc, rb_intern("args"), args_range);
1598
+
1599
+ return rbs_ast_members_mixin(
1600
+ klass,
1601
+ name,
1602
+ args,
1603
+ annotations,
1604
+ location,
1605
+ get_comment(state, comment_pos.line)
1606
+ );
1607
+ }
1608
+
1609
+ /**
1610
+ * @code
1611
+ * alias_member ::= {kALIAS} method_name <method_name>
1612
+ * | {kALIAS} kSELF `.` method_name kSELF `.` <method_name>
1613
+ * @endcode
1614
+ *
1615
+ * @param[in] instance_only `true` to reject `self.` alias.
1616
+ * */
1617
+ VALUE parse_alias_member(parserstate *state, bool instance_only, position comment_pos, VALUE annotations) {
1618
+ range member_range;
1619
+ range keyword_range, new_name_range, old_name_range;
1620
+ range new_kind_range, old_kind_range;
1621
+
1622
+ member_range.start = state->current_token.range.start;
1623
+ keyword_range = state->current_token.range;
1624
+
1625
+ comment_pos = nonnull_pos_or(comment_pos, member_range.start);
1626
+ VALUE comment = get_comment(state, comment_pos.line);
1627
+
1628
+ VALUE new_name;
1629
+ VALUE old_name;
1630
+ VALUE kind;
1631
+
1632
+ if (!instance_only && state->next_token.type == kSELF) {
1633
+ kind = ID2SYM(rb_intern("singleton"));
1634
+
1635
+ new_kind_range.start = state->next_token.range.start;
1636
+ new_kind_range.end = state->next_token2.range.end;
1637
+ parser_advance_assert(state, kSELF);
1638
+ parser_advance_assert(state, pDOT);
1639
+ new_name = parse_method_name(state, &new_name_range);
1640
+
1641
+ old_kind_range.start = state->next_token.range.start;
1642
+ old_kind_range.end = state->next_token2.range.end;
1643
+ parser_advance_assert(state, kSELF);
1644
+ parser_advance_assert(state, pDOT);
1645
+ old_name = parse_method_name(state, &old_name_range);
1646
+ } else {
1647
+ kind = ID2SYM(rb_intern("instance"));
1648
+ new_name = parse_method_name(state, &new_name_range);
1649
+ old_name = parse_method_name(state, &old_name_range);
1650
+
1651
+ new_kind_range = NULL_RANGE;
1652
+ old_kind_range = NULL_RANGE;
1653
+ }
1654
+
1655
+ member_range.end = state->current_token.range.end;
1656
+ VALUE location = rbs_new_location(state->buffer, member_range);
1657
+ rbs_loc *loc = rbs_check_location(location);
1658
+ rbs_loc_add_required_child(loc, rb_intern("keyword"), keyword_range);
1659
+ rbs_loc_add_required_child(loc, rb_intern("new_name"), new_name_range);
1660
+ rbs_loc_add_required_child(loc, rb_intern("old_name"), old_name_range);
1661
+ rbs_loc_add_optional_child(loc, rb_intern("new_kind"), new_kind_range);
1662
+ rbs_loc_add_optional_child(loc, rb_intern("old_kind"), old_kind_range);
1663
+
1664
+ return rbs_ast_members_alias(
1665
+ new_name,
1666
+ old_name,
1667
+ kind,
1668
+ annotations,
1669
+ location,
1670
+ comment
1671
+ );
1672
+ }
1673
+
1674
+ /*
1675
+ variable_member ::= {tAIDENT} `:` <type>
1676
+ | {kSELF} `.` tAIDENT `:` <type>
1677
+ | {tA2IDENT} `:` <type>
1678
+ */
1679
+ VALUE parse_variable_member(parserstate *state, position comment_pos, VALUE annotations) {
1680
+ range member_range;
1681
+ range name_range, colon_range;
1682
+ range kind_range = NULL_RANGE;
1683
+
1684
+ if (rb_array_len(annotations) > 0) {
1685
+ raise_syntax_error(
1686
+ state,
1687
+ state->current_token,
1688
+ "annotation cannot be given to variable members"
1689
+ );
1690
+ }
1691
+
1692
+ member_range.start = state->current_token.range.start;
1693
+ comment_pos = nonnull_pos_or(comment_pos, member_range.start);
1694
+ VALUE comment = get_comment(state, comment_pos.line);
1695
+
1696
+ VALUE klass;
1697
+ VALUE location;
1698
+ VALUE name;
1699
+ VALUE type;
1700
+
1701
+ switch (state->current_token.type)
1702
+ {
1703
+ case tAIDENT:
1704
+ klass = RBS_AST_Members_InstanceVariable;
1705
+
1706
+ name_range = state->current_token.range;
1707
+ name = ID2SYM(INTERN_TOKEN(state, state->current_token));
1708
+
1709
+ parser_advance_assert(state, pCOLON);
1710
+ colon_range = state->current_token.range;
1711
+
1712
+ type = parse_type(state);
1713
+ member_range.end = state->current_token.range.end;
1714
+
1715
+ break;
1716
+
1717
+ case tA2IDENT:
1718
+ klass = RBS_AST_Members_ClassVariable;
1719
+
1720
+ name_range = state->current_token.range;
1721
+ name = ID2SYM(INTERN_TOKEN(state, state->current_token));
1722
+
1723
+ parser_advance_assert(state, pCOLON);
1724
+ colon_range = state->current_token.range;
1725
+
1726
+ parser_push_typevar_table(state, true);
1727
+ type = parse_type(state);
1728
+ parser_pop_typevar_table(state);
1729
+ member_range.end = state->current_token.range.end;
1730
+
1731
+ break;
1732
+
1733
+ case kSELF:
1734
+ klass = RBS_AST_Members_ClassInstanceVariable;
1735
+
1736
+ kind_range.start = state->current_token.range.start;
1737
+ kind_range.end = state->next_token.range.end;
1738
+
1739
+ parser_advance_assert(state, pDOT);
1740
+ parser_advance_assert(state, tAIDENT);
1741
+
1742
+ name_range = state->current_token.range;
1743
+ name = ID2SYM(INTERN_TOKEN(state, state->current_token));
1744
+
1745
+ parser_advance_assert(state, pCOLON);
1746
+ colon_range = state->current_token.range;
1747
+
1748
+ parser_push_typevar_table(state, true);
1749
+ type = parse_type(state);
1750
+ parser_pop_typevar_table(state);
1751
+ member_range.end = state->current_token.range.end;
1752
+
1753
+ break;
1754
+
1755
+ default:
1756
+ rbs_abort();
1757
+ }
1758
+
1759
+ location = rbs_new_location(state->buffer, member_range);
1760
+ rbs_loc *loc = rbs_check_location(location);
1761
+ rbs_loc_add_required_child(loc, rb_intern("name"), name_range);
1762
+ rbs_loc_add_required_child(loc, rb_intern("colon"), colon_range);
1763
+ rbs_loc_add_optional_child(loc, rb_intern("kind"), kind_range);
1764
+
1765
+ return rbs_ast_members_variable(klass, name, type, location, comment);
1766
+ }
1767
+
1768
+ /*
1769
+ visibility_member ::= {<`public`>}
1770
+ | {<`private`>}
1771
+ */
1772
+ VALUE parse_visibility_member(parserstate *state, VALUE annotations) {
1773
+ if (rb_array_len(annotations) > 0) {
1774
+ raise_syntax_error(
1775
+ state,
1776
+ state->current_token,
1777
+ "annotation cannot be given to visibility members"
1778
+ );
1779
+ }
1780
+
1781
+ VALUE klass;
1782
+
1783
+ switch (state->current_token.type)
1784
+ {
1785
+ case kPUBLIC:
1786
+ klass = RBS_AST_Members_Public;
1787
+ break;
1788
+ case kPRIVATE:
1789
+ klass = RBS_AST_Members_Private;
1790
+ break;
1791
+ default:
1792
+ rbs_abort();
1793
+ }
1794
+
1795
+ return rbs_ast_members_visibility(
1796
+ klass,
1797
+ rbs_new_location(state->buffer, state->current_token.range)
1798
+ );
1799
+ }
1800
+
1801
+ /*
1802
+ attribute_member ::= {attr_keyword} attr_name attr_var `:` <type>
1803
+ | {attr_keyword} `self` `.` attr_name attr_var `:` <type>
1804
+
1805
+ attr_keyword ::= `attr_reader` | `attr_writer` | `attr_accessor`
1806
+
1807
+ attr_var ::= # empty
1808
+ | `(` tAIDENT `)` # Ivar name
1809
+ | `(` `)` # No variable
1810
+ */
1811
+ VALUE parse_attribute_member(parserstate *state, position comment_pos, VALUE annotations) {
1812
+ range member_range;
1813
+ range keyword_range, name_range, colon_range;
1814
+ range kind_range = NULL_RANGE, ivar_range = NULL_RANGE, ivar_name_range = NULL_RANGE;
1815
+
1816
+ InstanceSingletonKind is_kind;
1817
+ VALUE klass;
1818
+ VALUE kind;
1819
+ VALUE attr_name;
1820
+ VALUE ivar_name;
1821
+ VALUE type;
1822
+ VALUE comment;
1823
+ VALUE location;
1824
+ rbs_loc *loc;
1825
+
1826
+ member_range.start = state->current_token.range.start;
1827
+ comment_pos = nonnull_pos_or(comment_pos, member_range.start);
1828
+ comment = get_comment(state, comment_pos.line);
1829
+
1830
+ keyword_range = state->current_token.range;
1831
+ switch (state->current_token.type)
1832
+ {
1833
+ case kATTRREADER:
1834
+ klass = RBS_AST_Members_AttrReader;
1835
+ break;
1836
+ case kATTRWRITER:
1837
+ klass = RBS_AST_Members_AttrWriter;
1838
+ break;
1839
+ case kATTRACCESSOR:
1840
+ klass = RBS_AST_Members_AttrAccessor;
1841
+ break;
1842
+ default:
1843
+ rbs_abort();
1844
+ }
1845
+
1846
+ is_kind = parse_instance_singleton_kind(state, false, &kind_range);
1847
+ if (is_kind == INSTANCE_KIND) {
1848
+ kind = ID2SYM(rb_intern("instance"));
1849
+ } else {
1850
+ kind = ID2SYM(rb_intern("singleton"));
1851
+ }
1852
+
1853
+ attr_name = parse_method_name(state, &name_range);
1854
+
1855
+ if (state->next_token.type == pLPAREN) {
1856
+ parser_advance_assert(state, pLPAREN);
1857
+ ivar_range.start = state->current_token.range.start;
1858
+
1859
+ if (parser_advance_if(state, tAIDENT)) {
1860
+ ivar_name = ID2SYM(INTERN_TOKEN(state, state->current_token));
1861
+ ivar_name_range = state->current_token.range;
1862
+ } else {
1863
+ ivar_name = Qfalse;
1864
+ }
1865
+
1866
+ parser_advance_assert(state, pRPAREN);
1867
+ ivar_range.end = state->current_token.range.end;
1868
+ } else {
1869
+ ivar_name = Qnil;
1870
+ }
1871
+
1872
+ parser_advance_assert(state, pCOLON);
1873
+ colon_range = state->current_token.range;
1874
+
1875
+ parser_push_typevar_table(state, is_kind == SINGLETON_KIND);
1876
+ type = parse_type(state);
1877
+ parser_pop_typevar_table(state);
1878
+ member_range.end = state->current_token.range.end;
1879
+
1880
+ location = rbs_new_location(state->buffer, member_range);
1881
+ loc = rbs_check_location(location);
1882
+ rbs_loc_add_required_child(loc, rb_intern("keyword"), keyword_range);
1883
+ rbs_loc_add_required_child(loc, rb_intern("name"), name_range);
1884
+ rbs_loc_add_required_child(loc, rb_intern("colon"), colon_range);
1885
+ rbs_loc_add_optional_child(loc, rb_intern("kind"), kind_range);
1886
+ rbs_loc_add_optional_child(loc, rb_intern("ivar"), ivar_range);
1887
+ rbs_loc_add_optional_child(loc, rb_intern("ivar_name"), ivar_name_range);
1888
+
1889
+ return rbs_ast_members_attribute(
1890
+ klass,
1891
+ attr_name,
1892
+ type,
1893
+ ivar_name,
1894
+ kind,
1895
+ annotations,
1896
+ location,
1897
+ comment
1898
+ );
1899
+ }
1900
+
1901
+ /*
1902
+ interface_members ::= {} ...<interface_member> kEND
1903
+
1904
+ interface_member ::= def_member (instance method only && no overloading)
1905
+ | mixin_member (interface only)
1906
+ | alias_member (instance only)
1907
+ */
1908
+ VALUE parse_interface_members(parserstate *state) {
1909
+ VALUE members = rb_ary_new();
1910
+
1911
+ while (state->next_token.type != kEND) {
1912
+ VALUE annotations = rb_ary_new();
1913
+ position annot_pos = NullPosition;
1914
+
1915
+ parse_annotations(state, annotations, &annot_pos);
1916
+
1917
+ parser_advance(state);
1918
+
1919
+ VALUE member;
1920
+ switch (state->current_token.type) {
1921
+ case kDEF:
1922
+ member = parse_member_def(state, true, true, annot_pos, annotations);
1923
+ break;
1924
+
1925
+ case kINCLUDE:
1926
+ case kEXTEND:
1927
+ case kPREPEND:
1928
+ member = parse_mixin_member(state, true, annot_pos, annotations);
1929
+ break;
1930
+
1931
+ case kALIAS:
1932
+ member = parse_alias_member(state, true, annot_pos, annotations);
1933
+ break;
1934
+
1935
+ default:
1936
+ raise_syntax_error(
1937
+ state,
1938
+ state->current_token,
1939
+ "unexpected token for interface declaration member"
1940
+ );
1941
+ }
1942
+
1943
+ rb_ary_push(members, member);
1944
+ }
1945
+
1946
+ return members;
1947
+ }
1948
+
1949
+ /*
1950
+ interface_decl ::= {`interface`} interface_name module_type_params interface_members <kEND>
1951
+ */
1952
+ VALUE parse_interface_decl(parserstate *state, position comment_pos, VALUE annotations) {
1953
+ range member_range;
1954
+ range name_range, keyword_range, end_range;
1955
+ range type_params_range = NULL_RANGE;
1956
+
1957
+ member_range.start = state->current_token.range.start;
1958
+ comment_pos = nonnull_pos_or(comment_pos, member_range.start);
1959
+
1960
+ parser_push_typevar_table(state, true);
1961
+ keyword_range = state->current_token.range;
1962
+
1963
+ parser_advance(state);
1964
+
1965
+ VALUE name = parse_type_name(state, INTERFACE_NAME, &name_range);
1966
+ VALUE params = parse_module_type_params(state, &type_params_range);
1967
+ VALUE members = parse_interface_members(state);
1968
+
1969
+ parser_advance_assert(state, kEND);
1970
+ end_range = state->current_token.range;
1971
+ member_range.end = end_range.end;
1972
+
1973
+ parser_pop_typevar_table(state);
1974
+
1975
+ VALUE location = rbs_new_location(state->buffer, member_range);
1976
+ rbs_loc *loc = rbs_check_location(location);
1977
+ rbs_loc_add_required_child(loc, rb_intern("keyword"), keyword_range);
1978
+ rbs_loc_add_required_child(loc, rb_intern("name"), name_range);
1979
+ rbs_loc_add_required_child(loc, rb_intern("end"), end_range);
1980
+ rbs_loc_add_optional_child(loc, rb_intern("type_params"), type_params_range);
1981
+
1982
+ return rbs_ast_decl_interface(
1983
+ name,
1984
+ params,
1985
+ members,
1986
+ annotations,
1987
+ location,
1988
+ get_comment(state, comment_pos.line)
1989
+ );
1990
+ }
1991
+
1992
+ /*
1993
+ module_self_types ::= {`:`} module_self_type `,` ... `,` <module_self_type>
1994
+
1995
+ module_self_type ::= <module_name>
1996
+ | module_name `[` type_list <`]`>
1997
+ */
1998
+ void parse_module_self_types(parserstate *state, VALUE array) {
1999
+ while (true) {
2000
+ range self_range;
2001
+ range name_range;
2002
+ range args_range = NULL_RANGE;
2003
+
2004
+ parser_advance(state);
2005
+
2006
+ self_range.start = state->current_token.range.start;
2007
+
2008
+ VALUE module_name = parse_type_name(state, CLASS_NAME | INTERFACE_NAME, &name_range);
2009
+ self_range.end = name_range.end;
2010
+
2011
+ VALUE args = rb_ary_new();
2012
+ if (state->next_token.type == pLBRACKET) {
2013
+ parser_advance(state);
2014
+ args_range.start = state->current_token.range.start;
2015
+ parse_type_list(state, pRBRACKET, args);
2016
+ parser_advance(state);
2017
+ self_range.end = args_range.end = state->current_token.range.end;
2018
+ }
2019
+
2020
+ VALUE location = rbs_new_location(state->buffer, self_range);
2021
+ rbs_loc *loc = rbs_check_location(location);
2022
+ rbs_loc_add_required_child(loc, rb_intern("name"), name_range);
2023
+ rbs_loc_add_optional_child(loc, rb_intern("args"), args_range);
2024
+
2025
+ VALUE self_type = rbs_ast_decl_module_self(module_name, args, location);
2026
+ rb_ary_push(array, self_type);
2027
+
2028
+ if (state->next_token.type == pCOMMA) {
2029
+ parser_advance(state);
2030
+ } else {
2031
+ break;
2032
+ }
2033
+ }
2034
+ }
2035
+
2036
+ VALUE parse_nested_decl(parserstate *state, const char *nested_in, position annot_pos, VALUE annotations);
2037
+
2038
+ /*
2039
+ module_members ::= {} ...<module_member> kEND
2040
+
2041
+ module_member ::= def_member
2042
+ | variable_member
2043
+ | mixin_member
2044
+ | alias_member
2045
+ | attribute_member
2046
+ | `public`
2047
+ | `private`
2048
+ */
2049
+ VALUE parse_module_members(parserstate *state) {
2050
+ VALUE members = rb_ary_new();
2051
+
2052
+ while (state->next_token.type != kEND) {
2053
+ VALUE member;
2054
+ VALUE annotations = rb_ary_new();
2055
+ position annot_pos = NullPosition;
2056
+
2057
+ parse_annotations(state, annotations, &annot_pos);
2058
+
2059
+ parser_advance(state);
2060
+
2061
+ switch (state->current_token.type)
2062
+ {
2063
+ case kDEF:
2064
+ member = parse_member_def(state, false, true, annot_pos, annotations);
2065
+ break;
2066
+
2067
+ case kINCLUDE:
2068
+ case kEXTEND:
2069
+ case kPREPEND:
2070
+ member = parse_mixin_member(state, false, annot_pos, annotations);
2071
+ break;
2072
+
2073
+ case kALIAS:
2074
+ member = parse_alias_member(state, false, annot_pos, annotations);
2075
+ break;
2076
+
2077
+
2078
+ case tAIDENT:
2079
+ case tA2IDENT:
2080
+ case kSELF:
2081
+ member = parse_variable_member(state, annot_pos, annotations);
2082
+ break;
2083
+
2084
+ case kATTRREADER:
2085
+ case kATTRWRITER:
2086
+ case kATTRACCESSOR:
2087
+ member = parse_attribute_member(state, annot_pos, annotations);
2088
+ break;
2089
+
2090
+ case kPUBLIC:
2091
+ case kPRIVATE:
2092
+ member = parse_visibility_member(state, annotations);
2093
+ break;
2094
+
2095
+ default:
2096
+ member = parse_nested_decl(state, "module", annot_pos, annotations);
2097
+ break;
2098
+ }
2099
+
2100
+ rb_ary_push(members, member);
2101
+ }
2102
+
2103
+ return members;
2104
+ }
2105
+
2106
+ /*
2107
+ module_decl ::= {`module`} module_name module_type_params module_members <kEND>
2108
+ | {`module`} module_name module_type_params `:` module_self_types module_members <kEND>
2109
+ */
2110
+ VALUE parse_module_decl(parserstate *state, position comment_pos, VALUE annotations) {
2111
+ range decl_range;
2112
+ range keyword_range;
2113
+ range name_range;
2114
+ range end_range;
2115
+ range type_params_range;
2116
+ range colon_range;
2117
+ range self_types_range;
2118
+
2119
+ parser_push_typevar_table(state, true);
2120
+
2121
+ position start = state->current_token.range.start;
2122
+ comment_pos = nonnull_pos_or(comment_pos, start);
2123
+ VALUE comment = get_comment(state, comment_pos.line);
2124
+
2125
+ keyword_range = state->current_token.range;
2126
+ decl_range.start = state->current_token.range.start;
2127
+
2128
+ parser_advance(state);
2129
+ VALUE module_name = parse_type_name(state, CLASS_NAME, &name_range);
2130
+ VALUE type_params = parse_module_type_params(state, &type_params_range);
2131
+ VALUE self_types = rb_ary_new();
2132
+
2133
+ if (state->next_token.type == pCOLON) {
2134
+ parser_advance(state);
2135
+ colon_range = state->current_token.range;
2136
+ self_types_range.start = state->next_token.range.start;
2137
+ parse_module_self_types(state, self_types);
2138
+ self_types_range.end = state->current_token.range.end;
2139
+ } else {
2140
+ colon_range = NULL_RANGE;
2141
+ self_types_range = NULL_RANGE;
2142
+ }
2143
+
2144
+ VALUE members = parse_module_members(state);
2145
+
2146
+ parser_advance_assert(state, kEND);
2147
+ end_range = state->current_token.range;
2148
+ decl_range.end = state->current_token.range.end;
2149
+
2150
+ VALUE location = rbs_new_location(state->buffer, decl_range);
2151
+ rbs_loc *loc = rbs_check_location(location);
2152
+ rbs_loc_add_required_child(loc, rb_intern("keyword"), keyword_range);
2153
+ rbs_loc_add_required_child(loc, rb_intern("name"), name_range);
2154
+ rbs_loc_add_required_child(loc, rb_intern("end"), end_range);
2155
+ rbs_loc_add_optional_child(loc, rb_intern("type_params"), type_params_range);
2156
+ rbs_loc_add_optional_child(loc, rb_intern("colon"), colon_range);
2157
+ rbs_loc_add_optional_child(loc, rb_intern("self_types"), self_types_range);
2158
+
2159
+ parser_pop_typevar_table(state);
2160
+
2161
+ return rbs_ast_decl_module(
2162
+ module_name,
2163
+ type_params,
2164
+ self_types,
2165
+ members,
2166
+ annotations,
2167
+ location,
2168
+ comment
2169
+ );
2170
+ }
2171
+
2172
+ /*
2173
+ class_decl_super ::= {} `<` <class_instance_name>
2174
+ | {<>}
2175
+ */
2176
+ VALUE parse_class_decl_super(parserstate *state, range *lt_range) {
2177
+ if (parser_advance_if(state, pLT)) {
2178
+ range super_range;
2179
+ range name_range;
2180
+ range args_range = NULL_RANGE;
2181
+
2182
+ VALUE name;
2183
+ VALUE args;
2184
+ VALUE location;
2185
+ rbs_loc *loc;
2186
+
2187
+ *lt_range = state->current_token.range;
2188
+ super_range.start = state->next_token.range.start;
2189
+
2190
+ args = rb_ary_new();
2191
+ class_instance_name(state, CLASS_NAME, &name, args, &name_range, &args_range);
2192
+
2193
+ super_range.end = args_range.end;
2194
+
2195
+ location = rbs_new_location(state->buffer, super_range);
2196
+ loc = rbs_check_location(location);
2197
+ rbs_loc_add_required_child(loc, rb_intern("name"), name_range);
2198
+ rbs_loc_add_optional_child(loc, rb_intern("args"), args_range);
2199
+
2200
+ return rbs_ast_decl_class_super(name, args, location);
2201
+ } else {
2202
+ *lt_range = NULL_RANGE;
2203
+ return Qnil;
2204
+ }
2205
+ }
2206
+
2207
+ /*
2208
+ class_decl ::= {`class`} class_name type_params class_decl_super class_members <`end`>
2209
+ */
2210
+ VALUE parse_class_decl(parserstate *state, position comment_pos, VALUE annotations) {
2211
+ range decl_range;
2212
+ range keyword_range;
2213
+ range name_range;
2214
+ range end_range;
2215
+ range type_params_range;
2216
+ range lt_range;
2217
+
2218
+ VALUE name;
2219
+ VALUE type_params;
2220
+ VALUE super;
2221
+ VALUE members;
2222
+ VALUE comment;
2223
+ VALUE location;
2224
+
2225
+ rbs_loc *loc;
2226
+
2227
+ parser_push_typevar_table(state, true);
2228
+
2229
+ decl_range.start = state->current_token.range.start;
2230
+ keyword_range = state->current_token.range;
2231
+
2232
+ comment_pos = nonnull_pos_or(comment_pos, decl_range.start);
2233
+ comment = get_comment(state, comment_pos.line);
2234
+
2235
+ parser_advance(state);
2236
+ name = parse_type_name(state, CLASS_NAME, &name_range);
2237
+ type_params = parse_module_type_params(state, &type_params_range);
2238
+ super = parse_class_decl_super(state, &lt_range);
2239
+ members = parse_module_members(state);
2240
+ parser_advance_assert(state, kEND);
2241
+ end_range = state->current_token.range;
2242
+
2243
+ decl_range.end = end_range.end;
2244
+
2245
+ parser_pop_typevar_table(state);
2246
+
2247
+ location = rbs_new_location(state->buffer, decl_range);
2248
+ loc = rbs_check_location(location);
2249
+ rbs_loc_add_required_child(loc, rb_intern("keyword"), keyword_range);
2250
+ rbs_loc_add_required_child(loc, rb_intern("name"), name_range);
2251
+ rbs_loc_add_required_child(loc, rb_intern("end"), end_range);
2252
+ rbs_loc_add_optional_child(loc, rb_intern("type_params"), type_params_range);
2253
+ rbs_loc_add_optional_child(loc, rb_intern("lt"), lt_range);
2254
+
2255
+ return rbs_ast_decl_class(
2256
+ name,
2257
+ type_params,
2258
+ super,
2259
+ members,
2260
+ annotations,
2261
+ location,
2262
+ comment
2263
+ );
2264
+ }
2265
+
2266
+ /*
2267
+ nested_decl ::= {<const_decl>}
2268
+ | {<class_decl>}
2269
+ | {<interface_decl>}
2270
+ | {<module_decl>}
2271
+ | {<class_decl>}
2272
+ */
2273
+ VALUE parse_nested_decl(parserstate *state, const char *nested_in, position annot_pos, VALUE annotations) {
2274
+ VALUE decl;
2275
+
2276
+ parser_push_typevar_table(state, true);
2277
+
2278
+ switch (state->current_token.type) {
2279
+ case tUIDENT:
2280
+ case pCOLON2:
2281
+ decl = parse_const_decl(state);
2282
+ break;
2283
+ case kTYPE:
2284
+ decl = parse_type_decl(state, annot_pos, annotations);
2285
+ break;
2286
+ case kINTERFACE:
2287
+ decl = parse_interface_decl(state, annot_pos, annotations);
2288
+ break;
2289
+ case kMODULE:
2290
+ decl = parse_module_decl(state, annot_pos, annotations);
2291
+ break;
2292
+ case kCLASS:
2293
+ decl = parse_class_decl(state, annot_pos, annotations);
2294
+ break;
2295
+ default:
2296
+ raise_syntax_error(
2297
+ state,
2298
+ state->current_token,
2299
+ "unexpected token for class/module declaration member"
2300
+ );
2301
+ }
2302
+
2303
+ parser_pop_typevar_table(state);
2304
+
2305
+ return decl;
2306
+ }
2307
+
2308
+ VALUE parse_decl(parserstate *state) {
2309
+ VALUE annotations = rb_ary_new();
2310
+ position annot_pos = NullPosition;
2311
+
2312
+ parse_annotations(state, annotations, &annot_pos);
2313
+
2314
+ parser_advance(state);
2315
+ switch (state->current_token.type) {
2316
+ case tUIDENT:
2317
+ case pCOLON2:
2318
+ return parse_const_decl(state);
2319
+ case tGIDENT:
2320
+ return parse_global_decl(state);
2321
+ case kTYPE:
2322
+ return parse_type_decl(state, annot_pos, annotations);
2323
+ case kINTERFACE:
2324
+ return parse_interface_decl(state, annot_pos, annotations);
2325
+ case kMODULE:
2326
+ return parse_module_decl(state, annot_pos, annotations);
2327
+ case kCLASS:
2328
+ return parse_class_decl(state, annot_pos, annotations);
2329
+ default:
2330
+ raise_syntax_error(
2331
+ state,
2332
+ state->current_token,
2333
+ "cannot start a declaration"
2334
+ );
2335
+ }
2336
+ }
2337
+
2338
+ VALUE parse_signature(parserstate *state) {
2339
+ VALUE decls = rb_ary_new();
2340
+
2341
+ while (state->next_token.type != pEOF) {
2342
+ rb_ary_push(decls, parse_decl(state));
2343
+ }
2344
+
2345
+ return decls;
2346
+ }
2347
+
2348
+ static VALUE
2349
+ rbsparser_parse_type(VALUE self, VALUE buffer, VALUE line, VALUE column, VALUE variables)
2350
+ {
2351
+ parserstate *parser = alloc_parser(buffer, FIX2INT(line), FIX2INT(column), variables);
2352
+
2353
+ VALUE type = parse_type(parser);
2354
+ parser_advance_assert(parser, pEOF);
2355
+
2356
+ free_parser(parser);
2357
+
2358
+ return type;
2359
+ }
2360
+
2361
+ static VALUE
2362
+ rbsparser_parse_method_type(VALUE self, VALUE buffer, VALUE line, VALUE column, VALUE variables)
2363
+ {
2364
+ parserstate *parser = alloc_parser(buffer, FIX2INT(line), FIX2INT(column), variables);
2365
+ VALUE method_type = parse_method_type(parser);
2366
+ free(parser);
2367
+
2368
+ return method_type;
2369
+ }
2370
+
2371
+ static VALUE
2372
+ rbsparser_parse_signature(VALUE self, VALUE buffer, VALUE line, VALUE column)
2373
+ {
2374
+ parserstate *parser = alloc_parser(buffer, FIX2INT(line), FIX2INT(column), Qnil);
2375
+ VALUE signature = parse_signature(parser);
2376
+ free_parser(parser);
2377
+
2378
+ return signature;
2379
+ }
2380
+
2381
+ void rbs__init_parser() {
2382
+ RBS_Parser = rb_define_class_under(RBS, "Parser", rb_cObject);
2383
+ rb_define_singleton_method(RBS_Parser, "_parse_type", rbsparser_parse_type, 4);
2384
+ rb_define_singleton_method(RBS_Parser, "_parse_method_type", rbsparser_parse_method_type, 4);
2385
+ rb_define_singleton_method(RBS_Parser, "_parse_signature", rbsparser_parse_signature, 3);
2386
+
2387
+ RBS_Parser_KEYWORDS = rb_hash_new();
2388
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("bool"), INT2FIX(kBOOL));
2389
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("bot"), INT2FIX(kBOT));
2390
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("class"), INT2FIX(kCLASS));
2391
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("instance"), INT2FIX(kINSTANCE));
2392
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("interface"), INT2FIX(kINTERFACE));
2393
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("nil"), INT2FIX(kNIL));
2394
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("self"), INT2FIX(kSELF));
2395
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("singleton"), INT2FIX(kSINGLETON));
2396
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("top"), INT2FIX(kTOP));
2397
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("void"), INT2FIX(kVOID));
2398
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("type"), INT2FIX(kTYPE));
2399
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("unchecked"), INT2FIX(kUNCHECKED));
2400
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("in"), INT2FIX(kIN));
2401
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("out"), INT2FIX(kOUT));
2402
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("end"), INT2FIX(kEND));
2403
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("def"), INT2FIX(kDEF));
2404
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("include"), INT2FIX(kINCLUDE));
2405
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("extend"), INT2FIX(kEXTEND));
2406
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("prepend"), INT2FIX(kPREPEND));
2407
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("alias"), INT2FIX(kALIAS));
2408
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("module"), INT2FIX(kMODULE));
2409
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("attr_reader"), INT2FIX(kATTRREADER));
2410
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("attr_writer"), INT2FIX(kATTRWRITER));
2411
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("attr_accessor"), INT2FIX(kATTRACCESSOR));
2412
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("public"), INT2FIX(kPUBLIC));
2413
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("private"), INT2FIX(kPRIVATE));
2414
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("untyped"), INT2FIX(kUNTYPED));
2415
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("true"), INT2FIX(kTRUE));
2416
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("false"), INT2FIX(kFALSE));
2417
+ rb_define_const(RBS_Parser, "KEYWORDS", RBS_Parser_KEYWORDS);
2418
+ }