rbs 1.6.0 → 1.7.0.beta.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +0 -4
  3. data/.gitignore +1 -0
  4. data/CHANGELOG.md +26 -0
  5. data/Gemfile +1 -0
  6. data/Rakefile +7 -22
  7. data/core/enumerator.rbs +1 -0
  8. data/core/io.rbs +1 -1
  9. data/core/kernel.rbs +4 -4
  10. data/core/trace_point.rbs +1 -1
  11. data/ext/rbs_extension/constants.c +140 -0
  12. data/ext/rbs_extension/constants.h +72 -0
  13. data/ext/rbs_extension/extconf.rb +3 -0
  14. data/ext/rbs_extension/lexer.c +1070 -0
  15. data/ext/rbs_extension/lexer.h +145 -0
  16. data/ext/rbs_extension/location.c +295 -0
  17. data/ext/rbs_extension/location.h +59 -0
  18. data/ext/rbs_extension/main.c +9 -0
  19. data/ext/rbs_extension/parser.c +2422 -0
  20. data/ext/rbs_extension/parser.h +23 -0
  21. data/ext/rbs_extension/parserstate.c +313 -0
  22. data/ext/rbs_extension/parserstate.h +141 -0
  23. data/ext/rbs_extension/rbs_extension.h +40 -0
  24. data/ext/rbs_extension/ruby_objs.c +585 -0
  25. data/ext/rbs_extension/ruby_objs.h +46 -0
  26. data/ext/rbs_extension/unescape.c +65 -0
  27. data/goodcheck.yml +1 -1
  28. data/lib/rbs/ast/comment.rb +0 -12
  29. data/lib/rbs/buffer.rb +4 -0
  30. data/lib/rbs/cli.rb +5 -8
  31. data/lib/rbs/collection/sources/git.rb +18 -3
  32. data/lib/rbs/errors.rb +22 -1
  33. data/lib/rbs/location.rb +221 -217
  34. data/lib/rbs/location_aux.rb +121 -0
  35. data/lib/rbs/locator.rb +10 -7
  36. data/lib/rbs/parser_aux.rb +31 -0
  37. data/lib/rbs/types.rb +2 -3
  38. data/lib/rbs/version.rb +1 -1
  39. data/lib/rbs/writer.rb +4 -2
  40. data/lib/rbs.rb +3 -7
  41. data/rbs.gemspec +2 -1
  42. data/sig/ancestor_builder.rbs +2 -2
  43. data/sig/annotation.rbs +2 -2
  44. data/sig/comment.rbs +7 -7
  45. data/sig/constant_table.rbs +1 -1
  46. data/sig/declarations.rbs +9 -9
  47. data/sig/definition.rbs +1 -1
  48. data/sig/definition_builder.rbs +2 -2
  49. data/sig/errors.rbs +40 -25
  50. data/sig/location.rbs +46 -78
  51. data/sig/locator.rbs +2 -2
  52. data/sig/members.rbs +7 -7
  53. data/sig/method_types.rbs +3 -3
  54. data/sig/parser.rbs +13 -20
  55. data/sig/types.rbs +45 -27
  56. data/sig/writer.rbs +1 -1
  57. data/stdlib/json/0/json.rbs +3 -3
  58. metadata +25 -7
  59. data/lib/rbs/parser.rb +0 -3614
