Skip to content

Commit 94facd8

Browse files
committed
Parser inline leading @rbs METHOD-TYPEs annotation
1 parent 7ac54d4 commit 94facd8

File tree

2 files changed

+91
-0
lines changed

2 files changed

+91
-0
lines changed

ext/rbs_extension/parser.c

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2874,6 +2874,39 @@ static void parse_method_overload(parserstate *state, VALUE *annotations, VALUE
28742874
*method_type = parse_method_type(state);
28752875
}
28762876

2877+
/**
2878+
* @brief Parses inline method overload definitions and updates `overloads` and `bar_locations`
2879+
*
2880+
* inline_method_overloads ::= {} <overload> -- returns true
2881+
* | {} overload `|` ... `|` overload -- returns true
2882+
* | {<>} -- returns false
2883+
*
2884+
*
2885+
* @param state
2886+
* @param overloads
2887+
* @param bar_location
2888+
*/
2889+
static void parse_inline_method_overloads(parserstate *state, VALUE *overloads, VALUE *bar_locations) {
2890+
while (true) {
2891+
VALUE annotations = EMPTY_ARRAY;
2892+
VALUE method_type;
2893+
2894+
parse_method_overload(state, &annotations, &method_type);
2895+
2896+
VALUE overload = rbs_ast_members_method_definition_overload(annotations, method_type);
2897+
2898+
rb_ary_push(*overloads, overload);
2899+
2900+
if (state->next_token.type == pBAR) {
2901+
parser_advance(state);
2902+
melt_array(bar_locations);
2903+
rb_ary_push(*bar_locations, rbs_new_location(state->buffer, state->current_token.range));
2904+
} else {
2905+
return;
2906+
}
2907+
}
2908+
}
2909+
28772910
static VALUE parse_inline_leading_annotation(parserstate *state) {
28782911
switch (state->next_token.type) {
28792912
case pCOLON: {
@@ -2893,6 +2926,36 @@ static VALUE parse_inline_leading_annotation(parserstate *state) {
28932926
method_type
28942927
);
28952928
}
2929+
case kATRBS: {
2930+
range rbs_range = state->next_token.range;
2931+
parser_advance(state);
2932+
2933+
switch (state->next_token.type) {
2934+
case pLPAREN:
2935+
case pLBRACKET:
2936+
case pLBRACE:
2937+
case tANNOTATION: {
2938+
VALUE overloads = rb_ary_new();
2939+
VALUE bar_locations = EMPTY_ARRAY;
2940+
2941+
parse_inline_method_overloads(state, &overloads, &bar_locations);
2942+
2943+
return rbs_ast_ruby_annotations_method_types_annotation(
2944+
rbs_new_location(state->buffer, (range) { .start = rbs_range.start, .end = state->current_token.range.end }),
2945+
rbs_new_location(state->buffer, rbs_range),
2946+
overloads,
2947+
bar_locations
2948+
);
2949+
}
2950+
default: {
2951+
raise_syntax_error(
2952+
state,
2953+
state->next_token,
2954+
"unexpected token for @rbs annotation"
2955+
);
2956+
}
2957+
}
2958+
}
28962959
default: {
28972960
raise_syntax_error(
28982961
state,

test/rbs/inline_annotation_parsing_test.rb

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,32 @@ def test_parse__colon_method_type_annotation
4545
assert_equal ["a", "b"], annot.annotations.map(&:string)
4646
end
4747
end
48+
49+
def test_parse__rbs_method_types_annotation
50+
Parser.parse_inline_leading_annotation("@rbs %a{a} (String) -> void", 0...).tap do |annot|
51+
assert_instance_of AST::Ruby::Annotations::MethodTypesAnnotation, annot
52+
assert_equal "@rbs %a{a} (String) -> void", annot.location.source
53+
assert_equal "@rbs", annot.prefix_location.source
54+
annot.overloads[0].tap do |overload|
55+
assert_equal "(String) -> void", overload.method_type.location.source
56+
assert_equal ["a"], overload.annotations.map(&:string)
57+
end
58+
assert_empty annot.vertical_bar_locations
59+
end
60+
61+
Parser.parse_inline_leading_annotation("@rbs %a{a} (String) -> void | [T] (T) -> T", 0...).tap do |annot|
62+
assert_instance_of AST::Ruby::Annotations::MethodTypesAnnotation, annot
63+
assert_equal "@rbs %a{a} (String) -> void | [T] (T) -> T", annot.location.source
64+
assert_equal "@rbs", annot.prefix_location.source
65+
annot.overloads[0].tap do |overload|
66+
assert_equal "(String) -> void", overload.method_type.location.source
67+
assert_equal ["a"], overload.annotations.map(&:string)
68+
end
69+
annot.overloads[1].tap do |overload|
70+
assert_equal "[T] (T) -> T", overload.method_type.location.source
71+
assert_equal [], overload.annotations.map(&:string)
72+
end
73+
assert_equal ["|"], annot.vertical_bar_locations.map(&:source)
74+
end
75+
end
4876
end

0 commit comments

Comments
 (0)