Skip to content

Commit afe50c5

Browse files
committed
Implement parser
1 parent 1780c2f commit afe50c5

File tree

2 files changed

+134
-19
lines changed

2 files changed

+134
-19
lines changed

src/parser.c

Lines changed: 103 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,41 @@
6060
case kRETURN: \
6161
/* nop */
6262

63+
#define PARAM_NAME_CASES \
64+
case kBOOL:\
65+
case kBOT: \
66+
case kCLASS: \
67+
case kFALSE: \
68+
case kINSTANCE: \
69+
case kINTERFACE: \
70+
case kNIL: \
71+
case kSELF: \
72+
case kSINGLETON: \
73+
case kTOP: \
74+
case kTRUE: \
75+
case kVOID: \
76+
case kTYPE: \
77+
case kUNCHECKED: \
78+
case kIN: \
79+
case kOUT: \
80+
case kEND: \
81+
case kDEF: \
82+
case kINCLUDE: \
83+
case kEXTEND: \
84+
case kPREPEND: \
85+
case kALIAS: \
86+
case kMODULE: \
87+
case kATTRREADER: \
88+
case kATTRWRITER: \
89+
case kATTRACCESSOR: \
90+
case kPUBLIC: \
91+
case kPRIVATE: \
92+
case kUNTYPED: \
93+
case kUSE: \
94+
case kAS: \
95+
case k__TODO__: \
96+
/* nop */
97+
6398
#define CHECK_PARSE(call) \
6499
if (!call) { \
65100
return false; \
@@ -3632,6 +3667,46 @@ static bool parse_inline_comment(rbs_parser_t *parser, rbs_location_range *comme
36323667
return true;
36333668
}
36343669

3670+
NODISCARD
3671+
static bool parse_inline_param_type_annotation(rbs_parser_t *parser, rbs_ast_ruby_annotations_t **annotation, rbs_range_t rbs_range) {
3672+
rbs_parser_advance(parser);
3673+
3674+
rbs_location_range name_loc = rbs_location_range_current_token(parser);
3675+
3676+
ADVANCE_ASSERT(parser, pCOLON);
3677+
3678+
rbs_location_range colon_loc = rbs_location_range_current_token(parser);
3679+
3680+
rbs_node_t *param_type = NULL;
3681+
if (!rbs_parse_type(parser, &param_type, false, true, true)) {
3682+
return false;
3683+
}
3684+
3685+
rbs_location_range comment_loc = RBS_LOCATION_NULL_RANGE;
3686+
if (!parse_inline_comment(parser, &comment_loc)) {
3687+
return false;
3688+
}
3689+
3690+
rbs_location_range full_loc = {
3691+
.start_char = rbs_range.start.char_pos,
3692+
.start_byte = rbs_range.start.byte_pos,
3693+
.end_char = parser->current_token.range.end.char_pos,
3694+
.end_byte = parser->current_token.range.end.byte_pos,
3695+
};
3696+
3697+
*annotation = (rbs_ast_ruby_annotations_t *) rbs_ast_ruby_annotations_param_type_annotation_new(
3698+
ALLOCATOR(),
3699+
full_loc,
3700+
RBS_RANGE_LEX2AST(rbs_range),
3701+
name_loc,
3702+
colon_loc,
3703+
param_type,
3704+
comment_loc
3705+
);
3706+
3707+
return true;
3708+
}
3709+
36353710
NODISCARD
36363711
static bool parse_inline_leading_annotation(rbs_parser_t *parser, rbs_ast_ruby_annotations_t **annotation) {
36373712
switch (parser->next_token.type) {
@@ -3721,30 +3796,34 @@ static bool parse_inline_leading_annotation(rbs_parser_t *parser, rbs_ast_ruby_a
37213796
return true;
37223797
}
37233798
case kSKIP: {
3724-
rbs_parser_advance(parser);
3799+
if (parser->next_token2.type == pCOLON) {
3800+
return parse_inline_param_type_annotation(parser, annotation, rbs_range);
3801+
} else {
3802+
rbs_parser_advance(parser);
37253803

3726-
rbs_range_t skip_range = parser->current_token.range;
3804+
rbs_range_t skip_range = parser->current_token.range;
37273805

3728-
rbs_location_range comment_loc = RBS_LOCATION_NULL_RANGE;
3729-
if (!parse_inline_comment(parser, &comment_loc)) {
3730-
return false;
3731-
}
3806+
rbs_location_range comment_loc = RBS_LOCATION_NULL_RANGE;
3807+
if (!parse_inline_comment(parser, &comment_loc)) {
3808+
return false;
3809+
}
37323810

3733-
rbs_range_t full_range = {
3734-
.start = rbs_range.start,
3735-
.end = parser->current_token.range.end
3736-
};
3811+
rbs_range_t full_range = {
3812+
.start = rbs_range.start,
3813+
.end = parser->current_token.range.end
3814+
};
37373815

3738-
rbs_location_range full_loc = RBS_RANGE_LEX2AST(full_range);
3816+
rbs_location_range full_loc = RBS_RANGE_LEX2AST(full_range);
37393817

3740-
*annotation = (rbs_ast_ruby_annotations_t *) rbs_ast_ruby_annotations_skip_annotation_new(
3741-
ALLOCATOR(),
3742-
full_loc,
3743-
RBS_RANGE_LEX2AST(rbs_range),
3744-
RBS_RANGE_LEX2AST(skip_range),
3745-
comment_loc
3746-
);
3747-
return true;
3818+
*annotation = (rbs_ast_ruby_annotations_t *) rbs_ast_ruby_annotations_skip_annotation_new(
3819+
ALLOCATOR(),
3820+
full_loc,
3821+
RBS_RANGE_LEX2AST(rbs_range),
3822+
RBS_RANGE_LEX2AST(skip_range),
3823+
comment_loc
3824+
);
3825+
return true;
3826+
}
37483827
}
37493828
case kRETURN: {
37503829
rbs_parser_advance(parser);
@@ -3828,6 +3907,11 @@ static bool parse_inline_leading_annotation(rbs_parser_t *parser, rbs_ast_ruby_a
38283907
);
38293908
return true;
38303909
}
3910+
case tLIDENT:
3911+
PARAM_NAME_CASES
3912+
{
3913+
return parse_inline_param_type_annotation(parser, annotation, rbs_range);
3914+
}
38313915
default: {
38323916
rbs_parser_set_error(parser, parser->next_token, true, "unexpected token for @rbs annotation");
38333917
return false;

test/rbs/inline_annotation_parsing_test.rb

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,4 +362,35 @@ def test_parse__method_types_annotation__only_dot3
362362
assert_equal "...", annot.dot3_location.source
363363
end
364364
end
365+
366+
def test_parse__param_type
367+
Parser.parse_inline_leading_annotation("@rbs x: untyped", 0...).tap do |annot|
368+
assert_instance_of AST::Ruby::Annotations::ParamTypeAnnotation, annot
369+
assert_equal "@rbs x: untyped", annot.location.source
370+
assert_equal "x", annot.name_location.source
371+
assert_equal ":", annot.colon_location.source
372+
assert_equal "untyped", annot.param_type.location.source
373+
assert_nil annot.comment_location
374+
end
375+
376+
Parser.parse_inline_leading_annotation("@rbs abc: untyped -- some comment here", 0...).tap do |annot|
377+
assert_instance_of AST::Ruby::Annotations::ParamTypeAnnotation, annot
378+
assert_equal "@rbs abc: untyped -- some comment here", annot.location.source
379+
assert_equal "abc", annot.name_location.source
380+
assert_equal ":", annot.colon_location.source
381+
assert_equal "untyped", annot.param_type.location.source
382+
assert_equal "-- some comment here", annot.comment_location.source
383+
end
384+
end
385+
386+
def test_parse__param_type__skip
387+
Parser.parse_inline_leading_annotation("@rbs skip: untyped", 0...).tap do |annot|
388+
assert_instance_of AST::Ruby::Annotations::ParamTypeAnnotation, annot
389+
assert_equal "@rbs skip: untyped", annot.location.source
390+
assert_equal "skip", annot.name_location.source
391+
assert_equal ":", annot.colon_location.source
392+
assert_equal "untyped", annot.param_type.location.source
393+
assert_nil annot.comment_location
394+
end
395+
end
365396
end

0 commit comments

Comments
 (0)