@@ -0,0 +1,9 @@
1
+ #include "rbs_extension.h"
2
+
3
+ void
4
+ Init_rbs_extension(void)
5
+ {
6
+ rbs__init_constants();
7
+ rbs__init_location();
8
+ rbs__init_parser();
9
+ }
@@ -0,0 +1,2422 @@
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
+ member_range.end = overload_range.end;
1453
+ break;
1454
+ } else {
1455
+ raise_syntax_error(
1456
+ state,
1457
+ state->next_token,
1458
+ "unexpected overloading method definition"
1459
+ );
1460
+ }
1461
+
1462
+ default:
1463
+ raise_syntax_error(
1464
+ state,
1465
+ state->next_token,
1466
+ "unexpected token for method type"
1467
+ );
1468
+ }
1469
+
1470
+ if (state->next_token.type == pBAR) {
1471
+ parser_advance(state);
1472
+ } else {
1473
+ loop = false;
1474
+ }
1475
+ }
1476
+
1477
+ parser_pop_typevar_table(state);
1478
+
1479
+ VALUE k;
1480
+ switch (kind) {
1481
+ case INSTANCE_KIND:
1482
+ k = ID2SYM(rb_intern("instance"));
1483
+ break;
1484
+ case SINGLETON_KIND:
1485
+ k = ID2SYM(rb_intern("singleton"));
1486
+ break;
1487
+ case INSTANCE_SINGLETON_KIND:
1488
+ k = ID2SYM(rb_intern("singleton_instance"));
1489
+ break;
1490
+ }
1491
+
1492
+ VALUE location = rbs_new_location(state->buffer, member_range);
1493
+ rbs_loc *loc = rbs_check_location(location);
1494
+ rbs_loc_add_required_child(loc, rb_intern("keyword"), keyword_range);
1495
+ rbs_loc_add_required_child(loc, rb_intern("name"), name_range);
1496
+ rbs_loc_add_optional_child(loc, rb_intern("kind"), kind_range);
1497
+ rbs_loc_add_optional_child(loc, rb_intern("overload"), overload_range);
1498
+
1499
+ return rbs_ast_members_method_definition(
1500
+ name,
1501
+ k,
1502
+ method_types,
1503
+ annotations,
1504
+ location,
1505
+ comment,
1506
+ overload
1507
+ );
1508
+ }
1509
+
1510
+ /**
1511
+ * class_instance_name ::= {} <class_name>
1512
+ * | {} class_name `[` type args <`]`>
1513
+ *
1514
+ * @param kind
1515
+ * */
1516
+ void class_instance_name(parserstate *state, TypeNameKind kind, VALUE *name, VALUE args, range *name_range, range *args_range) {
1517
+ parser_advance(state);
1518
+
1519
+ *name = parse_type_name(state, kind, name_range);
1520
+
1521
+ if (state->next_token.type == pLBRACKET) {
1522
+ parser_advance(state);
1523
+ args_range->start = state->current_token.range.start;
1524
+ parse_type_list(state, pRBRACKET, args);
1525
+ parser_advance_assert(state, pRBRACKET);
1526
+ args_range->end = state->current_token.range.end;
1527
+ } else {
1528
+ *args_range = NULL_RANGE;
1529
+ }
1530
+ }
1531
+
1532
+ /**
1533
+ * mixin_member ::= {kINCLUDE} <class_instance_name>
1534
+ * | {kPREPEND} <class_instance_name>
1535
+ * | {kEXTEND} <class_instance_name>
1536
+ *
1537
+ * @param from_interface `true` when the member is in an interface.
1538
+ * */
1539
+ VALUE parse_mixin_member(parserstate *state, bool from_interface, position comment_pos, VALUE annotations) {
1540
+ range member_range;
1541
+ range name_range;
1542
+ range keyword_range;
1543
+ range args_range = NULL_RANGE;
1544
+ bool reset_typevar_scope;
1545
+
1546
+ member_range.start = state->current_token.range.start;
1547
+ comment_pos = nonnull_pos_or(comment_pos, member_range.start);
1548
+
1549
+ keyword_range = state->current_token.range;
1550
+
1551
+ VALUE klass = Qnil;
1552
+ switch (state->current_token.type)
1553
+ {
1554
+ case kINCLUDE:
1555
+ klass = RBS_AST_Members_Include;
1556
+ reset_typevar_scope = false;
1557
+ break;
1558
+ case kEXTEND:
1559
+ klass = RBS_AST_Members_Extend;
1560
+ reset_typevar_scope = true;
1561
+ break;
1562
+ case kPREPEND:
1563
+ klass = RBS_AST_Members_Prepend;
1564
+ reset_typevar_scope = false;
1565
+ break;
1566
+ default:
1567
+ rbs_abort();
1568
+ }
1569
+
1570
+ if (from_interface) {
1571
+ if (state->current_token.type != kINCLUDE) {
1572
+ raise_syntax_error(
1573
+ state,
1574
+ state->current_token,
1575
+ "unexpected mixin in interface declaration"
1576
+ );
1577
+ }
1578
+ }
1579
+
1580
+ parser_push_typevar_table(state, reset_typevar_scope);
1581
+
1582
+ VALUE name;
1583
+ VALUE args = rb_ary_new();
1584
+ class_instance_name(
1585
+ state,
1586
+ from_interface ? INTERFACE_NAME : (INTERFACE_NAME | CLASS_NAME),
1587
+ &name, args, &name_range, &args_range
1588
+ );
1589
+
1590
+ parser_pop_typevar_table(state);
1591
+
1592
+ member_range.end = state->current_token.range.end;
1593
+
1594
+ VALUE location = rbs_new_location(state->buffer, member_range);
1595
+ rbs_loc *loc = rbs_check_location(location);
1596
+ rbs_loc_add_required_child(loc, rb_intern("name"), name_range);
1597
+ rbs_loc_add_required_child(loc, rb_intern("keyword"), keyword_range);
1598
+ rbs_loc_add_optional_child(loc, rb_intern("args"), args_range);
1599
+
1600
+ return rbs_ast_members_mixin(
1601
+ klass,
1602
+ name,
1603
+ args,
1604
+ annotations,
1605
+ location,
1606
+ get_comment(state, comment_pos.line)
1607
+ );
1608
+ }
1609
+
1610
+ /**
1611
+ * @code
1612
+ * alias_member ::= {kALIAS} method_name <method_name>
1613
+ * | {kALIAS} kSELF `.` method_name kSELF `.` <method_name>
1614
+ * @endcode
1615
+ *
1616
+ * @param[in] instance_only `true` to reject `self.` alias.
1617
+ * */
1618
+ VALUE parse_alias_member(parserstate *state, bool instance_only, position comment_pos, VALUE annotations) {
1619
+ range member_range;
1620
+ range keyword_range, new_name_range, old_name_range;
1621
+ range new_kind_range, old_kind_range;
1622
+
1623
+ member_range.start = state->current_token.range.start;
1624
+ keyword_range = state->current_token.range;
1625
+
1626
+ comment_pos = nonnull_pos_or(comment_pos, member_range.start);
1627
+ VALUE comment = get_comment(state, comment_pos.line);
1628
+
1629
+ VALUE new_name;
1630
+ VALUE old_name;
1631
+ VALUE kind;
1632
+
1633
+ if (!instance_only && state->next_token.type == kSELF) {
1634
+ kind = ID2SYM(rb_intern("singleton"));
1635
+
1636
+ new_kind_range.start = state->next_token.range.start;
1637
+ new_kind_range.end = state->next_token2.range.end;
1638
+ parser_advance_assert(state, kSELF);
1639
+ parser_advance_assert(state, pDOT);
1640
+ new_name = parse_method_name(state, &new_name_range);
1641
+
1642
+ old_kind_range.start = state->next_token.range.start;
1643
+ old_kind_range.end = state->next_token2.range.end;
1644
+ parser_advance_assert(state, kSELF);
1645
+ parser_advance_assert(state, pDOT);
1646
+ old_name = parse_method_name(state, &old_name_range);
1647
+ } else {
1648
+ kind = ID2SYM(rb_intern("instance"));
1649
+ new_name = parse_method_name(state, &new_name_range);
1650
+ old_name = parse_method_name(state, &old_name_range);
1651
+
1652
+ new_kind_range = NULL_RANGE;
1653
+ old_kind_range = NULL_RANGE;
1654
+ }
1655
+
1656
+ member_range.end = state->current_token.range.end;
1657
+ VALUE location = rbs_new_location(state->buffer, member_range);
1658
+ rbs_loc *loc = rbs_check_location(location);
1659
+ rbs_loc_add_required_child(loc, rb_intern("keyword"), keyword_range);
1660
+ rbs_loc_add_required_child(loc, rb_intern("new_name"), new_name_range);
1661
+ rbs_loc_add_required_child(loc, rb_intern("old_name"), old_name_range);
1662
+ rbs_loc_add_optional_child(loc, rb_intern("new_kind"), new_kind_range);
1663
+ rbs_loc_add_optional_child(loc, rb_intern("old_kind"), old_kind_range);
1664
+
1665
+ return rbs_ast_members_alias(
1666
+ new_name,
1667
+ old_name,
1668
+ kind,
1669
+ annotations,
1670
+ location,
1671
+ comment
1672
+ );
1673
+ }
1674
+
1675
+ /*
1676
+ variable_member ::= {tAIDENT} `:` <type>
1677
+ | {kSELF} `.` tAIDENT `:` <type>
1678
+ | {tA2IDENT} `:` <type>
1679
+ */
1680
+ VALUE parse_variable_member(parserstate *state, position comment_pos, VALUE annotations) {
1681
+ range member_range;
1682
+ range name_range, colon_range;
1683
+ range kind_range = NULL_RANGE;
1684
+
1685
+ if (rb_array_len(annotations) > 0) {
1686
+ raise_syntax_error(
1687
+ state,
1688
+ state->current_token,
1689
+ "annotation cannot be given to variable members"
1690
+ );
1691
+ }
1692
+
1693
+ member_range.start = state->current_token.range.start;
1694
+ comment_pos = nonnull_pos_or(comment_pos, member_range.start);
1695
+ VALUE comment = get_comment(state, comment_pos.line);
1696
+
1697
+ VALUE klass;
1698
+ VALUE location;
1699
+ VALUE name;
1700
+ VALUE type;
1701
+
1702
+ switch (state->current_token.type)
1703
+ {
1704
+ case tAIDENT:
1705
+ klass = RBS_AST_Members_InstanceVariable;
1706
+
1707
+ name_range = state->current_token.range;
1708
+ name = ID2SYM(INTERN_TOKEN(state, state->current_token));
1709
+
1710
+ parser_advance_assert(state, pCOLON);
1711
+ colon_range = state->current_token.range;
1712
+
1713
+ type = parse_type(state);
1714
+ member_range.end = state->current_token.range.end;
1715
+
1716
+ break;
1717
+
1718
+ case tA2IDENT:
1719
+ klass = RBS_AST_Members_ClassVariable;
1720
+
1721
+ name_range = state->current_token.range;
1722
+ name = ID2SYM(INTERN_TOKEN(state, state->current_token));
1723
+
1724
+ parser_advance_assert(state, pCOLON);
1725
+ colon_range = state->current_token.range;
1726
+
1727
+ parser_push_typevar_table(state, true);
1728
+ type = parse_type(state);
1729
+ parser_pop_typevar_table(state);
1730
+ member_range.end = state->current_token.range.end;
1731
+
1732
+ break;
1733
+
1734
+ case kSELF:
1735
+ klass = RBS_AST_Members_ClassInstanceVariable;
1736
+
1737
+ kind_range.start = state->current_token.range.start;
1738
+ kind_range.end = state->next_token.range.end;
1739
+
1740
+ parser_advance_assert(state, pDOT);
1741
+ parser_advance_assert(state, tAIDENT);
1742
+
1743
+ name_range = state->current_token.range;
1744
+ name = ID2SYM(INTERN_TOKEN(state, state->current_token));
1745
+
1746
+ parser_advance_assert(state, pCOLON);
1747
+ colon_range = state->current_token.range;
1748
+
1749
+ parser_push_typevar_table(state, true);
1750
+ type = parse_type(state);
1751
+ parser_pop_typevar_table(state);
1752
+ member_range.end = state->current_token.range.end;
1753
+
1754
+ break;
1755
+
1756
+ default:
1757
+ rbs_abort();
1758
+ }
1759
+
1760
+ location = rbs_new_location(state->buffer, member_range);
1761
+ rbs_loc *loc = rbs_check_location(location);
1762
+ rbs_loc_add_required_child(loc, rb_intern("name"), name_range);
1763
+ rbs_loc_add_required_child(loc, rb_intern("colon"), colon_range);
1764
+ rbs_loc_add_optional_child(loc, rb_intern("kind"), kind_range);
1765
+
1766
+ return rbs_ast_members_variable(klass, name, type, location, comment);
1767
+ }
1768
+
1769
+ /*
1770
+ visibility_member ::= {<`public`>}
1771
+ | {<`private`>}
1772
+ */
1773
+ VALUE parse_visibility_member(parserstate *state, VALUE annotations) {
1774
+ if (rb_array_len(annotations) > 0) {
1775
+ raise_syntax_error(
1776
+ state,
1777
+ state->current_token,
1778
+ "annotation cannot be given to visibility members"
1779
+ );
1780
+ }
1781
+
1782
+ VALUE klass;
1783
+
1784
+ switch (state->current_token.type)
1785
+ {
1786
+ case kPUBLIC:
1787
+ klass = RBS_AST_Members_Public;
1788
+ break;
1789
+ case kPRIVATE:
1790
+ klass = RBS_AST_Members_Private;
1791
+ break;
1792
+ default:
1793
+ rbs_abort();
1794
+ }
1795
+
1796
+ return rbs_ast_members_visibility(
1797
+ klass,
1798
+ rbs_new_location(state->buffer, state->current_token.range)
1799
+ );
1800
+ }
1801
+
1802
+ /*
1803
+ attribute_member ::= {attr_keyword} attr_name attr_var `:` <type>
1804
+ | {attr_keyword} `self` `.` attr_name attr_var `:` <type>
1805
+
1806
+ attr_keyword ::= `attr_reader` | `attr_writer` | `attr_accessor`
1807
+
1808
+ attr_var ::= # empty
1809
+ | `(` tAIDENT `)` # Ivar name
1810
+ | `(` `)` # No variable
1811
+ */
1812
+ VALUE parse_attribute_member(parserstate *state, position comment_pos, VALUE annotations) {
1813
+ range member_range;
1814
+ range keyword_range, name_range, colon_range;
1815
+ range kind_range = NULL_RANGE, ivar_range = NULL_RANGE, ivar_name_range = NULL_RANGE;
1816
+
1817
+ InstanceSingletonKind is_kind;
1818
+ VALUE klass;
1819
+ VALUE kind;
1820
+ VALUE attr_name;
1821
+ VALUE ivar_name;
1822
+ VALUE type;
1823
+ VALUE comment;
1824
+ VALUE location;
1825
+ rbs_loc *loc;
1826
+
1827
+ member_range.start = state->current_token.range.start;
1828
+ comment_pos = nonnull_pos_or(comment_pos, member_range.start);
1829
+ comment = get_comment(state, comment_pos.line);
1830
+
1831
+ keyword_range = state->current_token.range;
1832
+ switch (state->current_token.type)
1833
+ {
1834
+ case kATTRREADER:
1835
+ klass = RBS_AST_Members_AttrReader;
1836
+ break;
1837
+ case kATTRWRITER:
1838
+ klass = RBS_AST_Members_AttrWriter;
1839
+ break;
1840
+ case kATTRACCESSOR:
1841
+ klass = RBS_AST_Members_AttrAccessor;
1842
+ break;
1843
+ default:
1844
+ rbs_abort();
1845
+ }
1846
+
1847
+ is_kind = parse_instance_singleton_kind(state, false, &kind_range);
1848
+ if (is_kind == INSTANCE_KIND) {
1849
+ kind = ID2SYM(rb_intern("instance"));
1850
+ } else {
1851
+ kind = ID2SYM(rb_intern("singleton"));
1852
+ }
1853
+
1854
+ attr_name = parse_method_name(state, &name_range);
1855
+
1856
+ if (state->next_token.type == pLPAREN) {
1857
+ parser_advance_assert(state, pLPAREN);
1858
+ ivar_range.start = state->current_token.range.start;
1859
+
1860
+ if (parser_advance_if(state, tAIDENT)) {
1861
+ ivar_name = ID2SYM(INTERN_TOKEN(state, state->current_token));
1862
+ ivar_name_range = state->current_token.range;
1863
+ } else {
1864
+ ivar_name = Qfalse;
1865
+ }
1866
+
1867
+ parser_advance_assert(state, pRPAREN);
1868
+ ivar_range.end = state->current_token.range.end;
1869
+ } else {
1870
+ ivar_name = Qnil;
1871
+ }
1872
+
1873
+ parser_advance_assert(state, pCOLON);
1874
+ colon_range = state->current_token.range;
1875
+
1876
+ parser_push_typevar_table(state, is_kind == SINGLETON_KIND);
1877
+ type = parse_type(state);
1878
+ parser_pop_typevar_table(state);
1879
+ member_range.end = state->current_token.range.end;
1880
+
1881
+ location = rbs_new_location(state->buffer, member_range);
1882
+ loc = rbs_check_location(location);
1883
+ rbs_loc_add_required_child(loc, rb_intern("keyword"), keyword_range);
1884
+ rbs_loc_add_required_child(loc, rb_intern("name"), name_range);
1885
+ rbs_loc_add_required_child(loc, rb_intern("colon"), colon_range);
1886
+ rbs_loc_add_optional_child(loc, rb_intern("kind"), kind_range);
1887
+ rbs_loc_add_optional_child(loc, rb_intern("ivar"), ivar_range);
1888
+ rbs_loc_add_optional_child(loc, rb_intern("ivar_name"), ivar_name_range);
1889
+
1890
+ return rbs_ast_members_attribute(
1891
+ klass,
1892
+ attr_name,
1893
+ type,
1894
+ ivar_name,
1895
+ kind,
1896
+ annotations,
1897
+ location,
1898
+ comment
1899
+ );
1900
+ }
1901
+
1902
+ /*
1903
+ interface_members ::= {} ...<interface_member> kEND
1904
+
1905
+ interface_member ::= def_member (instance method only && no overloading)
1906
+ | mixin_member (interface only)
1907
+ | alias_member (instance only)
1908
+ */
1909
+ VALUE parse_interface_members(parserstate *state) {
1910
+ VALUE members = rb_ary_new();
1911
+
1912
+ while (state->next_token.type != kEND) {
1913
+ VALUE annotations = rb_ary_new();
1914
+ position annot_pos = NullPosition;
1915
+
1916
+ parse_annotations(state, annotations, &annot_pos);
1917
+
1918
+ parser_advance(state);
1919
+
1920
+ VALUE member;
1921
+ switch (state->current_token.type) {
1922
+ case kDEF:
1923
+ member = parse_member_def(state, true, true, annot_pos, annotations);
1924
+ break;
1925
+
1926
+ case kINCLUDE:
1927
+ case kEXTEND:
1928
+ case kPREPEND:
1929
+ member = parse_mixin_member(state, true, annot_pos, annotations);
1930
+ break;
1931
+
1932
+ case kALIAS:
1933
+ member = parse_alias_member(state, true, annot_pos, annotations);
1934
+ break;
1935
+
1936
+ default:
1937
+ raise_syntax_error(
1938
+ state,
1939
+ state->current_token,
1940
+ "unexpected token for interface declaration member"
1941
+ );
1942
+ }
1943
+
1944
+ rb_ary_push(members, member);
1945
+ }
1946
+
1947
+ return members;
1948
+ }
1949
+
1950
+ /*
1951
+ interface_decl ::= {`interface`} interface_name module_type_params interface_members <kEND>
1952
+ */
1953
+ VALUE parse_interface_decl(parserstate *state, position comment_pos, VALUE annotations) {
1954
+ range member_range;
1955
+ range name_range, keyword_range, end_range;
1956
+ range type_params_range = NULL_RANGE;
1957
+
1958
+ member_range.start = state->current_token.range.start;
1959
+ comment_pos = nonnull_pos_or(comment_pos, member_range.start);
1960
+
1961
+ parser_push_typevar_table(state, true);
1962
+ keyword_range = state->current_token.range;
1963
+
1964
+ parser_advance(state);
1965
+
1966
+ VALUE name = parse_type_name(state, INTERFACE_NAME, &name_range);
1967
+ VALUE params = parse_module_type_params(state, &type_params_range);
1968
+ VALUE members = parse_interface_members(state);
1969
+
1970
+ parser_advance_assert(state, kEND);
1971
+ end_range = state->current_token.range;
1972
+ member_range.end = end_range.end;
1973
+
1974
+ parser_pop_typevar_table(state);
1975
+
1976
+ VALUE location = rbs_new_location(state->buffer, member_range);
1977
+ rbs_loc *loc = rbs_check_location(location);
1978
+ rbs_loc_add_required_child(loc, rb_intern("keyword"), keyword_range);
1979
+ rbs_loc_add_required_child(loc, rb_intern("name"), name_range);
1980
+ rbs_loc_add_required_child(loc, rb_intern("end"), end_range);
1981
+ rbs_loc_add_optional_child(loc, rb_intern("type_params"), type_params_range);
1982
+
1983
+ return rbs_ast_decl_interface(
1984
+ name,
1985
+ params,
1986
+ members,
1987
+ annotations,
1988
+ location,
1989
+ get_comment(state, comment_pos.line)
1990
+ );
1991
+ }
1992
+
1993
+ /*
1994
+ module_self_types ::= {`:`} module_self_type `,` ... `,` <module_self_type>
1995
+
1996
+ module_self_type ::= <module_name>
1997
+ | module_name `[` type_list <`]`>
1998
+ */
1999
+ void parse_module_self_types(parserstate *state, VALUE array) {
2000
+ while (true) {
2001
+ range self_range;
2002
+ range name_range;
2003
+ range args_range = NULL_RANGE;
2004
+
2005
+ parser_advance(state);
2006
+
2007
+ self_range.start = state->current_token.range.start;
2008
+
2009
+ VALUE module_name = parse_type_name(state, CLASS_NAME | INTERFACE_NAME, &name_range);
2010
+ self_range.end = name_range.end;
2011
+
2012
+ VALUE args = rb_ary_new();
2013
+ if (state->next_token.type == pLBRACKET) {
2014
+ parser_advance(state);
2015
+ args_range.start = state->current_token.range.start;
2016
+ parse_type_list(state, pRBRACKET, args);
2017
+ parser_advance(state);
2018
+ self_range.end = args_range.end = state->current_token.range.end;
2019
+ }
2020
+
2021
+ VALUE location = rbs_new_location(state->buffer, self_range);
2022
+ rbs_loc *loc = rbs_check_location(location);
2023
+ rbs_loc_add_required_child(loc, rb_intern("name"), name_range);
2024
+ rbs_loc_add_optional_child(loc, rb_intern("args"), args_range);
2025
+
2026
+ VALUE self_type = rbs_ast_decl_module_self(module_name, args, location);
2027
+ rb_ary_push(array, self_type);
2028
+
2029
+ if (state->next_token.type == pCOMMA) {
2030
+ parser_advance(state);
2031
+ } else {
2032
+ break;
2033
+ }
2034
+ }
2035
+ }
2036
+
2037
+ VALUE parse_nested_decl(parserstate *state, const char *nested_in, position annot_pos, VALUE annotations);
2038
+
2039
+ /*
2040
+ module_members ::= {} ...<module_member> kEND
2041
+
2042
+ module_member ::= def_member
2043
+ | variable_member
2044
+ | mixin_member
2045
+ | alias_member
2046
+ | attribute_member
2047
+ | `public`
2048
+ | `private`
2049
+ */
2050
+ VALUE parse_module_members(parserstate *state) {
2051
+ VALUE members = rb_ary_new();
2052
+
2053
+ while (state->next_token.type != kEND) {
2054
+ VALUE member;
2055
+ VALUE annotations = rb_ary_new();
2056
+ position annot_pos = NullPosition;
2057
+
2058
+ parse_annotations(state, annotations, &annot_pos);
2059
+
2060
+ parser_advance(state);
2061
+
2062
+ switch (state->current_token.type)
2063
+ {
2064
+ case kDEF:
2065
+ member = parse_member_def(state, false, true, annot_pos, annotations);
2066
+ break;
2067
+
2068
+ case kINCLUDE:
2069
+ case kEXTEND:
2070
+ case kPREPEND:
2071
+ member = parse_mixin_member(state, false, annot_pos, annotations);
2072
+ break;
2073
+
2074
+ case kALIAS:
2075
+ member = parse_alias_member(state, false, annot_pos, annotations);
2076
+ break;
2077
+
2078
+
2079
+ case tAIDENT:
2080
+ case tA2IDENT:
2081
+ case kSELF:
2082
+ member = parse_variable_member(state, annot_pos, annotations);
2083
+ break;
2084
+
2085
+ case kATTRREADER:
2086
+ case kATTRWRITER:
2087
+ case kATTRACCESSOR:
2088
+ member = parse_attribute_member(state, annot_pos, annotations);
2089
+ break;
2090
+
2091
+ case kPUBLIC:
2092
+ case kPRIVATE:
2093
+ member = parse_visibility_member(state, annotations);
2094
+ break;
2095
+
2096
+ default:
2097
+ member = parse_nested_decl(state, "module", annot_pos, annotations);
2098
+ break;
2099
+ }
2100
+
2101
+ rb_ary_push(members, member);
2102
+ }
2103
+
2104
+ return members;
2105
+ }
2106
+
2107
+ /*
2108
+ module_decl ::= {`module`} module_name module_type_params module_members <kEND>
2109
+ | {`module`} module_name module_type_params `:` module_self_types module_members <kEND>
2110
+ */
2111
+ VALUE parse_module_decl(parserstate *state, position comment_pos, VALUE annotations) {
2112
+ range decl_range;
2113
+ range keyword_range;
2114
+ range name_range;
2115
+ range end_range;
2116
+ range type_params_range;
2117
+ range colon_range;
2118
+ range self_types_range;
2119
+
2120
+ parser_push_typevar_table(state, true);
2121
+
2122
+ position start = state->current_token.range.start;
2123
+ comment_pos = nonnull_pos_or(comment_pos, start);
2124
+ VALUE comment = get_comment(state, comment_pos.line);
2125
+
2126
+ keyword_range = state->current_token.range;
2127
+ decl_range.start = state->current_token.range.start;
2128
+
2129
+ parser_advance(state);
2130
+ VALUE module_name = parse_type_name(state, CLASS_NAME, &name_range);
2131
+ VALUE type_params = parse_module_type_params(state, &type_params_range);
2132
+ VALUE self_types = rb_ary_new();
2133
+
2134
+ if (state->next_token.type == pCOLON) {
2135
+ parser_advance(state);
2136
+ colon_range = state->current_token.range;
2137
+ self_types_range.start = state->next_token.range.start;
2138
+ parse_module_self_types(state, self_types);
2139
+ self_types_range.end = state->current_token.range.end;
2140
+ } else {
2141
+ colon_range = NULL_RANGE;
2142
+ self_types_range = NULL_RANGE;
2143
+ }
2144
+
2145
+ VALUE members = parse_module_members(state);
2146
+
2147
+ parser_advance_assert(state, kEND);
2148
+ end_range = state->current_token.range;
2149
+ decl_range.end = state->current_token.range.end;
2150
+
2151
+ VALUE location = rbs_new_location(state->buffer, decl_range);
2152
+ rbs_loc *loc = rbs_check_location(location);
2153
+ rbs_loc_add_required_child(loc, rb_intern("keyword"), keyword_range);
2154
+ rbs_loc_add_required_child(loc, rb_intern("name"), name_range);
2155
+ rbs_loc_add_required_child(loc, rb_intern("end"), end_range);
2156
+ rbs_loc_add_optional_child(loc, rb_intern("type_params"), type_params_range);
2157
+ rbs_loc_add_optional_child(loc, rb_intern("colon"), colon_range);
2158
+ rbs_loc_add_optional_child(loc, rb_intern("self_types"), self_types_range);
2159
+
2160
+ parser_pop_typevar_table(state);
2161
+
2162
+ return rbs_ast_decl_module(
2163
+ module_name,
2164
+ type_params,
2165
+ self_types,
2166
+ members,
2167
+ annotations,
2168
+ location,
2169
+ comment
2170
+ );
2171
+ }
2172
+
2173
+ /*
2174
+ class_decl_super ::= {} `<` <class_instance_name>
2175
+ | {<>}
2176
+ */
2177
+ VALUE parse_class_decl_super(parserstate *state, range *lt_range) {
2178
+ if (parser_advance_if(state, pLT)) {
2179
+ range super_range;
2180
+ range name_range;
2181
+ range args_range = NULL_RANGE;
2182
+
2183
+ VALUE name;
2184
+ VALUE args;
2185
+ VALUE location;
2186
+ rbs_loc *loc;
2187
+
2188
+ *lt_range = state->current_token.range;
2189
+ super_range.start = state->next_token.range.start;
2190
+
2191
+ args = rb_ary_new();
2192
+ class_instance_name(state, CLASS_NAME, &name, args, &name_range, &args_range);
2193
+
2194
+ super_range.end = args_range.end;
2195
+
2196
+ location = rbs_new_location(state->buffer, super_range);
2197
+ loc = rbs_check_location(location);
2198
+ rbs_loc_add_required_child(loc, rb_intern("name"), name_range);
2199
+ rbs_loc_add_optional_child(loc, rb_intern("args"), args_range);
2200
+
2201
+ return rbs_ast_decl_class_super(name, args, location);
2202
+ } else {
2203
+ *lt_range = NULL_RANGE;
2204
+ return Qnil;
2205
+ }
2206
+ }
2207
+
2208
+ /*
2209
+ class_decl ::= {`class`} class_name type_params class_decl_super class_members <`end`>
2210
+ */
2211
+ VALUE parse_class_decl(parserstate *state, position comment_pos, VALUE annotations) {
2212
+ range decl_range;
2213
+ range keyword_range;
2214
+ range name_range;
2215
+ range end_range;
2216
+ range type_params_range;
2217
+ range lt_range;
2218
+
2219
+ VALUE name;
2220
+ VALUE type_params;
2221
+ VALUE super;
2222
+ VALUE members;
2223
+ VALUE comment;
2224
+ VALUE location;
2225
+
2226
+ rbs_loc *loc;
2227
+
2228
+ parser_push_typevar_table(state, true);
2229
+
2230
+ decl_range.start = state->current_token.range.start;
2231
+ keyword_range = state->current_token.range;
2232
+
2233
+ comment_pos = nonnull_pos_or(comment_pos, decl_range.start);
2234
+ comment = get_comment(state, comment_pos.line);
2235
+
2236
+ parser_advance(state);
2237
+ name = parse_type_name(state, CLASS_NAME, &name_range);
2238
+ type_params = parse_module_type_params(state, &type_params_range);
2239
+ super = parse_class_decl_super(state, &lt_range);
2240
+ members = parse_module_members(state);
2241
+ parser_advance_assert(state, kEND);
2242
+ end_range = state->current_token.range;
2243
+
2244
+ decl_range.end = end_range.end;
2245
+
2246
+ parser_pop_typevar_table(state);
2247
+
2248
+ location = rbs_new_location(state->buffer, decl_range);
2249
+ loc = rbs_check_location(location);
2250
+ rbs_loc_add_required_child(loc, rb_intern("keyword"), keyword_range);
2251
+ rbs_loc_add_required_child(loc, rb_intern("name"), name_range);
2252
+ rbs_loc_add_required_child(loc, rb_intern("end"), end_range);
2253
+ rbs_loc_add_optional_child(loc, rb_intern("type_params"), type_params_range);
2254
+ rbs_loc_add_optional_child(loc, rb_intern("lt"), lt_range);
2255
+
2256
+ return rbs_ast_decl_class(
2257
+ name,
2258
+ type_params,
2259
+ super,
2260
+ members,
2261
+ annotations,
2262
+ location,
2263
+ comment
2264
+ );
2265
+ }
2266
+
2267
+ /*
2268
+ nested_decl ::= {<const_decl>}
2269
+ | {<class_decl>}
2270
+ | {<interface_decl>}
2271
+ | {<module_decl>}
2272
+ | {<class_decl>}
2273
+ */
2274
+ VALUE parse_nested_decl(parserstate *state, const char *nested_in, position annot_pos, VALUE annotations) {
2275
+ VALUE decl;
2276
+
2277
+ parser_push_typevar_table(state, true);
2278
+
2279
+ switch (state->current_token.type) {
2280
+ case tUIDENT:
2281
+ case pCOLON2:
2282
+ decl = parse_const_decl(state);
2283
+ break;
2284
+ case tGIDENT:
2285
+ decl = parse_global_decl(state);
2286
+ break;
2287
+ case kTYPE:
2288
+ decl = parse_type_decl(state, annot_pos, annotations);
2289
+ break;
2290
+ case kINTERFACE:
2291
+ decl = parse_interface_decl(state, annot_pos, annotations);
2292
+ break;
2293
+ case kMODULE:
2294
+ decl = parse_module_decl(state, annot_pos, annotations);
2295
+ break;
2296
+ case kCLASS:
2297
+ decl = parse_class_decl(state, annot_pos, annotations);
2298
+ break;
2299
+ default:
2300
+ raise_syntax_error(
2301
+ state,
2302
+ state->current_token,
2303
+ "unexpected token for class/module declaration member"
2304
+ );
2305
+ }
2306
+
2307
+ parser_pop_typevar_table(state);
2308
+
2309
+ return decl;
2310
+ }
2311
+
2312
+ VALUE parse_decl(parserstate *state) {
2313
+ VALUE annotations = rb_ary_new();
2314
+ position annot_pos = NullPosition;
2315
+
2316
+ parse_annotations(state, annotations, &annot_pos);
2317
+
2318
+ parser_advance(state);
2319
+ switch (state->current_token.type) {
2320
+ case tUIDENT:
2321
+ case pCOLON2:
2322
+ return parse_const_decl(state);
2323
+ case tGIDENT:
2324
+ return parse_global_decl(state);
2325
+ case kTYPE:
2326
+ return parse_type_decl(state, annot_pos, annotations);
2327
+ case kINTERFACE:
2328
+ return parse_interface_decl(state, annot_pos, annotations);
2329
+ case kMODULE:
2330
+ return parse_module_decl(state, annot_pos, annotations);
2331
+ case kCLASS:
2332
+ return parse_class_decl(state, annot_pos, annotations);
2333
+ default:
2334
+ raise_syntax_error(
2335
+ state,
2336
+ state->current_token,
2337
+ "cannot start a declaration"
2338
+ );
2339
+ }
2340
+ }
2341
+
2342
+ VALUE parse_signature(parserstate *state) {
2343
+ VALUE decls = rb_ary_new();
2344
+
2345
+ while (state->next_token.type != pEOF) {
2346
+ rb_ary_push(decls, parse_decl(state));
2347
+ }
2348
+
2349
+ return decls;
2350
+ }
2351
+
2352
+ static VALUE
2353
+ rbsparser_parse_type(VALUE self, VALUE buffer, VALUE line, VALUE column, VALUE variables)
2354
+ {
2355
+ parserstate *parser = alloc_parser(buffer, FIX2INT(line), FIX2INT(column), variables);
2356
+
2357
+ VALUE type = parse_type(parser);
2358
+ parser_advance_assert(parser, pEOF);
2359
+
2360
+ free_parser(parser);
2361
+
2362
+ return type;
2363
+ }
2364
+
2365
+ static VALUE
2366
+ rbsparser_parse_method_type(VALUE self, VALUE buffer, VALUE line, VALUE column, VALUE variables)
2367
+ {
2368
+ parserstate *parser = alloc_parser(buffer, FIX2INT(line), FIX2INT(column), variables);
2369
+ VALUE method_type = parse_method_type(parser);
2370
+ free(parser);
2371
+
2372
+ return method_type;
2373
+ }
2374
+
2375
+ static VALUE
2376
+ rbsparser_parse_signature(VALUE self, VALUE buffer, VALUE line, VALUE column)
2377
+ {
2378
+ parserstate *parser = alloc_parser(buffer, FIX2INT(line), FIX2INT(column), Qnil);
2379
+ VALUE signature = parse_signature(parser);
2380
+ free_parser(parser);
2381
+
2382
+ return signature;
2383
+ }
2384
+
2385
+ void rbs__init_parser() {
2386
+ RBS_Parser = rb_define_class_under(RBS, "Parser", rb_cObject);
2387
+ rb_define_singleton_method(RBS_Parser, "_parse_type", rbsparser_parse_type, 4);
2388
+ rb_define_singleton_method(RBS_Parser, "_parse_method_type", rbsparser_parse_method_type, 4);
2389
+ rb_define_singleton_method(RBS_Parser, "_parse_signature", rbsparser_parse_signature, 3);
2390
+
2391
+ RBS_Parser_KEYWORDS = rb_hash_new();
2392
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("bool"), INT2FIX(kBOOL));
2393
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("bot"), INT2FIX(kBOT));
2394
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("class"), INT2FIX(kCLASS));
2395
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("instance"), INT2FIX(kINSTANCE));
2396
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("interface"), INT2FIX(kINTERFACE));
2397
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("nil"), INT2FIX(kNIL));
2398
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("self"), INT2FIX(kSELF));
2399
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("singleton"), INT2FIX(kSINGLETON));
2400
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("top"), INT2FIX(kTOP));
2401
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("void"), INT2FIX(kVOID));
2402
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("type"), INT2FIX(kTYPE));
2403
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("unchecked"), INT2FIX(kUNCHECKED));
2404
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("in"), INT2FIX(kIN));
2405
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("out"), INT2FIX(kOUT));
2406
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("end"), INT2FIX(kEND));
2407
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("def"), INT2FIX(kDEF));
2408
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("include"), INT2FIX(kINCLUDE));
2409
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("extend"), INT2FIX(kEXTEND));
2410
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("prepend"), INT2FIX(kPREPEND));
2411
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("alias"), INT2FIX(kALIAS));
2412
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("module"), INT2FIX(kMODULE));
2413
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("attr_reader"), INT2FIX(kATTRREADER));
2414
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("attr_writer"), INT2FIX(kATTRWRITER));
2415
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("attr_accessor"), INT2FIX(kATTRACCESSOR));
2416
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("public"), INT2FIX(kPUBLIC));
2417
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("private"), INT2FIX(kPRIVATE));
2418
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("untyped"), INT2FIX(kUNTYPED));
2419
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("true"), INT2FIX(kTRUE));
2420
+ rb_hash_aset(RBS_Parser_KEYWORDS, rb_str_new_literal("false"), INT2FIX(kFALSE));
2421
+ rb_define_const(RBS_Parser, "KEYWORDS", RBS_Parser_KEYWORDS);
2422
+ }