Skip to content

Commit 63ae39e

Browse files
committed
Implement parser
1 parent 3d0786e commit 63ae39e

2 files changed

Lines changed: 134 additions & 19 deletions

File tree

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; \
@@ -3635,6 +3670,46 @@ static bool parse_inline_comment(rbs_parser_t *parser, rbs_location_range *comme
36353670
return true;
36363671
}
36373672

3673+
NODISCARD
3674+
static bool parse_inline_param_type_annotation(rbs_parser_t *parser, rbs_ast_ruby_annotations_t **annotation, rbs_range_t rbs_range) {
3675+
rbs_parser_advance(parser);
3676+
3677+
rbs_location_range name_loc = rbs_location_range_current_token(parser);
3678+
3679+
ADVANCE_ASSERT(parser, pCOLON);
3680+
3681+
rbs_location_range colon_loc = rbs_location_range_current_token(parser);
3682+
3683+
rbs_node_t *param_type = NULL;
3684+
if (!rbs_parse_type(parser, &param_type, false, true, true)) {
3685+
return false;
3686+
}
3687+
3688+
rbs_location_range comment_loc = RBS_LOCATION_NULL_RANGE;
3689+
if (!parse_inline_comment(parser, &comment_loc)) {
3690+
return false;
3691+
}
3692+
3693+
rbs_location_range full_loc = {
3694+
.start_char = rbs_range.start.char_pos,
3695+
.start_byte = rbs_range.start.byte_pos,
3696+
.end_char = parser->current_token.range.end.char_pos,
3697+
.end_byte = parser->current_token.range.end.byte_pos,
3698+
};
3699+
3700+
*annotation = (rbs_ast_ruby_annotations_t *) rbs_ast_ruby_annotations_param_type_annotation_new(
3701+
ALLOCATOR(),
3702+
full_loc,
3703+
RBS_RANGE_LEX2AST(rbs_range),
3704+
name_loc,
3705+
colon_loc,
3706+
param_type,
3707+
comment_loc
3708+
);
3709+
3710+
return true;
3711+
}
3712+
36383713
NODISCARD
36393714
static bool parse_inline_leading_annotation(rbs_parser_t *parser, rbs_ast_ruby_annotations_t **annotation) {
36403715
switch (parser->next_token.type) {
@@ -3724,30 +3799,34 @@ static bool parse_inline_leading_annotation(rbs_parser_t *parser, rbs_ast_ruby_a
37243799
return true;
37253800
}
37263801
case kSKIP: {
3727-
rbs_parser_advance(parser);
3802+
if (parser->next_token2.type == pCOLON) {
3803+
return parse_inline_param_type_annotation(parser, annotation, rbs_range);
3804+
} else {
3805+
rbs_parser_advance(parser);
37283806

3729-
rbs_range_t skip_range = parser->current_token.range;
3807+
rbs_range_t skip_range = parser->current_token.range;
37303808

3731-
rbs_location_range comment_loc = RBS_LOCATION_NULL_RANGE;
3732-
if (!parse_inline_comment(parser, &comment_loc)) {
3733-
return false;
3734-
}
3809+
rbs_location_range comment_loc = RBS_LOCATION_NULL_RANGE;
3810+
if (!parse_inline_comment(parser, &comment_loc)) {
3811+
return false;
3812+
}
37353813

3736-
rbs_range_t full_range = {
3737-
.start = rbs_range.start,
3738-
.end = parser->current_token.range.end
3739-
};
3814+
rbs_range_t full_range = {
3815+
.start = rbs_range.start,
3816+
.end = parser->current_token.range.end
3817+
};
37403818

3741-
rbs_location_range full_loc = RBS_RANGE_LEX2AST(full_range);
3819+
rbs_location_range full_loc = RBS_RANGE_LEX2AST(full_range);
37423820

3743-
*annotation = (rbs_ast_ruby_annotations_t *) rbs_ast_ruby_annotations_skip_annotation_new(
3744-
ALLOCATOR(),
3745-
full_loc,
3746-
RBS_RANGE_LEX2AST(rbs_range),
3747-
RBS_RANGE_LEX2AST(skip_range),
3748-
comment_loc
3749-
);
3750-
return true;
3821+
*annotation = (rbs_ast_ruby_annotations_t *) rbs_ast_ruby_annotations_skip_annotation_new(
3822+
ALLOCATOR(),
3823+
full_loc,
3824+
RBS_RANGE_LEX2AST(rbs_range),
3825+
RBS_RANGE_LEX2AST(skip_range),
3826+
comment_loc
3827+
);
3828+
return true;
3829+
}
37513830
}
37523831
case kRETURN: {
37533832
rbs_parser_advance(parser);
@@ -3831,6 +3910,11 @@ static bool parse_inline_leading_annotation(rbs_parser_t *parser, rbs_ast_ruby_a
38313910
);
38323911
return true;
38333912
}
3913+
case tLIDENT:
3914+
PARAM_NAME_CASES
3915+
{
3916+
return parse_inline_param_type_annotation(parser, annotation, rbs_range);
3917+
}
38343918
default: {
38353919
rbs_parser_set_error(parser, parser->next_token, true, "unexpected token for @rbs annotation");
38363920
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)