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.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +0 -4
- data/.gitignore +1 -0
- data/CHANGELOG.md +6 -0
- data/Gemfile +1 -0
- data/Rakefile +7 -22
- data/core/kernel.rbs +4 -4
- data/core/trace_point.rbs +1 -1
- data/ext/rbs/extension/constants.c +140 -0
- data/ext/rbs/extension/constants.h +72 -0
- data/ext/rbs/extension/extconf.rb +3 -0
- data/ext/rbs/extension/lexer.c +1070 -0
- data/ext/rbs/extension/lexer.h +145 -0
- data/ext/rbs/extension/location.c +295 -0
- data/ext/rbs/extension/location.h +59 -0
- data/ext/rbs/extension/main.c +9 -0
- data/ext/rbs/extension/parser.c +2418 -0
- data/ext/rbs/extension/parser.h +23 -0
- data/ext/rbs/extension/parserstate.c +313 -0
- data/ext/rbs/extension/parserstate.h +141 -0
- data/ext/rbs/extension/rbs_extension.h +40 -0
- data/ext/rbs/extension/ruby_objs.c +585 -0
- data/ext/rbs/extension/ruby_objs.h +46 -0
- data/ext/rbs/extension/unescape.c +65 -0
- data/goodcheck.yml +1 -1
- data/lib/rbs/ast/comment.rb +0 -12
- data/lib/rbs/buffer.rb +4 -0
- data/lib/rbs/cli.rb +5 -8
- data/lib/rbs/collection/sources/git.rb +18 -3
- data/lib/rbs/errors.rb +14 -1
- data/lib/rbs/location.rb +221 -217
- data/lib/rbs/location_aux.rb +108 -0
- data/lib/rbs/locator.rb +10 -7
- data/lib/rbs/parser_aux.rb +24 -0
- data/lib/rbs/types.rb +2 -3
- data/lib/rbs/version.rb +1 -1
- data/lib/rbs/writer.rb +4 -2
- data/lib/rbs.rb +3 -7
- data/rbs.gemspec +2 -1
- data/sig/ancestor_builder.rbs +2 -2
- data/sig/annotation.rbs +2 -2
- data/sig/comment.rbs +7 -7
- data/sig/constant_table.rbs +1 -1
- data/sig/declarations.rbs +9 -9
- data/sig/definition.rbs +1 -1
- data/sig/definition_builder.rbs +2 -2
- data/sig/errors.rbs +30 -25
- data/sig/location.rbs +42 -79
- data/sig/locator.rbs +2 -2
- data/sig/members.rbs +7 -7
- data/sig/method_types.rbs +3 -3
- data/sig/parser.rbs +11 -21
- data/sig/types.rbs +45 -27
- data/sig/writer.rbs +1 -1
- data/stdlib/json/0/json.rbs +3 -3
- metadata +24 -6
- data/lib/rbs/parser.rb +0 -3614
@@ -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(¶ms);
|
578
|
+
|
579
|
+
if (state->next_token.type == pLPAREN) {
|
580
|
+
parser_advance(state);
|
581
|
+
parse_params(state, ¶ms);
|
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, <_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
|
+
}
|