Skip to content

Commit 3d92378

Browse files
committed
Implement parser
1 parent d9b2ecd commit 3d92378

File tree

8 files changed

+202
-37
lines changed

8 files changed

+202
-37
lines changed

config.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -497,3 +497,17 @@ nodes:
497497
c_type: rbs_location
498498
- name: comma_locations
499499
c_type: rbs_location_list
500+
- name: RBS::AST::Ruby::Annotations::InstanceVariableAnnotation
501+
fields:
502+
- name: prefix_location
503+
c_type: rbs_location
504+
- name: ivar_name
505+
c_type: rbs_ast_symbol
506+
- name: ivar_name_location
507+
c_type: rbs_location
508+
- name: colon_location
509+
c_type: rbs_location
510+
- name: type
511+
c_type: rbs_node
512+
- name: comment_location
513+
c_type: rbs_location

ext/rbs_extension/ast_translation.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,24 @@ VALUE rbs_struct_to_ruby_value(rbs_translation_context_t ctx, rbs_node_t *instan
588588
&h
589589
);
590590
}
591+
case RBS_AST_RUBY_ANNOTATIONS_INSTANCE_VARIABLE_ANNOTATION: {
592+
rbs_ast_ruby_annotations_instance_variable_annotation_t *node = (rbs_ast_ruby_annotations_instance_variable_annotation_t *) instance;
593+
594+
VALUE h = rb_hash_new();
595+
rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
596+
rb_hash_aset(h, ID2SYM(rb_intern("prefix_location")), rbs_loc_to_ruby_location(ctx, node->prefix_location));
597+
rb_hash_aset(h, ID2SYM(rb_intern("ivar_name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->ivar_name)); // rbs_ast_symbol
598+
rb_hash_aset(h, ID2SYM(rb_intern("ivar_name_location")), rbs_loc_to_ruby_location(ctx, node->ivar_name_location));
599+
rb_hash_aset(h, ID2SYM(rb_intern("colon_location")), rbs_loc_to_ruby_location(ctx, node->colon_location));
600+
rb_hash_aset(h, ID2SYM(rb_intern("type")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type)); // rbs_node
601+
rb_hash_aset(h, ID2SYM(rb_intern("comment_location")), rbs_loc_to_ruby_location(ctx, node->comment_location));
602+
603+
return CLASS_NEW_INSTANCE(
604+
RBS_AST_Ruby_Annotations_InstanceVariableAnnotation,
605+
1,
606+
&h
607+
);
608+
}
591609
case RBS_AST_RUBY_ANNOTATIONS_METHOD_TYPES_ANNOTATION: {
592610
rbs_ast_ruby_annotations_method_types_annotation_t *node = (rbs_ast_ruby_annotations_method_types_annotation_t *) instance;
593611

ext/rbs_extension/class_constants.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ VALUE RBS_AST_Members_Prepend;
5050
VALUE RBS_AST_Members_Private;
5151
VALUE RBS_AST_Members_Public;
5252
VALUE RBS_AST_Ruby_Annotations_ColonMethodTypeAnnotation;
53+
VALUE RBS_AST_Ruby_Annotations_InstanceVariableAnnotation;
5354
VALUE RBS_AST_Ruby_Annotations_MethodTypesAnnotation;
5455
VALUE RBS_AST_Ruby_Annotations_NodeTypeAssertion;
5556
VALUE RBS_AST_Ruby_Annotations_ReturnTypeAnnotation;
@@ -136,6 +137,7 @@ void rbs__init_constants(void) {
136137
IMPORT_CONSTANT(RBS_AST_Members_Private, RBS_AST_Members, "Private");
137138
IMPORT_CONSTANT(RBS_AST_Members_Public, RBS_AST_Members, "Public");
138139
IMPORT_CONSTANT(RBS_AST_Ruby_Annotations_ColonMethodTypeAnnotation, RBS_AST_Ruby_Annotations, "ColonMethodTypeAnnotation");
140+
IMPORT_CONSTANT(RBS_AST_Ruby_Annotations_InstanceVariableAnnotation, RBS_AST_Ruby_Annotations, "InstanceVariableAnnotation");
139141
IMPORT_CONSTANT(RBS_AST_Ruby_Annotations_MethodTypesAnnotation, RBS_AST_Ruby_Annotations, "MethodTypesAnnotation");
140142
IMPORT_CONSTANT(RBS_AST_Ruby_Annotations_NodeTypeAssertion, RBS_AST_Ruby_Annotations, "NodeTypeAssertion");
141143
IMPORT_CONSTANT(RBS_AST_Ruby_Annotations_ReturnTypeAnnotation, RBS_AST_Ruby_Annotations, "ReturnTypeAnnotation");

ext/rbs_extension/class_constants.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ extern VALUE RBS_AST_Members_Prepend;
5656
extern VALUE RBS_AST_Members_Private;
5757
extern VALUE RBS_AST_Members_Public;
5858
extern VALUE RBS_AST_Ruby_Annotations_ColonMethodTypeAnnotation;
59+
extern VALUE RBS_AST_Ruby_Annotations_InstanceVariableAnnotation;
5960
extern VALUE RBS_AST_Ruby_Annotations_MethodTypesAnnotation;
6061
extern VALUE RBS_AST_Ruby_Annotations_NodeTypeAssertion;
6162
extern VALUE RBS_AST_Ruby_Annotations_ReturnTypeAnnotation;

include/rbs/ast.h

Lines changed: 50 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -46,43 +46,44 @@ enum rbs_node_type {
4646
RBS_AST_MEMBERS_PRIVATE = 30,
4747
RBS_AST_MEMBERS_PUBLIC = 31,
4848
RBS_AST_RUBY_ANNOTATIONS_COLON_METHOD_TYPE_ANNOTATION = 32,
49-
RBS_AST_RUBY_ANNOTATIONS_METHOD_TYPES_ANNOTATION = 33,
50-
RBS_AST_RUBY_ANNOTATIONS_NODE_TYPE_ASSERTION = 34,
51-
RBS_AST_RUBY_ANNOTATIONS_RETURN_TYPE_ANNOTATION = 35,
52-
RBS_AST_RUBY_ANNOTATIONS_SKIP_ANNOTATION = 36,
53-
RBS_AST_RUBY_ANNOTATIONS_TYPE_APPLICATION_ANNOTATION = 37,
54-
RBS_AST_STRING = 38,
55-
RBS_AST_TYPE_PARAM = 39,
56-
RBS_METHOD_TYPE = 40,
57-
RBS_NAMESPACE = 41,
58-
RBS_SIGNATURE = 42,
59-
RBS_TYPE_NAME = 43,
60-
RBS_TYPES_ALIAS = 44,
61-
RBS_TYPES_BASES_ANY = 45,
62-
RBS_TYPES_BASES_BOOL = 46,
63-
RBS_TYPES_BASES_BOTTOM = 47,
64-
RBS_TYPES_BASES_CLASS = 48,
65-
RBS_TYPES_BASES_INSTANCE = 49,
66-
RBS_TYPES_BASES_NIL = 50,
67-
RBS_TYPES_BASES_SELF = 51,
68-
RBS_TYPES_BASES_TOP = 52,
69-
RBS_TYPES_BASES_VOID = 53,
70-
RBS_TYPES_BLOCK = 54,
71-
RBS_TYPES_CLASS_INSTANCE = 55,
72-
RBS_TYPES_CLASS_SINGLETON = 56,
73-
RBS_TYPES_FUNCTION = 57,
74-
RBS_TYPES_FUNCTION_PARAM = 58,
75-
RBS_TYPES_INTERFACE = 59,
76-
RBS_TYPES_INTERSECTION = 60,
77-
RBS_TYPES_LITERAL = 61,
78-
RBS_TYPES_OPTIONAL = 62,
79-
RBS_TYPES_PROC = 63,
80-
RBS_TYPES_RECORD = 64,
81-
RBS_TYPES_RECORD_FIELD_TYPE = 65,
82-
RBS_TYPES_TUPLE = 66,
83-
RBS_TYPES_UNION = 67,
84-
RBS_TYPES_UNTYPED_FUNCTION = 68,
85-
RBS_TYPES_VARIABLE = 69,
49+
RBS_AST_RUBY_ANNOTATIONS_INSTANCE_VARIABLE_ANNOTATION = 33,
50+
RBS_AST_RUBY_ANNOTATIONS_METHOD_TYPES_ANNOTATION = 34,
51+
RBS_AST_RUBY_ANNOTATIONS_NODE_TYPE_ASSERTION = 35,
52+
RBS_AST_RUBY_ANNOTATIONS_RETURN_TYPE_ANNOTATION = 36,
53+
RBS_AST_RUBY_ANNOTATIONS_SKIP_ANNOTATION = 37,
54+
RBS_AST_RUBY_ANNOTATIONS_TYPE_APPLICATION_ANNOTATION = 38,
55+
RBS_AST_STRING = 39,
56+
RBS_AST_TYPE_PARAM = 40,
57+
RBS_METHOD_TYPE = 41,
58+
RBS_NAMESPACE = 42,
59+
RBS_SIGNATURE = 43,
60+
RBS_TYPE_NAME = 44,
61+
RBS_TYPES_ALIAS = 45,
62+
RBS_TYPES_BASES_ANY = 46,
63+
RBS_TYPES_BASES_BOOL = 47,
64+
RBS_TYPES_BASES_BOTTOM = 48,
65+
RBS_TYPES_BASES_CLASS = 49,
66+
RBS_TYPES_BASES_INSTANCE = 50,
67+
RBS_TYPES_BASES_NIL = 51,
68+
RBS_TYPES_BASES_SELF = 52,
69+
RBS_TYPES_BASES_TOP = 53,
70+
RBS_TYPES_BASES_VOID = 54,
71+
RBS_TYPES_BLOCK = 55,
72+
RBS_TYPES_CLASS_INSTANCE = 56,
73+
RBS_TYPES_CLASS_SINGLETON = 57,
74+
RBS_TYPES_FUNCTION = 58,
75+
RBS_TYPES_FUNCTION_PARAM = 59,
76+
RBS_TYPES_INTERFACE = 60,
77+
RBS_TYPES_INTERSECTION = 61,
78+
RBS_TYPES_LITERAL = 62,
79+
RBS_TYPES_OPTIONAL = 63,
80+
RBS_TYPES_PROC = 64,
81+
RBS_TYPES_RECORD = 65,
82+
RBS_TYPES_RECORD_FIELD_TYPE = 66,
83+
RBS_TYPES_TUPLE = 67,
84+
RBS_TYPES_UNION = 68,
85+
RBS_TYPES_UNTYPED_FUNCTION = 69,
86+
RBS_TYPES_VARIABLE = 70,
8687
RBS_KEYWORD,
8788
RBS_AST_SYMBOL,
8889
};
@@ -406,6 +407,17 @@ typedef struct rbs_ast_ruby_annotations_colon_method_type_annotation {
406407
struct rbs_node *method_type;
407408
} rbs_ast_ruby_annotations_colon_method_type_annotation_t;
408409

410+
typedef struct rbs_ast_ruby_annotations_instance_variable_annotation {
411+
rbs_node_t base;
412+
413+
struct rbs_location *prefix_location;
414+
struct rbs_ast_symbol *ivar_name;
415+
struct rbs_location *ivar_name_location;
416+
struct rbs_location *colon_location;
417+
struct rbs_node *type;
418+
struct rbs_location *comment_location;
419+
} rbs_ast_ruby_annotations_instance_variable_annotation_t;
420+
409421
typedef struct rbs_ast_ruby_annotations_method_types_annotation {
410422
rbs_node_t base;
411423

@@ -718,6 +730,7 @@ rbs_ast_members_prepend_t *rbs_ast_members_prepend_new(rbs_allocator_t *allocato
718730
rbs_ast_members_private_t *rbs_ast_members_private_new(rbs_allocator_t *allocator, rbs_location_t *location);
719731
rbs_ast_members_public_t *rbs_ast_members_public_new(rbs_allocator_t *allocator, rbs_location_t *location);
720732
rbs_ast_ruby_annotations_colon_method_type_annotation_t *rbs_ast_ruby_annotations_colon_method_type_annotation_new(rbs_allocator_t *allocator, rbs_location_t *location, rbs_location_t *prefix_location, rbs_node_list_t *annotations, rbs_node_t *method_type);
733+
rbs_ast_ruby_annotations_instance_variable_annotation_t *rbs_ast_ruby_annotations_instance_variable_annotation_new(rbs_allocator_t *allocator, rbs_location_t *location, rbs_location_t *prefix_location, rbs_ast_symbol_t *ivar_name, rbs_location_t *ivar_name_location, rbs_location_t *colon_location, rbs_node_t *type, rbs_location_t *comment_location);
721734
rbs_ast_ruby_annotations_method_types_annotation_t *rbs_ast_ruby_annotations_method_types_annotation_new(rbs_allocator_t *allocator, rbs_location_t *location, rbs_location_t *prefix_location, rbs_node_list_t *overloads, rbs_location_list_t *vertical_bar_locations);
722735
rbs_ast_ruby_annotations_node_type_assertion_t *rbs_ast_ruby_annotations_node_type_assertion_new(rbs_allocator_t *allocator, rbs_location_t *location, rbs_location_t *prefix_location, rbs_node_t *type);
723736
rbs_ast_ruby_annotations_return_type_annotation_t *rbs_ast_ruby_annotations_return_type_annotation_new(rbs_allocator_t *allocator, rbs_location_t *location, rbs_location_t *prefix_location, rbs_location_t *return_location, rbs_location_t *colon_location, rbs_node_t *return_type, rbs_location_t *comment_location);

src/ast.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ const char *rbs_node_type_name(rbs_node_t *node) {
7777
return "RBS::AST::Members::Public";
7878
case RBS_AST_RUBY_ANNOTATIONS_COLON_METHOD_TYPE_ANNOTATION:
7979
return "RBS::AST::Ruby::Annotations::ColonMethodTypeAnnotation";
80+
case RBS_AST_RUBY_ANNOTATIONS_INSTANCE_VARIABLE_ANNOTATION:
81+
return "RBS::AST::Ruby::Annotations::InstanceVariableAnnotation";
8082
case RBS_AST_RUBY_ANNOTATIONS_METHOD_TYPES_ANNOTATION:
8183
return "RBS::AST::Ruby::Annotations::MethodTypesAnnotation";
8284
case RBS_AST_RUBY_ANNOTATIONS_NODE_TYPE_ASSERTION:
@@ -818,6 +820,25 @@ rbs_ast_ruby_annotations_colon_method_type_annotation_t *rbs_ast_ruby_annotation
818820
return instance;
819821
}
820822
#line 156 "prism/templates/src/ast.c.erb"
823+
rbs_ast_ruby_annotations_instance_variable_annotation_t *rbs_ast_ruby_annotations_instance_variable_annotation_new(rbs_allocator_t *allocator, rbs_location_t *location, rbs_location_t *prefix_location, rbs_ast_symbol_t *ivar_name, rbs_location_t *ivar_name_location, rbs_location_t *colon_location, rbs_node_t *type, rbs_location_t *comment_location) {
824+
rbs_ast_ruby_annotations_instance_variable_annotation_t *instance = rbs_allocator_alloc(allocator, rbs_ast_ruby_annotations_instance_variable_annotation_t);
825+
826+
*instance = (rbs_ast_ruby_annotations_instance_variable_annotation_t) {
827+
.base = (rbs_node_t) {
828+
.type = RBS_AST_RUBY_ANNOTATIONS_INSTANCE_VARIABLE_ANNOTATION,
829+
.location = location,
830+
},
831+
.prefix_location = prefix_location,
832+
.ivar_name = ivar_name,
833+
.ivar_name_location = ivar_name_location,
834+
.colon_location = colon_location,
835+
.type = type,
836+
.comment_location = comment_location,
837+
};
838+
839+
return instance;
840+
}
841+
#line 156 "prism/templates/src/ast.c.erb"
821842
rbs_ast_ruby_annotations_method_types_annotation_t *rbs_ast_ruby_annotations_method_types_annotation_new(rbs_allocator_t *allocator, rbs_location_t *location, rbs_location_t *prefix_location, rbs_node_list_t *overloads, rbs_location_list_t *vertical_bar_locations) {
822843
rbs_ast_ruby_annotations_method_types_annotation_t *instance = rbs_allocator_alloc(allocator, rbs_ast_ruby_annotations_method_types_annotation_t);
823844

src/parser.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3766,6 +3766,53 @@ static bool parse_inline_leading_annotation(rbs_parser_t *parser, rbs_ast_ruby_a
37663766
);
37673767
return true;
37683768
}
3769+
case tAIDENT: {
3770+
// Parse instance variable annotation: @rbs @name: Type
3771+
rbs_parser_advance(parser);
3772+
3773+
rbs_range_t ivar_name_range = parser->current_token.range;
3774+
rbs_location_t *ivar_name_loc = rbs_location_new(ALLOCATOR(), ivar_name_range);
3775+
3776+
// Extract the instance variable name as a symbol
3777+
rbs_string_t ivar_string = rbs_parser_peek_current_token(parser);
3778+
rbs_constant_id_t ivar_id = rbs_constant_pool_insert_string(&parser->constant_pool, ivar_string);
3779+
rbs_ast_symbol_t *ivar_name = rbs_ast_symbol_new(ALLOCATOR(), ivar_name_loc, &parser->constant_pool, ivar_id);
3780+
3781+
ADVANCE_ASSERT(parser, pCOLON);
3782+
3783+
rbs_range_t colon_range = parser->current_token.range;
3784+
rbs_location_t *colon_loc = rbs_location_new(ALLOCATOR(), colon_range);
3785+
3786+
rbs_node_t *type = NULL;
3787+
if (!rbs_parse_type(parser, &type, false)) {
3788+
return false;
3789+
}
3790+
3791+
rbs_location_t *comment_loc = NULL;
3792+
if (!parse_inline_comment(parser, &comment_loc)) {
3793+
return false;
3794+
}
3795+
3796+
rbs_range_t full_range = {
3797+
.start = rbs_range.start,
3798+
.end = parser->current_token.range.end
3799+
};
3800+
3801+
rbs_location_t *full_loc = rbs_location_new(ALLOCATOR(), full_range);
3802+
rbs_location_t *rbs_loc = rbs_location_new(ALLOCATOR(), rbs_range);
3803+
3804+
*annotation = (rbs_ast_ruby_annotations_t *) rbs_ast_ruby_annotations_instance_variable_annotation_new(
3805+
ALLOCATOR(),
3806+
full_loc,
3807+
rbs_loc,
3808+
ivar_name,
3809+
ivar_name_loc,
3810+
colon_loc,
3811+
type,
3812+
comment_loc
3813+
);
3814+
return true;
3815+
}
37693816
default: {
37703817
rbs_parser_set_error(parser, parser->next_token, true, "unexpected token for @rbs annotation");
37713818
return false;

test/rbs/inline_annotation_parsing_test.rb

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,4 +156,53 @@ def test_error__type_application
156156
Parser.parse_inline_trailing_annotation("[,String]", 0...)
157157
end
158158
end
159+
160+
def test_parse__instance_variable
161+
Parser.parse_inline_leading_annotation("@rbs @name: String", 0...).tap do |annot|
162+
assert_instance_of AST::Ruby::Annotations::InstanceVariableAnnotation, annot
163+
assert_equal "@rbs @name: String", annot.location.source
164+
assert_equal "@rbs", annot.prefix_location.source
165+
assert_equal "@name", annot.ivar_name_location.source
166+
assert_equal :@name, annot.ivar_name
167+
assert_equal ":", annot.colon_location.source
168+
assert_equal "String", annot.type.location.source
169+
assert_nil annot.comment_location
170+
end
171+
172+
Parser.parse_inline_leading_annotation("@rbs @age: Integer? -- person's age", 0...).tap do |annot|
173+
assert_instance_of AST::Ruby::Annotations::InstanceVariableAnnotation, annot
174+
assert_equal "@rbs @age: Integer? -- person's age", annot.location.source
175+
assert_equal "@rbs", annot.prefix_location.source
176+
assert_equal "@age", annot.ivar_name_location.source
177+
assert_equal :@age, annot.ivar_name
178+
assert_equal ":", annot.colon_location.source
179+
assert_equal "Integer?", annot.type.location.source
180+
assert_equal "-- person's age", annot.comment_location.source
181+
end
182+
183+
Parser.parse_inline_leading_annotation("@rbs @items: Array[String]", 0...).tap do |annot|
184+
assert_instance_of AST::Ruby::Annotations::InstanceVariableAnnotation, annot
185+
assert_equal "@rbs @items: Array[String]", annot.location.source
186+
assert_equal "@rbs", annot.prefix_location.source
187+
assert_equal "@items", annot.ivar_name_location.source
188+
assert_equal :@items, annot.ivar_name
189+
assert_equal ":", annot.colon_location.source
190+
assert_equal "Array[String]", annot.type.location.source
191+
assert_nil annot.comment_location
192+
end
193+
end
194+
195+
def test_error__instance_variable
196+
assert_raises RBS::ParsingError do
197+
Parser.parse_inline_leading_annotation("@rbs @name", 0...)
198+
end
199+
200+
assert_raises RBS::ParsingError do
201+
Parser.parse_inline_leading_annotation("@rbs @name:", 0...)
202+
end
203+
204+
assert_raises RBS::ParsingError do
205+
Parser.parse_inline_leading_annotation("@rbs name: String", 0...)
206+
end
207+
end
159208
end

0 commit comments

Comments
 (0)