Skip to content

Commit 38bcc0c

Browse files
authored
Merge pull request #2627 from ksss/self_allowed
`self` type is rejected depending on the context
2 parents e59a2ce + 50474e1 commit 38bcc0c

File tree

12 files changed

+235
-158
lines changed

12 files changed

+235
-158
lines changed

ext/rbs_extension/main.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ struct parse_type_arg {
8686
rbs_parser_t *parser;
8787
VALUE require_eof;
8888
VALUE void_allowed;
89+
VALUE self_allowed;
8990
};
9091

9192
struct parse_method_type_arg {
@@ -116,9 +117,10 @@ static VALUE parse_type_try(VALUE a) {
116117
}
117118

118119
bool void_allowed = RTEST(arg->void_allowed);
120+
bool self_allowed = RTEST(arg->self_allowed);
119121

120122
rbs_node_t *type;
121-
rbs_parse_type(parser, &type, void_allowed);
123+
rbs_parse_type(parser, &type, void_allowed, self_allowed);
122124

123125
raise_error_if_any(parser, arg->buffer);
124126

@@ -174,7 +176,7 @@ static rbs_parser_t *alloc_parser_from_buffer(VALUE buffer, int start_pos, int e
174176
);
175177
}
176178

177-
static VALUE rbsparser_parse_type(VALUE self, VALUE buffer, VALUE start_pos, VALUE end_pos, VALUE variables, VALUE require_eof, VALUE void_allowed) {
179+
static VALUE rbsparser_parse_type(VALUE self, VALUE buffer, VALUE start_pos, VALUE end_pos, VALUE variables, VALUE require_eof, VALUE void_allowed, VALUE self_allowed) {
178180
VALUE string = rb_funcall(buffer, rb_intern("content"), 0);
179181
StringValue(string);
180182
rb_encoding *encoding = rb_enc_get(string);
@@ -186,7 +188,8 @@ static VALUE rbsparser_parse_type(VALUE self, VALUE buffer, VALUE start_pos, VAL
186188
.encoding = encoding,
187189
.parser = parser,
188190
.require_eof = require_eof,
189-
.void_allowed = void_allowed
191+
.void_allowed = void_allowed,
192+
.self_allowed = self_allowed
190193
};
191194

192195
VALUE result = rb_ensure(parse_type_try, (VALUE) &arg, ensure_free_parser, (VALUE) parser);
@@ -450,7 +453,7 @@ void rbs__init_parser(void) {
450453
VALUE empty_array = rb_obj_freeze(rb_ary_new());
451454
rb_gc_register_mark_object(empty_array);
452455

453-
rb_define_singleton_method(RBS_Parser, "_parse_type", rbsparser_parse_type, 6);
456+
rb_define_singleton_method(RBS_Parser, "_parse_type", rbsparser_parse_type, 7);
454457
rb_define_singleton_method(RBS_Parser, "_parse_method_type", rbsparser_parse_method_type, 5);
455458
rb_define_singleton_method(RBS_Parser, "_parse_signature", rbsparser_parse_signature, 3);
456459
rb_define_singleton_method(RBS_Parser, "_parse_type_params", rbsparser_parse_type_params, 4);

include/rbs/parser.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ rbs_ast_comment_t *rbs_parser_get_comment(rbs_parser_t *parser, int subject_line
126126

127127
void rbs_parser_set_error(rbs_parser_t *parser, rbs_token_t tok, bool syntax_error, const char *fmt, ...) RBS_ATTRIBUTE_FORMAT(4, 5);
128128

129-
bool rbs_parse_type(rbs_parser_t *parser, rbs_node_t **type, bool void_allowed);
129+
bool rbs_parse_type(rbs_parser_t *parser, rbs_node_t **type, bool void_allowed, bool self_allowed);
130130
bool rbs_parse_method_type(rbs_parser_t *parser, rbs_method_type_t **method_type);
131131
bool rbs_parse_signature(rbs_parser_t *parser, rbs_signature_t **signature);
132132

lib/rbs/cli/validate.rb

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,6 @@ def validate_class_module_definition
122122
entry.each_decl do |decl|
123123
if super_class = decl.super_class
124124
super_class.args.each do |arg|
125-
no_self_type_validator(arg)
126125
no_classish_type_validator(arg)
127126
@validator.validate_type(arg, context: nil)
128127
end
@@ -132,7 +131,6 @@ def validate_class_module_definition
132131
entry.each_decl do |decl|
133132
decl.self_types.each do |self_type|
134133
self_type.args.each do |arg|
135-
no_self_type_validator(arg)
136134
no_classish_type_validator(arg)
137135
@validator.validate_type(arg, context: nil)
138136
end
@@ -161,19 +159,16 @@ def validate_class_module_definition
161159

162160
d.type_params.each do |param|
163161
if ub = param.upper_bound_type
164-
no_self_type_validator(ub)
165162
no_classish_type_validator(ub)
166163
@validator.validate_type(ub, context: nil)
167164
end
168165

169166
if lb = param.lower_bound_type
170-
no_self_type_validator(lb)
171167
no_classish_type_validator(lb)
172168
@validator.validate_type(lb, context: nil)
173169
end
174170

175171
if dt = param.default_type
176-
no_self_type_validator(dt)
177172
no_classish_type_validator(dt)
178173
@validator.validate_type(dt, context: nil)
179174
end
@@ -189,9 +184,6 @@ def validate_class_module_definition
189184
when AST::Members::MethodDefinition
190185
@validator.validate_method_definition(member, type_name: name)
191186
when AST::Members::Mixin
192-
member.args.each do |arg|
193-
no_self_type_validator(arg)
194-
end
195187
params =
196188
if member.name.class?
197189
module_decl = @env.normalized_module_entry(member.name) or raise
@@ -203,9 +195,6 @@ def validate_class_module_definition
203195
InvalidTypeApplicationError.check!(type_name: member.name, params: params, args: member.args, location: member.location)
204196
when AST::Members::Var
205197
@validator.validate_variable(member)
206-
if member.is_a?(AST::Members::ClassVariable)
207-
no_self_type_validator(member.type)
208-
end
209198
end
210199
end
211200
else
@@ -241,19 +230,16 @@ def validate_interface
241230

242231
decl.decl.type_params.each do |param|
243232
if ub = param.upper_bound_type
244-
no_self_type_validator(ub)
245233
no_classish_type_validator(ub)
246234
@validator.validate_type(ub, context: nil)
247235
end
248236

249237
if lb = param.lower_bound_type
250-
no_self_type_validator(lb)
251238
no_classish_type_validator(lb)
252239
@validator.validate_type(lb, context: nil)
253240
end
254241

255242
if dt = param.default_type
256-
no_self_type_validator(dt)
257243
no_classish_type_validator(dt)
258244
@validator.validate_type(dt, context: nil)
259245
end
@@ -280,7 +266,6 @@ def validate_constant
280266
RBS.logger.info "Validating constant: `#{name}`..."
281267
@validator.validate_type const.decl.type, context: const.context
282268
@builder.ensure_namespace!(name.namespace, location: const.decl.location)
283-
no_self_type_validator(const.decl.type)
284269
no_classish_type_validator(const.decl.type)
285270
rescue BaseError => error
286271
@errors.add(error)
@@ -291,7 +276,6 @@ def validate_global
291276
@env.global_decls.each do |name, global|
292277
RBS.logger.info "Validating global: `#{name}`..."
293278
@validator.validate_type global.decl.type, context: nil
294-
no_self_type_validator(global.decl.type)
295279
no_classish_type_validator(global.decl.type)
296280
rescue BaseError => error
297281
@errors.add(error)
@@ -315,27 +299,23 @@ def validate_type_alias
315299

316300
decl.decl.type_params.each do |param|
317301
if ub = param.upper_bound_type
318-
no_self_type_validator(ub)
319302
no_classish_type_validator(ub)
320303
@validator.validate_type(ub, context: nil)
321304
end
322305

323306
if lb = param.lower_bound_type
324-
no_self_type_validator(lb)
325307
no_classish_type_validator(lb)
326308
@validator.validate_type(lb, context: nil)
327309
end
328310

329311
if dt = param.default_type
330-
no_self_type_validator(dt)
331312
no_classish_type_validator(dt)
332313
@validator.validate_type(dt, context: nil)
333314
end
334315
end
335316

336317
TypeParamDefaultReferenceError.check!(decl.decl.type_params)
337318

338-
no_self_type_validator(decl.decl.type)
339319
no_classish_type_validator(decl.decl.type)
340320
rescue BaseError => error
341321
@errors.add(error)

lib/rbs/parser_aux.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55

66
module RBS
77
class Parser
8-
def self.parse_type(source, range: 0..., variables: [], require_eof: false, void_allowed: true)
8+
def self.parse_type(source, range: 0..., variables: [], require_eof: false, void_allowed: true, self_allowed: true)
99
buf = buffer(source)
10-
_parse_type(buf, range.begin || 0, range.end || buf.last_position, variables, require_eof, void_allowed)
10+
_parse_type(buf, range.begin || 0, range.end || buf.last_position, variables, require_eof, void_allowed, self_allowed)
1111
end
1212

1313
def self.parse_method_type(source, range: 0..., variables: [], require_eof: false)

lib/rbs/prototype/rb.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -372,8 +372,8 @@ def process(node, decls:, comments:, context:)
372372
end
373373

374374
value_node = node.children.last
375-
type = if value_node.nil?
376-
# Give up type prediction when node is MASGN.
375+
type = if value_node.nil? || value_node.type == :SELF
376+
# Give up type prediction when node is MASGN or SELF.
377377
Types::Bases::Any.new(location: nil)
378378
else
379379
literal_to_type(value_node)

sig/cli/validate.rbs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ module RBS
4444
def validate_constant: () -> void
4545
def validate_global: () -> void
4646
def validate_type_alias: () -> void
47-
def no_self_type_validator: (::RBS::Types::t | ::RBS::MethodType type) -> void
4847
def no_classish_type_validator: (::RBS::Types::t | ::RBS::MethodType type) -> void
48+
def no_self_type_validator: (::RBS::Types::t | ::RBS::MethodType type) -> void
4949
%a{deprecated} def void_type_context_validator: (::RBS::Types::t | ::RBS::MethodType type, ?bool allowed_here) -> void
5050
end
5151
end

sig/parser.rbs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,14 @@ module RBS
6969
# RBS::Parser.parse_type("void", void_allowed: false) # => Raises an syntax error
7070
# ```
7171
#
72-
def self.parse_type: (Buffer | String, ?range: Range[Integer?], ?variables: Array[Symbol], ?require_eof: bool, ?void_allowed: bool) -> Types::t?
72+
# The `self_allowed` keyword controls whether `self` is allowed as a type.
73+
#
74+
# ```ruby
75+
# RBS::Parser.parse_type("self", self_allowed: true) # => `self`
76+
# RBS::Parser.parse_type("self", self_allowed: false) # => Raises an syntax error
77+
# ```
78+
#
79+
def self.parse_type: (Buffer | String, ?range: Range[Integer?], ?variables: Array[Symbol], ?require_eof: bool, ?void_allowed: bool, ?self_allowed: bool) -> Types::t?
7380

7481
# Parse whole RBS file and return an array of declarations
7582
#
@@ -123,7 +130,7 @@ module RBS
123130

124131
def self.buffer: (String | Buffer source) -> Buffer
125132

126-
def self._parse_type: (Buffer, Integer start_pos, Integer end_pos, Array[Symbol] variables, bool require_eof, bool void_allowed) -> Types::t?
133+
def self._parse_type: (Buffer, Integer start_pos, Integer end_pos, Array[Symbol] variables, bool require_eof, bool void_allowed, bool self_allowed) -> Types::t?
127134

128135
def self._parse_method_type: (Buffer, Integer start_pos, Integer end_pos, Array[Symbol] variables, bool require_eof) -> MethodType?
129136

0 commit comments

Comments
 (0)