diff --git a/ext/rbs_extension/main.c b/ext/rbs_extension/main.c index 6d3237b4e1..766a6cc06b 100644 --- a/ext/rbs_extension/main.c +++ b/ext/rbs_extension/main.c @@ -86,6 +86,7 @@ struct parse_type_arg { rbs_parser_t *parser; VALUE require_eof; VALUE void_allowed; + VALUE self_allowed; }; struct parse_method_type_arg { @@ -116,9 +117,10 @@ static VALUE parse_type_try(VALUE a) { } bool void_allowed = RTEST(arg->void_allowed); + bool self_allowed = RTEST(arg->self_allowed); rbs_node_t *type; - rbs_parse_type(parser, &type, void_allowed); + rbs_parse_type(parser, &type, void_allowed, self_allowed); raise_error_if_any(parser, arg->buffer); @@ -174,7 +176,7 @@ static rbs_parser_t *alloc_parser_from_buffer(VALUE buffer, int start_pos, int e ); } -static VALUE rbsparser_parse_type(VALUE self, VALUE buffer, VALUE start_pos, VALUE end_pos, VALUE variables, VALUE require_eof, VALUE void_allowed) { +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) { VALUE string = rb_funcall(buffer, rb_intern("content"), 0); StringValue(string); rb_encoding *encoding = rb_enc_get(string); @@ -186,7 +188,8 @@ static VALUE rbsparser_parse_type(VALUE self, VALUE buffer, VALUE start_pos, VAL .encoding = encoding, .parser = parser, .require_eof = require_eof, - .void_allowed = void_allowed + .void_allowed = void_allowed, + .self_allowed = self_allowed }; VALUE result = rb_ensure(parse_type_try, (VALUE) &arg, ensure_free_parser, (VALUE) parser); @@ -450,7 +453,7 @@ void rbs__init_parser(void) { VALUE empty_array = rb_obj_freeze(rb_ary_new()); rb_gc_register_mark_object(empty_array); - rb_define_singleton_method(RBS_Parser, "_parse_type", rbsparser_parse_type, 6); + rb_define_singleton_method(RBS_Parser, "_parse_type", rbsparser_parse_type, 7); rb_define_singleton_method(RBS_Parser, "_parse_method_type", rbsparser_parse_method_type, 5); rb_define_singleton_method(RBS_Parser, "_parse_signature", rbsparser_parse_signature, 3); rb_define_singleton_method(RBS_Parser, "_parse_type_params", rbsparser_parse_type_params, 4); diff --git a/include/rbs/parser.h b/include/rbs/parser.h index 7f69672647..339235deb8 100644 --- a/include/rbs/parser.h +++ b/include/rbs/parser.h @@ -126,7 +126,7 @@ rbs_ast_comment_t *rbs_parser_get_comment(rbs_parser_t *parser, int subject_line void rbs_parser_set_error(rbs_parser_t *parser, rbs_token_t tok, bool syntax_error, const char *fmt, ...) RBS_ATTRIBUTE_FORMAT(4, 5); -bool rbs_parse_type(rbs_parser_t *parser, rbs_node_t **type, bool void_allowed); +bool rbs_parse_type(rbs_parser_t *parser, rbs_node_t **type, bool void_allowed, bool self_allowed); bool rbs_parse_method_type(rbs_parser_t *parser, rbs_method_type_t **method_type); bool rbs_parse_signature(rbs_parser_t *parser, rbs_signature_t **signature); diff --git a/lib/rbs/cli/validate.rb b/lib/rbs/cli/validate.rb index 5247a9a705..42be20eeee 100644 --- a/lib/rbs/cli/validate.rb +++ b/lib/rbs/cli/validate.rb @@ -122,7 +122,6 @@ def validate_class_module_definition entry.each_decl do |decl| if super_class = decl.super_class super_class.args.each do |arg| - no_self_type_validator(arg) no_classish_type_validator(arg) @validator.validate_type(arg, context: nil) end @@ -132,7 +131,6 @@ def validate_class_module_definition entry.each_decl do |decl| decl.self_types.each do |self_type| self_type.args.each do |arg| - no_self_type_validator(arg) no_classish_type_validator(arg) @validator.validate_type(arg, context: nil) end @@ -161,19 +159,16 @@ def validate_class_module_definition d.type_params.each do |param| if ub = param.upper_bound_type - no_self_type_validator(ub) no_classish_type_validator(ub) @validator.validate_type(ub, context: nil) end if lb = param.lower_bound_type - no_self_type_validator(lb) no_classish_type_validator(lb) @validator.validate_type(lb, context: nil) end if dt = param.default_type - no_self_type_validator(dt) no_classish_type_validator(dt) @validator.validate_type(dt, context: nil) end @@ -189,9 +184,6 @@ def validate_class_module_definition when AST::Members::MethodDefinition @validator.validate_method_definition(member, type_name: name) when AST::Members::Mixin - member.args.each do |arg| - no_self_type_validator(arg) - end params = if member.name.class? module_decl = @env.normalized_module_entry(member.name) or raise @@ -203,9 +195,6 @@ def validate_class_module_definition InvalidTypeApplicationError.check!(type_name: member.name, params: params, args: member.args, location: member.location) when AST::Members::Var @validator.validate_variable(member) - if member.is_a?(AST::Members::ClassVariable) - no_self_type_validator(member.type) - end end end else @@ -241,19 +230,16 @@ def validate_interface decl.decl.type_params.each do |param| if ub = param.upper_bound_type - no_self_type_validator(ub) no_classish_type_validator(ub) @validator.validate_type(ub, context: nil) end if lb = param.lower_bound_type - no_self_type_validator(lb) no_classish_type_validator(lb) @validator.validate_type(lb, context: nil) end if dt = param.default_type - no_self_type_validator(dt) no_classish_type_validator(dt) @validator.validate_type(dt, context: nil) end @@ -280,7 +266,6 @@ def validate_constant RBS.logger.info "Validating constant: `#{name}`..." @validator.validate_type const.decl.type, context: const.context @builder.ensure_namespace!(name.namespace, location: const.decl.location) - no_self_type_validator(const.decl.type) no_classish_type_validator(const.decl.type) rescue BaseError => error @errors.add(error) @@ -291,7 +276,6 @@ def validate_global @env.global_decls.each do |name, global| RBS.logger.info "Validating global: `#{name}`..." @validator.validate_type global.decl.type, context: nil - no_self_type_validator(global.decl.type) no_classish_type_validator(global.decl.type) rescue BaseError => error @errors.add(error) @@ -315,19 +299,16 @@ def validate_type_alias decl.decl.type_params.each do |param| if ub = param.upper_bound_type - no_self_type_validator(ub) no_classish_type_validator(ub) @validator.validate_type(ub, context: nil) end if lb = param.lower_bound_type - no_self_type_validator(lb) no_classish_type_validator(lb) @validator.validate_type(lb, context: nil) end if dt = param.default_type - no_self_type_validator(dt) no_classish_type_validator(dt) @validator.validate_type(dt, context: nil) end @@ -335,7 +316,6 @@ def validate_type_alias TypeParamDefaultReferenceError.check!(decl.decl.type_params) - no_self_type_validator(decl.decl.type) no_classish_type_validator(decl.decl.type) rescue BaseError => error @errors.add(error) diff --git a/lib/rbs/parser_aux.rb b/lib/rbs/parser_aux.rb index 529cfb806e..97b74f73cb 100644 --- a/lib/rbs/parser_aux.rb +++ b/lib/rbs/parser_aux.rb @@ -5,9 +5,9 @@ module RBS class Parser - def self.parse_type(source, range: 0..., variables: [], require_eof: false, void_allowed: true) + def self.parse_type(source, range: 0..., variables: [], require_eof: false, void_allowed: true, self_allowed: true) buf = buffer(source) - _parse_type(buf, range.begin || 0, range.end || buf.last_position, variables, require_eof, void_allowed) + _parse_type(buf, range.begin || 0, range.end || buf.last_position, variables, require_eof, void_allowed, self_allowed) end def self.parse_method_type(source, range: 0..., variables: [], require_eof: false) diff --git a/lib/rbs/prototype/rb.rb b/lib/rbs/prototype/rb.rb index c5aedc12d5..c90575eec4 100644 --- a/lib/rbs/prototype/rb.rb +++ b/lib/rbs/prototype/rb.rb @@ -372,8 +372,8 @@ def process(node, decls:, comments:, context:) end value_node = node.children.last - type = if value_node.nil? - # Give up type prediction when node is MASGN. + type = if value_node.nil? || value_node.type == :SELF + # Give up type prediction when node is MASGN or SELF. Types::Bases::Any.new(location: nil) else literal_to_type(value_node) diff --git a/sig/cli/validate.rbs b/sig/cli/validate.rbs index c57adc67bb..338a609b18 100644 --- a/sig/cli/validate.rbs +++ b/sig/cli/validate.rbs @@ -44,8 +44,8 @@ module RBS def validate_constant: () -> void def validate_global: () -> void def validate_type_alias: () -> void - def no_self_type_validator: (::RBS::Types::t | ::RBS::MethodType type) -> void def no_classish_type_validator: (::RBS::Types::t | ::RBS::MethodType type) -> void + def no_self_type_validator: (::RBS::Types::t | ::RBS::MethodType type) -> void %a{deprecated} def void_type_context_validator: (::RBS::Types::t | ::RBS::MethodType type, ?bool allowed_here) -> void end end diff --git a/sig/parser.rbs b/sig/parser.rbs index e9328d0a2b..54f5d3ea52 100644 --- a/sig/parser.rbs +++ b/sig/parser.rbs @@ -69,7 +69,14 @@ module RBS # RBS::Parser.parse_type("void", void_allowed: false) # => Raises an syntax error # ``` # - def self.parse_type: (Buffer | String, ?range: Range[Integer?], ?variables: Array[Symbol], ?require_eof: bool, ?void_allowed: bool) -> Types::t? + # The `self_allowed` keyword controls whether `self` is allowed as a type. + # + # ```ruby + # RBS::Parser.parse_type("self", self_allowed: true) # => `self` + # RBS::Parser.parse_type("self", self_allowed: false) # => Raises an syntax error + # ``` + # + def self.parse_type: (Buffer | String, ?range: Range[Integer?], ?variables: Array[Symbol], ?require_eof: bool, ?void_allowed: bool, ?self_allowed: bool) -> Types::t? # Parse whole RBS file and return an array of declarations # @@ -123,7 +130,7 @@ module RBS def self.buffer: (String | Buffer source) -> Buffer - def self._parse_type: (Buffer, Integer start_pos, Integer end_pos, Array[Symbol] variables, bool require_eof, bool void_allowed) -> Types::t? + 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? def self._parse_method_type: (Buffer, Integer start_pos, Integer end_pos, Array[Symbol] variables, bool require_eof) -> MethodType? diff --git a/src/parser.c b/src/parser.c index c023a26204..f75060dda3 100644 --- a/src/parser.c +++ b/src/parser.c @@ -120,8 +120,8 @@ static rbs_location_t *rbs_location_current_token(rbs_parser_t *parser) { return rbs_location_new(ALLOCATOR(), parser->current_token.range); } -static bool parse_optional(rbs_parser_t *parser, rbs_node_t **optional, bool void_allowed); -static bool parse_simple(rbs_parser_t *parser, rbs_node_t **type, bool void_allowed); +static bool parse_optional(rbs_parser_t *parser, rbs_node_t **optional, bool void_allowed, bool self_allowed); +static bool parse_simple(rbs_parser_t *parser, rbs_node_t **type, bool void_allowed, bool self_allowed); /** * @returns A borrowed copy of the current token, which does *not* need to be freed. @@ -244,10 +244,10 @@ error_handling: { | {} type `,` ... `,` eol */ NODISCARD -static bool parse_type_list(rbs_parser_t *parser, enum RBSTokenType eol, rbs_node_list_t *types, bool void_allowed) { +static bool parse_type_list(rbs_parser_t *parser, enum RBSTokenType eol, rbs_node_list_t *types, bool void_allowed, bool self_allowed) { while (true) { rbs_node_t *type; - CHECK_PARSE(rbs_parse_type(parser, &type, void_allowed)); + CHECK_PARSE(rbs_parse_type(parser, &type, void_allowed, self_allowed)); rbs_node_list_append(types, type); if (parser->next_token.type == pCOMMA) { @@ -274,10 +274,10 @@ static bool parse_type_list(rbs_parser_t *parser, enum RBSTokenType eol, rbs_nod | {} type `,` ... `,` eol */ NODISCARD -static bool parse_type_list_with_commas(rbs_parser_t *parser, enum RBSTokenType eol, rbs_node_list_t *types, rbs_location_list_t *comma_locations, bool void_allowed) { +static bool parse_type_list_with_commas(rbs_parser_t *parser, enum RBSTokenType eol, rbs_node_list_t *types, rbs_location_list_t *comma_locations, bool void_allowed, bool self_allowed) { while (true) { rbs_node_t *type; - CHECK_PARSE(rbs_parse_type(parser, &type, void_allowed)); + CHECK_PARSE(rbs_parse_type(parser, &type, void_allowed, self_allowed)); rbs_node_list_append(types, type); if (parser->next_token.type == pCOMMA) { @@ -326,11 +326,11 @@ static bool is_keyword_token(enum RBSTokenType type) { | {} type */ NODISCARD -static bool parse_function_param(rbs_parser_t *parser, rbs_types_function_param_t **function_param) { +static bool parse_function_param(rbs_parser_t *parser, rbs_types_function_param_t **function_param, bool self_allowed) { rbs_range_t type_range; type_range.start = parser->next_token.range.start; rbs_node_t *type; - CHECK_PARSE(rbs_parse_type(parser, &type, false)); + CHECK_PARSE(rbs_parse_type(parser, &type, false, self_allowed)); type_range.end = parser->current_token.range.end; if (parser->next_token.type == pCOMMA || parser->next_token.type == pRPAREN) { @@ -409,7 +409,7 @@ static bool parse_keyword_key(rbs_parser_t *parser, rbs_ast_symbol_t **key) { keyword ::= {} keyword `:` */ NODISCARD -static bool parse_keyword(rbs_parser_t *parser, rbs_hash_t *keywords, rbs_hash_t *memo) { +static bool parse_keyword(rbs_parser_t *parser, rbs_hash_t *keywords, rbs_hash_t *memo, bool self_allowed) { rbs_ast_symbol_t *key = NULL; CHECK_PARSE(parse_keyword_key(parser, &key)); @@ -423,7 +423,7 @@ static bool parse_keyword(rbs_parser_t *parser, rbs_hash_t *keywords, rbs_hash_t ADVANCE_ASSERT(parser, pCOLON); rbs_types_function_param_t *param = NULL; - CHECK_PARSE(parse_function_param(parser, ¶m)); + CHECK_PARSE(parse_function_param(parser, ¶m, self_allowed)); rbs_hash_set(keywords, (rbs_node_t *) key, (rbs_node_t *) param); @@ -494,7 +494,7 @@ static bool parser_advance_if(rbs_parser_t *parser, enum RBSTokenType type) { | {} `**` */ NODISCARD -static bool parse_params(rbs_parser_t *parser, method_params *params) { +static bool parse_params(rbs_parser_t *parser, method_params *params, bool self_allowed) { if (parser->next_token.type == pQUESTION && parser->next_token2.type == pRPAREN) { params->required_positionals = NULL; rbs_parser_advance(parser); @@ -523,7 +523,7 @@ static bool parse_params(rbs_parser_t *parser, method_params *params) { } rbs_types_function_param_t *param = NULL; - CHECK_PARSE(parse_function_param(parser, ¶m)); + CHECK_PARSE(parse_function_param(parser, ¶m, self_allowed)); rbs_node_list_append(params->required_positionals, (rbs_node_t *) param); break; @@ -541,13 +541,13 @@ static bool parse_params(rbs_parser_t *parser, method_params *params) { rbs_parser_advance(parser); if (is_keyword(parser)) { - CHECK_PARSE(parse_keyword(parser, params->optional_keywords, memo)); + CHECK_PARSE(parse_keyword(parser, params->optional_keywords, memo, self_allowed)); parser_advance_if(parser, pCOMMA); goto PARSE_KEYWORDS; } rbs_types_function_param_t *param = NULL; - CHECK_PARSE(parse_function_param(parser, ¶m)); + CHECK_PARSE(parse_function_param(parser, ¶m, self_allowed)); rbs_node_list_append(params->optional_positionals, (rbs_node_t *) param); break; @@ -564,7 +564,7 @@ static bool parse_params(rbs_parser_t *parser, method_params *params) { if (parser->next_token.type == pSTAR) { rbs_parser_advance(parser); rbs_types_function_param_t *param = NULL; - CHECK_PARSE(parse_function_param(parser, ¶m)); + CHECK_PARSE(parse_function_param(parser, ¶m, self_allowed)); params->rest_positionals = (rbs_node_t *) param; if (!parser_advance_if(parser, pCOMMA)) { @@ -591,7 +591,7 @@ static bool parse_params(rbs_parser_t *parser, method_params *params) { } rbs_types_function_param_t *param = NULL; - CHECK_PARSE(parse_function_param(parser, ¶m)); + CHECK_PARSE(parse_function_param(parser, ¶m, self_allowed)); rbs_node_list_append(params->trailing_positionals, (rbs_node_t *) param); break; @@ -608,7 +608,7 @@ static bool parse_params(rbs_parser_t *parser, method_params *params) { case pQUESTION: rbs_parser_advance(parser); if (is_keyword(parser)) { - CHECK_PARSE(parse_keyword(parser, params->optional_keywords, memo)); + CHECK_PARSE(parse_keyword(parser, params->optional_keywords, memo, self_allowed)); } else { rbs_parser_set_error(parser, parser->next_token, true, "optional keyword argument type is expected"); return false; @@ -618,7 +618,7 @@ static bool parse_params(rbs_parser_t *parser, method_params *params) { case pSTAR2: rbs_parser_advance(parser); rbs_types_function_param_t *param = NULL; - CHECK_PARSE(parse_function_param(parser, ¶m)); + CHECK_PARSE(parse_function_param(parser, ¶m, self_allowed)); params->rest_keywords = (rbs_node_t *) param; break; @@ -630,7 +630,7 @@ static bool parse_params(rbs_parser_t *parser, method_params *params) { case tBANGIDENT: KEYWORD_CASES if (is_keyword(parser)) { - CHECK_PARSE(parse_keyword(parser, params->required_keywords, memo)); + CHECK_PARSE(parse_keyword(parser, params->required_keywords, memo, self_allowed)); } else { rbs_parser_set_error(parser, parser->next_token, true, "required keyword argument type is expected"); return false; @@ -660,12 +660,12 @@ static bool parse_params(rbs_parser_t *parser, method_params *params) { | {} simple_type <`?`> */ NODISCARD -static bool parse_optional(rbs_parser_t *parser, rbs_node_t **optional, bool void_allowed) { +static bool parse_optional(rbs_parser_t *parser, rbs_node_t **optional, bool void_allowed, bool self_allowed) { rbs_range_t rg; rg.start = parser->next_token.range.start; rbs_node_t *type = NULL; - CHECK_PARSE(parse_simple(parser, &type, void_allowed)); + CHECK_PARSE(parse_simple(parser, &type, void_allowed, self_allowed)); if (parser->next_token.type == pQUESTION) { if (void_allowed && type->type == RBS_TYPES_BASES_VOID) { @@ -701,13 +701,13 @@ static void initialize_method_params(method_params *params, rbs_allocator_t *all | {} `[` `self` `:` type <`]`> */ NODISCARD -static bool parse_self_type_binding(rbs_parser_t *parser, rbs_node_t **self_type) { +static bool parse_self_type_binding(rbs_parser_t *parser, rbs_node_t **self_type, bool self_allowed) { if (parser->next_token.type == pLBRACKET) { rbs_parser_advance(parser); ADVANCE_ASSERT(parser, kSELF); ADVANCE_ASSERT(parser, pCOLON); rbs_node_t *type; - CHECK_PARSE(rbs_parse_type(parser, &type, false)); + CHECK_PARSE(rbs_parse_type(parser, &type, false, self_allowed)); ADVANCE_ASSERT(parser, pRBRACKET); *self_type = type; } @@ -729,7 +729,7 @@ typedef struct { | {} self_type_binding? `->` */ NODISCARD -static bool parse_function(rbs_parser_t *parser, bool accept_type_binding, parse_function_result **result) { +static bool parse_function(rbs_parser_t *parser, bool accept_type_binding, parse_function_result **result, bool self_allowed) { rbs_node_t *function = NULL; rbs_types_block_t *block = NULL; rbs_node_t *function_self_type = NULL; @@ -741,13 +741,13 @@ static bool parse_function(rbs_parser_t *parser, bool accept_type_binding, parse if (parser->next_token.type == pLPAREN) { rbs_parser_advance(parser); - CHECK_PARSE(parse_params(parser, ¶ms)); + CHECK_PARSE(parse_params(parser, ¶ms, self_allowed)); ADVANCE_ASSERT(parser, pRPAREN); } // Passing NULL to function_self_type means the function itself doesn't accept self type binding. (== method type) if (accept_type_binding) { - CHECK_PARSE(parse_self_type_binding(parser, &function_self_type)); + CHECK_PARSE(parse_self_type_binding(parser, &function_self_type, self_allowed)); } else { if (rbs_is_untyped_params(¶ms)) { if (parser->next_token.type != pARROW) { @@ -777,16 +777,16 @@ static bool parse_function(rbs_parser_t *parser, bool accept_type_binding, parse if (parser->next_token.type == pLPAREN) { rbs_parser_advance(parser); - CHECK_PARSE(parse_params(parser, &block_params)); + CHECK_PARSE(parse_params(parser, &block_params, self_allowed)); ADVANCE_ASSERT(parser, pRPAREN); } rbs_node_t *self_type = NULL; - CHECK_PARSE(parse_self_type_binding(parser, &self_type)); + CHECK_PARSE(parse_self_type_binding(parser, &self_type, self_allowed)); ADVANCE_ASSERT(parser, pARROW); rbs_node_t *block_return_type = NULL; - CHECK_PARSE(parse_optional(parser, &block_return_type, true)); + CHECK_PARSE(parse_optional(parser, &block_return_type, true, self_allowed)); ADVANCE_ASSERT(parser, pRBRACE); @@ -816,7 +816,7 @@ static bool parse_function(rbs_parser_t *parser, bool accept_type_binding, parse ADVANCE_ASSERT(parser, pARROW); rbs_node_t *type = NULL; - CHECK_PARSE(parse_optional(parser, &type, true)); + CHECK_PARSE(parse_optional(parser, &type, true, self_allowed)); function_range.end = parser->current_token.range.end; rbs_location_t *loc = rbs_location_new(ALLOCATOR(), function_range); @@ -847,10 +847,10 @@ static bool parse_function(rbs_parser_t *parser, bool accept_type_binding, parse proc_type ::= {`^`} */ NODISCARD -static bool parse_proc_type(rbs_parser_t *parser, rbs_types_proc_t **proc) { +static bool parse_proc_type(rbs_parser_t *parser, rbs_types_proc_t **proc, bool self_allowed) { rbs_position_t start = parser->current_token.range.start; parse_function_result *result = rbs_allocator_alloc(ALLOCATOR(), parse_function_result); - CHECK_PARSE(parse_function(parser, true, &result)); + CHECK_PARSE(parse_function(parser, true, &result, self_allowed)); rbs_position_t end = parser->current_token.range.end; rbs_location_t *loc = rbs_location_new(ALLOCATOR(), (rbs_range_t) { .start = start, .end = end }); @@ -875,7 +875,7 @@ static void check_key_duplication(rbs_parser_t *parser, rbs_hash_t *fields, rbs_ | {} literal_type `=>` */ NODISCARD -static bool parse_record_attributes(rbs_parser_t *parser, rbs_hash_t **fields) { +static bool parse_record_attributes(rbs_parser_t *parser, rbs_hash_t **fields, bool self_allowed) { *fields = rbs_hash_new(ALLOCATOR()); if (parser->next_token.type == pRBRACE) return true; @@ -908,7 +908,7 @@ static bool parse_record_attributes(rbs_parser_t *parser, rbs_hash_t **fields) { case kTRUE: case kFALSE: { rbs_node_t *type = NULL; - CHECK_PARSE(parse_simple(parser, &type, false)); + CHECK_PARSE(parse_simple(parser, &type, false, self_allowed)); key = (rbs_ast_symbol_t *) ((rbs_types_literal_t *) type)->literal; break; @@ -925,7 +925,7 @@ static bool parse_record_attributes(rbs_parser_t *parser, rbs_hash_t **fields) { field_range.start = parser->current_token.range.end; rbs_node_t *type; - CHECK_PARSE(rbs_parse_type(parser, &type, false)); + CHECK_PARSE(rbs_parse_type(parser, &type, false, self_allowed)); field_range.end = parser->current_token.range.end; rbs_location_t *loc = rbs_location_new(ALLOCATOR(), field_range); @@ -1032,7 +1032,7 @@ static bool parse_instance_type(rbs_parser_t *parser, bool parse_alias, rbs_node if (parser->next_token.type == pLBRACKET) { rbs_parser_advance(parser); args_range.start = parser->current_token.range.start; - CHECK_PARSE(parse_type_list(parser, pRBRACKET, types, true)); + CHECK_PARSE(parse_type_list(parser, pRBRACKET, types, true, true)); ADVANCE_ASSERT(parser, pRBRACKET); args_range.end = parser->current_token.range.end; } else { @@ -1119,13 +1119,13 @@ static bool parser_typevar_member(rbs_parser_t *parser, rbs_constant_id_t id) { | {} `^` */ NODISCARD -static bool parse_simple(rbs_parser_t *parser, rbs_node_t **type, bool void_allowed) { +static bool parse_simple(rbs_parser_t *parser, rbs_node_t **type, bool void_allowed, bool self_allowed) { rbs_parser_advance(parser); switch (parser->current_token.type) { case pLPAREN: { rbs_node_t *lparen_type; - CHECK_PARSE(rbs_parse_type(parser, &lparen_type, false)); + CHECK_PARSE(rbs_parse_type(parser, &lparen_type, false, self_allowed)); ADVANCE_ASSERT(parser, pRPAREN); *type = lparen_type; return true; @@ -1156,6 +1156,11 @@ static bool parse_simple(rbs_parser_t *parser, rbs_node_t **type, bool void_allo return true; } case kSELF: { + if (!self_allowed) { + rbs_parser_set_error(parser, parser->current_token, true, "self type is not allowed here"); + return false; + } + rbs_location_t *loc = rbs_location_current_token(parser); *type = (rbs_node_t *) rbs_types_bases_self_new(ALLOCATOR(), loc); return true; @@ -1259,7 +1264,7 @@ static bool parse_simple(rbs_parser_t *parser, rbs_node_t **type, bool void_allo rg.start = parser->current_token.range.start; rbs_node_list_t *types = rbs_node_list_new(ALLOCATOR()); if (parser->next_token.type != pRBRACKET) { - CHECK_PARSE(parse_type_list(parser, pRBRACKET, types, false)); + CHECK_PARSE(parse_type_list(parser, pRBRACKET, types, false, self_allowed)); } ADVANCE_ASSERT(parser, pRBRACKET); rg.end = parser->current_token.range.end; @@ -1277,7 +1282,7 @@ static bool parse_simple(rbs_parser_t *parser, rbs_node_t **type, bool void_allo case pLBRACE: { rbs_position_t start = parser->current_token.range.start; rbs_hash_t *fields = NULL; - CHECK_PARSE(parse_record_attributes(parser, &fields)); + CHECK_PARSE(parse_record_attributes(parser, &fields, self_allowed)); ADVANCE_ASSERT(parser, pRBRACE); rbs_position_t end = parser->current_token.range.end; rbs_location_t *loc = rbs_location_new(ALLOCATOR(), (rbs_range_t) { .start = start, .end = end }); @@ -1286,7 +1291,7 @@ static bool parse_simple(rbs_parser_t *parser, rbs_node_t **type, bool void_allo } case pHAT: { rbs_types_proc_t *value = NULL; - CHECK_PARSE(parse_proc_type(parser, &value)); + CHECK_PARSE(parse_proc_type(parser, &value, self_allowed)); *type = (rbs_node_t *) value; return true; } @@ -1301,12 +1306,12 @@ static bool parse_simple(rbs_parser_t *parser, rbs_node_t **type, bool void_allo | {} */ NODISCARD -static bool parse_intersection(rbs_parser_t *parser, rbs_node_t **type, bool void_allowed) { +static bool parse_intersection(rbs_parser_t *parser, rbs_node_t **type, bool void_allowed, bool self_allowed) { rbs_range_t rg; rg.start = parser->next_token.range.start; rbs_node_t *optional = NULL; - CHECK_PARSE(parse_optional(parser, &optional, void_allowed)); + CHECK_PARSE(parse_optional(parser, &optional, void_allowed, self_allowed)); *type = optional; rbs_node_list_t *intersection_types = rbs_node_list_new(ALLOCATOR()); @@ -1320,7 +1325,7 @@ static bool parse_intersection(rbs_parser_t *parser, rbs_node_t **type, bool voi rbs_parser_advance(parser); rbs_node_t *type = NULL; - CHECK_PARSE(parse_optional(parser, &type, false)); + CHECK_PARSE(parse_optional(parser, &type, false, self_allowed)); rbs_node_list_append(intersection_types, type); } @@ -1338,12 +1343,12 @@ static bool parse_intersection(rbs_parser_t *parser, rbs_node_t **type, bool voi union ::= {} intersection '|' ... '|' | {} */ -bool rbs_parse_type(rbs_parser_t *parser, rbs_node_t **type, bool void_allowed) { +bool rbs_parse_type(rbs_parser_t *parser, rbs_node_t **type, bool void_allowed, bool self_allowed) { rbs_range_t rg; rg.start = parser->next_token.range.start; rbs_node_list_t *union_types = rbs_node_list_new(ALLOCATOR()); - CHECK_PARSE(parse_intersection(parser, type, void_allowed)); + CHECK_PARSE(parse_intersection(parser, type, void_allowed, self_allowed)); rbs_node_list_append(union_types, *type); @@ -1355,7 +1360,7 @@ bool rbs_parse_type(rbs_parser_t *parser, rbs_node_t **type, bool void_allowed) rbs_parser_advance(parser); rbs_node_t *intersection = NULL; - CHECK_PARSE(parse_intersection(parser, &intersection, false)); + CHECK_PARSE(parse_intersection(parser, &intersection, false, self_allowed)); rbs_node_list_append(union_types, intersection); } @@ -1448,7 +1453,7 @@ static bool parse_type_params(rbs_parser_t *parser, rbs_range_t *rg, bool module rbs_parser_advance(parser); upper_bound_range.start = parser->current_token.range.start; - CHECK_PARSE(rbs_parse_type(parser, &upper_bound, false)); + CHECK_PARSE(rbs_parse_type(parser, &upper_bound, false, false)); upper_bound_range.end = parser->current_token.range.end; break; @@ -1460,7 +1465,7 @@ static bool parse_type_params(rbs_parser_t *parser, rbs_range_t *rg, bool module rbs_parser_advance(parser); lower_bound_range.start = parser->current_token.range.start; - CHECK_PARSE(rbs_parse_type(parser, &lower_bound, false)); + CHECK_PARSE(rbs_parse_type(parser, &lower_bound, false, false)); lower_bound_range.end = parser->current_token.range.end; break; @@ -1475,7 +1480,7 @@ static bool parse_type_params(rbs_parser_t *parser, rbs_range_t *rg, bool module rbs_parser_advance(parser); default_type_range.start = parser->current_token.range.start; - CHECK_PARSE(rbs_parse_type(parser, &default_type, true)); + CHECK_PARSE(rbs_parse_type(parser, &default_type, true, false)); default_type_range.end = parser->current_token.range.end; required_param_allowed = false; @@ -1559,7 +1564,7 @@ bool rbs_parse_method_type(rbs_parser_t *parser, rbs_method_type_t **method_type type_range.start = parser->next_token.range.start; parse_function_result *result = rbs_allocator_alloc(ALLOCATOR(), parse_function_result); - CHECK_PARSE(parse_function(parser, false, &result)); + CHECK_PARSE(parse_function(parser, false, &result, true)); rg.end = parser->current_token.range.end; type_range.end = rg.end; @@ -1594,7 +1599,7 @@ static bool parse_global_decl(rbs_parser_t *parser, rbs_node_list_t *annotations rbs_range_t colon_range = parser->current_token.range; rbs_node_t *type; - CHECK_PARSE(rbs_parse_type(parser, &type, false)); + CHECK_PARSE(rbs_parse_type(parser, &type, false, false)); decl_range.end = parser->current_token.range.end; rbs_location_t *loc = rbs_location_new(ALLOCATOR(), decl_range); @@ -1624,7 +1629,7 @@ static bool parse_const_decl(rbs_parser_t *parser, rbs_node_list_t *annotations, rbs_range_t colon_range = parser->current_token.range; rbs_node_t *type; - CHECK_PARSE(rbs_parse_type(parser, &type, false)); + CHECK_PARSE(rbs_parse_type(parser, &type, false, false)); decl_range.end = parser->current_token.range.end; @@ -1664,7 +1669,7 @@ static bool parse_type_decl(rbs_parser_t *parser, rbs_position_t comment_pos, rb rbs_range_t eq_range = parser->current_token.range; rbs_node_t *type; - CHECK_PARSE(rbs_parse_type(parser, &type, false)); + CHECK_PARSE(rbs_parse_type(parser, &type, false, false)); decl_range.end = parser->current_token.range.end; @@ -2058,7 +2063,7 @@ static bool class_instance_name(rbs_parser_t *parser, TypeNameKind kind, rbs_nod if (parser->next_token.type == pLBRACKET) { rbs_parser_advance(parser); args_range->start = parser->current_token.range.start; - CHECK_PARSE(parse_type_list(parser, pRBRACKET, args, true)); + CHECK_PARSE(parse_type_list(parser, pRBRACKET, args, true, false)); ADVANCE_ASSERT(parser, pRBRACKET); args_range->end = parser->current_token.range.end; } else { @@ -2233,7 +2238,7 @@ static bool parse_variable_member(rbs_parser_t *parser, rbs_position_t comment_p rbs_range_t colon_range = parser->current_token.range; rbs_node_t *type; - CHECK_PARSE(rbs_parse_type(parser, &type, false)); + CHECK_PARSE(rbs_parse_type(parser, &type, false, true)); member_range.end = parser->current_token.range.end; rbs_location_t *loc = rbs_location_new(ALLOCATOR(), member_range); @@ -2256,7 +2261,7 @@ static bool parse_variable_member(rbs_parser_t *parser, rbs_position_t comment_p rbs_parser_push_typevar_table(parser, true); rbs_node_t *type; - CHECK_PARSE(rbs_parse_type(parser, &type, false)); + CHECK_PARSE(rbs_parse_type(parser, &type, false, false)); CHECK_PARSE(parser_pop_typevar_table(parser)); @@ -2295,7 +2300,7 @@ static bool parse_variable_member(rbs_parser_t *parser, rbs_position_t comment_p rbs_parser_push_typevar_table(parser, true); rbs_node_t *type; - CHECK_PARSE(rbs_parse_type(parser, &type, false)); + CHECK_PARSE(rbs_parse_type(parser, &type, false, true)); CHECK_PARSE(parser_pop_typevar_table(parser)); @@ -2436,7 +2441,7 @@ static bool parse_attribute_member(rbs_parser_t *parser, rbs_position_t comment_ rbs_parser_push_typevar_table(parser, is_kind == SINGLETON_KIND); rbs_node_t *type; - CHECK_PARSE(rbs_parse_type(parser, &type, false)); + CHECK_PARSE(rbs_parse_type(parser, &type, false, true)); CHECK_PARSE(parser_pop_typevar_table(parser)); @@ -2589,7 +2594,7 @@ static bool parse_module_self_types(rbs_parser_t *parser, rbs_node_list_t *array if (parser->next_token.type == pLBRACKET) { rbs_parser_advance(parser); args_range.start = parser->current_token.range.start; - CHECK_PARSE(parse_type_list(parser, pRBRACKET, args, true)); + CHECK_PARSE(parse_type_list(parser, pRBRACKET, args, true, false)); rbs_parser_advance(parser); self_range.end = args_range.end = parser->current_token.range.end; } @@ -3738,7 +3743,7 @@ static bool parse_inline_leading_annotation(rbs_parser_t *parser, rbs_ast_ruby_a rbs_location_t *colon_loc = rbs_location_new(ALLOCATOR(), colon_range); rbs_node_t *return_type = NULL; - if (!rbs_parse_type(parser, &return_type, true)) { + if (!rbs_parse_type(parser, &return_type, true, true)) { return false; } @@ -3784,7 +3789,7 @@ static bool parse_inline_leading_annotation(rbs_parser_t *parser, rbs_ast_ruby_a rbs_location_t *colon_loc = rbs_location_new(ALLOCATOR(), colon_range); rbs_node_t *type = NULL; - if (!rbs_parse_type(parser, &type, false)) { + if (!rbs_parse_type(parser, &type, false, false)) { return false; } @@ -3835,7 +3840,7 @@ static bool parse_inline_trailing_annotation(rbs_parser_t *parser, rbs_ast_ruby_ rbs_parser_advance(parser); rbs_node_t *type = NULL; - if (!rbs_parse_type(parser, &type, true)) { + if (!rbs_parse_type(parser, &type, true, true)) { return false; } @@ -3868,7 +3873,7 @@ static bool parse_inline_trailing_annotation(rbs_parser_t *parser, rbs_ast_ruby_ } // Parse type list with comma tracking - CHECK_PARSE(parse_type_list_with_commas(parser, pRBRACKET, type_args, comma_locations, true)); + CHECK_PARSE(parse_type_list_with_commas(parser, pRBRACKET, type_args, comma_locations, true, true)); rbs_range_t close_bracket_range = parser->next_token.range; rbs_location_t *close_bracket_loc = rbs_location_new(ALLOCATOR(), close_bracket_range); diff --git a/test/rbs/cli_test.rb b/test/rbs/cli_test.rb index 151e9cfe4c..36f25fec5d 100644 --- a/test/rbs/cli_test.rb +++ b/test/rbs/cli_test.rb @@ -594,34 +594,6 @@ module X7 : A[String, untyped] end end - def test_validate__generics_default_self - with_cli do |cli| - Dir.mktmpdir do |dir| - (Pathname(dir) + 'a.rbs').write(<<~RBS) - module A[T = self] - end - - class B[S = self] - end - - interface _C[T = self] - end - - type t[T = self] = untyped - RBS - - assert_cli_success do - cli.run(["-I", dir, "validate"]) - end - - assert_include stdout.string, "/a.rbs:1:13...1:17: `self` type is not allowed in this context (RBS::WillSyntaxError)\n" - assert_include stdout.string, "/a.rbs:4:12...4:16: `self` type is not allowed in this context (RBS::WillSyntaxError)\n" - assert_include stdout.string, "/a.rbs:7:17...7:21: `self` type is not allowed in this context (RBS::WillSyntaxError)\n" - assert_include stdout.string, "/a.rbs:10:11...10:15: `self` type is not allowed in this context (RBS::WillSyntaxError)\n" - end - end - end - def test_validate__generics_default_ref with_cli do |cli| Dir.mktmpdir do |dir| @@ -655,17 +627,20 @@ def test_validate_multiple Dir.mktmpdir do |dir| (Pathname(dir) + 'a.rbs').write(<<~RBS) class Foo - type foo = self - type bar = instance + def foo: () -> Nothing + end + + class Bar + def bar: () -> Nothing end RBS - assert_cli_success do + refute_cli_success do cli.run(["-I", dir, "--log-level=warn", "validate"]) end - assert_include stdout.string, "a.rbs:2:13...2:17: `self` type is not allowed in this context (RBS::WillSyntaxError)" - assert_include stdout.string, "a.rbs:3:13...3:21: `instance` or `class` type is not allowed in this context (RBS::WillSyntaxError)" + assert_include stdout.string, "a.rbs:2:17...2:24: Could not find Nothing (RBS::NoTypeFoundError)" + assert_include stdout.string, "a.rbs:6:17...6:24: Could not find Nothing (RBS::NoTypeFoundError)" end end end @@ -675,16 +650,17 @@ def test_validate_multiple_with_fail_fast Dir.mktmpdir do |dir| (Pathname(dir) + 'a.rbs').write(<<~RBS) class Foo - type foo = self - type bar = instance + def foo: () -> Nothing + end + class Bar + def bar: () -> Nothing end RBS - assert_cli_success do + refute_cli_success do cli.run(["-I", dir, "--log-level=warn", "validate", "--fail-fast"]) end - assert_include stdout.string, "a.rbs:2:13...2:17: `self` type is not allowed in this context (RBS::WillSyntaxError)" - assert_include stdout.string, "a.rbs:3:13...3:21: `instance` or `class` type is not allowed in this context (RBS::WillSyntaxError)" + assert_include stdout.string, "a.rbs:2:17...2:24: Could not find Nothing (RBS::NoTypeFoundError)" end end end @@ -694,7 +670,6 @@ def test_validate_multiple_with_exit_error_on_syntax_error Dir.mktmpdir do |dir| (Pathname(dir) + 'a.rbs').write(<<~RBS) class Foo - type foo = self type bar = instance end RBS @@ -702,8 +677,7 @@ class Foo refute_cli_success do cli.run(["-I", dir, "--log-level=warn", "validate", "--exit-error-on-syntax-error"]) end - assert_include stdout.string, "a.rbs:2:13...2:17: `self` type is not allowed in this context (RBS::WillSyntaxError)" - assert_include stdout.string, "a.rbs:3:13...3:21: `instance` or `class` type is not allowed in this context (RBS::WillSyntaxError)" + assert_include stdout.string, "a.rbs:2:13...2:21: `instance` or `class` type is not allowed in this context (RBS::WillSyntaxError)" end end end @@ -786,26 +760,12 @@ class Foo < Bar[instance] module Bar : _Each[instance] end RBS - <<~RBS, - module Foo[A < _Each[self]] - end - RBS - <<~RBS, - class Foo - @@bar: self - end - RBS <<~RBS, type foo = instance RBS <<~RBS, BAR: instance RBS - <<~RBS, - class Foo - include Enumerable[self] - end - RBS <<~RBS, $FOO: instance RBS diff --git a/test/rbs/inline_annotation_parsing_test.rb b/test/rbs/inline_annotation_parsing_test.rb index 25f7286dfa..1e2a7055e0 100644 --- a/test/rbs/inline_annotation_parsing_test.rb +++ b/test/rbs/inline_annotation_parsing_test.rb @@ -97,21 +97,21 @@ def test_parse__skip end def test_parse__return - Parser.parse_inline_leading_annotation("@rbs return: untyped", 0...).tap do |annot| + Parser.parse_inline_leading_annotation("@rbs return: void", 0...).tap do |annot| assert_instance_of AST::Ruby::Annotations::ReturnTypeAnnotation, annot - assert_equal "@rbs return: untyped", annot.location.source + assert_equal "@rbs return: void", annot.location.source assert_equal "return", annot.return_location.source assert_equal ":", annot.colon_location.source - assert_equal "untyped", annot.return_type.location.source + assert_equal "void", annot.return_type.location.source assert_nil annot.comment_location end - Parser.parse_inline_leading_annotation("@rbs return: untyped -- some comment here", 0...).tap do |annot| + Parser.parse_inline_leading_annotation("@rbs return: self -- some comment here", 0...).tap do |annot| assert_instance_of AST::Ruby::Annotations::ReturnTypeAnnotation, annot - assert_equal "@rbs return: untyped -- some comment here", annot.location.source + assert_equal "@rbs return: self -- some comment here", annot.location.source assert_equal "return", annot.return_location.source assert_equal ":", annot.colon_location.source - assert_equal "untyped", annot.return_type.location.source + assert_equal "self", annot.return_type.location.source assert_equal "-- some comment here", annot.comment_location.source end end @@ -204,5 +204,13 @@ def test_error__instance_variable assert_raises RBS::ParsingError do Parser.parse_inline_leading_annotation("@rbs name: String", 0...) end + + assert_raises RBS::ParsingError do + Parser.parse_inline_leading_annotation("@rbs @name: void", 0...) + end + + assert_raises RBS::ParsingError do + Parser.parse_inline_leading_annotation("@rbs @name: self", 0...) + end end end diff --git a/test/rbs/rb_prototype_test.rb b/test/rbs/rb_prototype_test.rb index 804b0d48c3..2722347ece 100644 --- a/test/rbs/rb_prototype_test.rb +++ b/test/rbs/rb_prototype_test.rb @@ -763,7 +763,7 @@ def test_literal_types H: { id: 123 } -I: self +I: untyped EOF end diff --git a/test/rbs/signature_parsing_test.rb b/test/rbs/signature_parsing_test.rb index 206cdc5e88..bd8ad4654a 100644 --- a/test/rbs/signature_parsing_test.rb +++ b/test/rbs/signature_parsing_test.rb @@ -2531,6 +2531,12 @@ def test_context_syntax_error_super_class end assert_equal [1, 19], ex.location.start_loc assert_equal [1, 23], ex.location.end_loc + + ex = assert_raises RBS::ParsingError do + Parser.parse_signature("class Foo < Array[self] end") + end + assert_equal [1, 18], ex.location.start_loc + assert_equal [1, 22], ex.location.end_loc end def test_context_syntax_error_module_self_type @@ -2543,6 +2549,12 @@ def test_context_syntax_error_module_self_type end assert_equal [1, 20], ex.location.start_loc assert_equal [1, 24], ex.location.end_loc + + ex = assert_raises RBS::ParsingError do + Parser.parse_signature("module Foo : Array[self] end") + end + assert_equal [1, 19], ex.location.start_loc + assert_equal [1, 23], ex.location.end_loc end def test_context_syntax_error_global @@ -2551,6 +2563,12 @@ def test_context_syntax_error_global end assert_equal [1, 7], ex.location.start_loc assert_equal [1, 11], ex.location.end_loc + + ex = assert_raises RBS::ParsingError do + Parser.parse_signature("$glob: self") + end + assert_equal [1, 7], ex.location.start_loc + assert_equal [1, 11], ex.location.end_loc end def test_context_syntax_error_constant @@ -2559,6 +2577,12 @@ def test_context_syntax_error_constant end assert_equal [1, 7], ex.location.start_loc assert_equal [1, 11], ex.location.end_loc + + ex = assert_raises RBS::ParsingError do + Parser.parse_signature("CONST: self") + end + assert_equal [1, 7], ex.location.start_loc + assert_equal [1, 11], ex.location.end_loc end def test_context_syntax_error_type_alias @@ -2567,6 +2591,12 @@ def test_context_syntax_error_type_alias end assert_equal [1, 9], ex.location.start_loc assert_equal [1, 13], ex.location.end_loc + + ex = assert_raises RBS::ParsingError do + Parser.parse_signature("type a = self") + end + assert_equal [1, 9], ex.location.start_loc + assert_equal [1, 13], ex.location.end_loc end def test_context_syntax_error_mixin @@ -2585,6 +2615,12 @@ class C end assert_equal [1, 19], ex.location.start_loc assert_equal [1, 23], ex.location.end_loc + + ex = assert_raises RBS::ParsingError do + Parser.parse_signature("class C include M[self] end") + end + assert_equal [1, 18], ex.location.start_loc + assert_equal [1, 22], ex.location.end_loc end def test_context_syntax_error_variable @@ -2620,6 +2656,12 @@ class Foo end assert_equal [1, 17], ex.location.start_loc assert_equal [1, 21], ex.location.end_loc + + ex = assert_raises RBS::ParsingError do + Parser.parse_signature("class Foo @@foo: self end") + end + assert_equal [1, 17], ex.location.start_loc + assert_equal [1, 21], ex.location.end_loc end def test_context_syntax_error_upper_bound @@ -2641,23 +2683,47 @@ module M[T < Array[void]] assert_equal [1, 12], ex.location.start_loc assert_equal [1, 16], ex.location.end_loc + ex = assert_raises RBS::ParsingError do + Parser.parse_signature("class C[T < self] end") + end + assert_equal [1, 12], ex.location.start_loc + assert_equal [1, 16], ex.location.end_loc + ex = assert_raises RBS::ParsingError do Parser.parse_signature("module M[T < void] end") end assert_equal [1, 13], ex.location.start_loc assert_equal [1, 17], ex.location.end_loc + ex = assert_raises RBS::ParsingError do + Parser.parse_signature("module M[T < self] end") + end + assert_equal [1, 13], ex.location.start_loc + assert_equal [1, 17], ex.location.end_loc + ex = assert_raises RBS::ParsingError do Parser.parse_signature("interface _I[T < void] end") end assert_equal [1, 17], ex.location.start_loc assert_equal [1, 21], ex.location.end_loc + ex = assert_raises RBS::ParsingError do + Parser.parse_signature("interface _I[T < self] end") + end + assert_equal [1, 17], ex.location.start_loc + assert_equal [1, 21], ex.location.end_loc + ex = assert_raises RBS::ParsingError do Parser.parse_signature("type a[T < void] = 1") end assert_equal [1, 11], ex.location.start_loc assert_equal [1, 15], ex.location.end_loc + + ex = assert_raises RBS::ParsingError do + Parser.parse_signature("type a[T < self] = 1") + end + assert_equal [1, 11], ex.location.start_loc + assert_equal [1, 15], ex.location.end_loc end def test_context_syntax_error_lower_bound @@ -2679,23 +2745,47 @@ module M[T > Array[void]] assert_equal [1, 12], ex.location.start_loc assert_equal [1, 16], ex.location.end_loc + ex = assert_raises RBS::ParsingError do + Parser.parse_signature("class C[T > self] end") + end + assert_equal [1, 12], ex.location.start_loc + assert_equal [1, 16], ex.location.end_loc + ex = assert_raises RBS::ParsingError do Parser.parse_signature("module M[T > void] end") end assert_equal [1, 13], ex.location.start_loc assert_equal [1, 17], ex.location.end_loc + ex = assert_raises RBS::ParsingError do + Parser.parse_signature("module M[T > self] end") + end + assert_equal [1, 13], ex.location.start_loc + assert_equal [1, 17], ex.location.end_loc + ex = assert_raises RBS::ParsingError do Parser.parse_signature("interface _I[T > void] end") end assert_equal [1, 17], ex.location.start_loc assert_equal [1, 21], ex.location.end_loc + ex = assert_raises RBS::ParsingError do + Parser.parse_signature("interface _I[T > self] end") + end + assert_equal [1, 17], ex.location.start_loc + assert_equal [1, 21], ex.location.end_loc + ex = assert_raises RBS::ParsingError do Parser.parse_signature("type a[T > void] = 1") end assert_equal [1, 11], ex.location.start_loc assert_equal [1, 15], ex.location.end_loc + + ex = assert_raises RBS::ParsingError do + Parser.parse_signature("type a[T > self] = 1") + end + assert_equal [1, 11], ex.location.start_loc + assert_equal [1, 15], ex.location.end_loc end def test_context_syntax_error_upper_and_lower_bound @@ -2762,22 +2852,46 @@ module MA[T = Array[void]] assert_equal [1, 13], ex.location.start_loc assert_equal [1, 17], ex.location.end_loc + ex = assert_raises RBS::ParsingError do + Parser.parse_signature("class C[T = self] end") + end + assert_equal [1, 12], ex.location.start_loc + assert_equal [1, 16], ex.location.end_loc + ex = assert_raises RBS::ParsingError do Parser.parse_signature("module M[T = [void]] end") end assert_equal [1, 14], ex.location.start_loc assert_equal [1, 18], ex.location.end_loc + ex = assert_raises RBS::ParsingError do + Parser.parse_signature("module M[T = self] end") + end + assert_equal [1, 13], ex.location.start_loc + assert_equal [1, 17], ex.location.end_loc + ex = assert_raises RBS::ParsingError do Parser.parse_signature("interface _I[T = [void]] end") end assert_equal [1, 18], ex.location.start_loc assert_equal [1, 22], ex.location.end_loc + ex = assert_raises RBS::ParsingError do + Parser.parse_signature("interface _I[T = self] end") + end + assert_equal [1, 17], ex.location.start_loc + assert_equal [1, 21], ex.location.end_loc + ex = assert_raises RBS::ParsingError do Parser.parse_signature("type a[T = [void]] = 1") end assert_equal [1, 12], ex.location.start_loc assert_equal [1, 16], ex.location.end_loc + + ex = assert_raises RBS::ParsingError do + Parser.parse_signature("type a[T = self] = 1") + end + assert_equal [1, 11], ex.location.start_loc + assert_equal [1, 15], ex.location.end_loc end end