diff --git a/Rakefile b/Rakefile index 2a9541de8..0f45dcb98 100644 --- a/Rakefile +++ b/Rakefile @@ -187,7 +187,7 @@ end task :validate => :compile do require 'yaml' - sh "#{ruby} #{rbs} validate --exit-error-on-syntax-error" + sh "#{ruby} #{rbs} validate" libs = FileList["stdlib/*"].map {|path| File.basename(path).to_s } @@ -208,7 +208,7 @@ task :validate => :compile do end libs.each do |lib| - sh "#{ruby} #{rbs} -r #{lib} validate --exit-error-on-syntax-error" + sh "#{ruby} #{rbs} -r #{lib} validate" end end diff --git a/ext/rbs_extension/main.c b/ext/rbs_extension/main.c index 766a6cc06..9b296433d 100644 --- a/ext/rbs_extension/main.c +++ b/ext/rbs_extension/main.c @@ -87,6 +87,7 @@ struct parse_type_arg { VALUE require_eof; VALUE void_allowed; VALUE self_allowed; + VALUE classish_allowed; }; struct parse_method_type_arg { @@ -118,9 +119,10 @@ static VALUE parse_type_try(VALUE a) { bool void_allowed = RTEST(arg->void_allowed); bool self_allowed = RTEST(arg->self_allowed); + bool classish_allowed = RTEST(arg->classish_allowed); rbs_node_t *type; - rbs_parse_type(parser, &type, void_allowed, self_allowed); + rbs_parse_type(parser, &type, void_allowed, self_allowed, classish_allowed); raise_error_if_any(parser, arg->buffer); @@ -176,7 +178,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, VALUE self_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 classish_allowed) { VALUE string = rb_funcall(buffer, rb_intern("content"), 0); StringValue(string); rb_encoding *encoding = rb_enc_get(string); @@ -189,7 +191,8 @@ static VALUE rbsparser_parse_type(VALUE self, VALUE buffer, VALUE start_pos, VAL .parser = parser, .require_eof = require_eof, .void_allowed = void_allowed, - .self_allowed = self_allowed + .self_allowed = self_allowed, + .classish_allowed = classish_allowed }; VALUE result = rb_ensure(parse_type_try, (VALUE) &arg, ensure_free_parser, (VALUE) parser); @@ -208,7 +211,7 @@ static VALUE parse_method_type_try(VALUE a) { } rbs_method_type_t *method_type = NULL; - rbs_parse_method_type(parser, &method_type); + rbs_parse_method_type(parser, &method_type, true); raise_error_if_any(parser, arg->buffer); @@ -453,7 +456,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, 7); + rb_define_singleton_method(RBS_Parser, "_parse_type", rbsparser_parse_type, 8); 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 339235deb..1c46b5c06 100644 --- a/include/rbs/parser.h +++ b/include/rbs/parser.h @@ -126,8 +126,8 @@ 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 self_allowed); -bool rbs_parse_method_type(rbs_parser_t *parser, rbs_method_type_t **method_type); +bool rbs_parse_type(rbs_parser_t *parser, rbs_node_t **type, bool void_allowed, bool self_allowed, bool classish_allowed); +bool rbs_parse_method_type(rbs_parser_t *parser, rbs_method_type_t **method_type, bool classish_allowed); bool rbs_parse_signature(rbs_parser_t *parser, rbs_signature_t **signature); bool rbs_parse_type_params(rbs_parser_t *parser, bool module_type_params, rbs_node_list_t **params); diff --git a/lib/rbs/cli/validate.rb b/lib/rbs/cli/validate.rb index 42be20eee..8dc66fbda 100644 --- a/lib/rbs/cli/validate.rb +++ b/lib/rbs/cli/validate.rb @@ -4,20 +4,13 @@ module RBS class CLI class Validate class Errors - def initialize(limit:, exit_error:) + def initialize(limit:) @limit = limit - @exit_error = exit_error @errors = [] - @has_syntax_error = false end def add(error) - if error.instance_of?(WillSyntaxError) - RBS.logger.warn(build_message(error)) - @has_syntax_error = true - else - @errors << error - end + @errors << error finish if @limit == 1 end @@ -30,13 +23,7 @@ def try(&block) end def finish - if @errors.empty? - if @exit_error && @has_syntax_error - throw @tag, 1 - else - # success - end - else + unless @errors.empty? @errors.each do |error| RBS.logger.error(build_message(error)) end @@ -63,7 +50,6 @@ def initialize(args:, options:) @env = Environment.from_loader(loader).resolve_type_names @builder = DefinitionBuilder.new(env: @env) @validator = Validator.new(env: @env) - exit_error = false limit = nil #: Integer? OptionParser.new do |opts| opts.banner = < error @@ -266,7 +241,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_classish_type_validator(const.decl.type) rescue BaseError => error @errors.add(error) end @@ -276,7 +250,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_classish_type_validator(global.decl.type) rescue BaseError => error @errors.add(error) end @@ -299,51 +272,23 @@ def validate_type_alias decl.decl.type_params.each do |param| if ub = param.upper_bound_type - no_classish_type_validator(ub) @validator.validate_type(ub, context: nil) end if lb = param.lower_bound_type - no_classish_type_validator(lb) @validator.validate_type(lb, context: nil) end if dt = param.default_type - no_classish_type_validator(dt) @validator.validate_type(dt, context: nil) end end TypeParamDefaultReferenceError.check!(decl.decl.type_params) - - no_classish_type_validator(decl.decl.type) rescue BaseError => error @errors.add(error) end end - - private - - def no_self_type_validator(type) - if type.has_self_type? - @errors.add WillSyntaxError.new("`self` type is not allowed in this context", location: type.location) - end - end - - def no_classish_type_validator(type) - if type.has_classish_type? - @errors.add WillSyntaxError.new("`instance` or `class` type is not allowed in this context", location: type.location) - end - end - - def void_type_context_validator(type, allowed_here = false) - if allowed_here - return if type.is_a?(Types::Bases::Void) - end - if type.with_nonreturn_void? # steep:ignore DeprecatedReference - @errors.add WillSyntaxError.new("`void` type is only allowed in return type or generics parameter", location: type.location) - end - end end end end diff --git a/lib/rbs/errors.rb b/lib/rbs/errors.rb index e27275582..48cb1a7c8 100644 --- a/lib/rbs/errors.rb +++ b/lib/rbs/errors.rb @@ -491,7 +491,7 @@ def self.check!(type_name:, env:, member:) else raise "Unknown member type: #{member.class}" end - + if env.class_decl?(name) raise new(type_name: type_name, member: member) end @@ -611,17 +611,6 @@ def location end end - class WillSyntaxError < DefinitionError - include DetailedMessageable - - attr_reader :location - - def initialize(message, location:) - super "#{Location.to_string(location)}: #{message}" - @location = location - end - end - class TypeParamDefaultReferenceError < DefinitionError include DetailedMessageable diff --git a/lib/rbs/parser_aux.rb b/lib/rbs/parser_aux.rb index 97b74f73c..1607eb922 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, self_allowed: true) + def self.parse_type(source, range: 0..., variables: [], require_eof: false, void_allowed: true, self_allowed: true, classish_allowed: true) buf = buffer(source) - _parse_type(buf, range.begin || 0, range.end || buf.last_position, variables, require_eof, void_allowed, self_allowed) + _parse_type(buf, range.begin || 0, range.end || buf.last_position, variables, require_eof, void_allowed, self_allowed, classish_allowed) end def self.parse_method_type(source, range: 0..., variables: [], require_eof: false) diff --git a/sig/cli/validate.rbs b/sig/cli/validate.rbs index 338a609b1..e2f0b77d6 100644 --- a/sig/cli/validate.rbs +++ b/sig/cli/validate.rbs @@ -3,14 +3,12 @@ module RBS class Validate class Errors @limit: Integer? - @exit_error: boolish - @has_syntax_error: bool @errors: Array[BaseError] # The tag that will be thrown in #finish method @tag: top - def initialize: (limit: Integer?, exit_error: boolish) -> void + def initialize: (limit: Integer?) -> void def add: (BaseError) -> void @@ -44,9 +42,6 @@ module RBS def validate_constant: () -> void def validate_global: () -> void def validate_type_alias: () -> 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 end diff --git a/sig/errors.rbs b/sig/errors.rbs index cab03130d..c2c716ade 100644 --- a/sig/errors.rbs +++ b/sig/errors.rbs @@ -394,14 +394,6 @@ module RBS def location: () -> AST::Declarations::AliasDecl::loc? end - class WillSyntaxError < BaseError - include RBS::DetailedMessageable - - def initialize: (String message, location: Location[untyped, untyped]?) -> void - - attr_reader location: Location[untyped, untyped]? - end - class TypeParamDefaultReferenceError < BaseError include DetailedMessageable diff --git a/sig/parser.rbs b/sig/parser.rbs index 54f5d3ea5..028dc8df1 100644 --- a/sig/parser.rbs +++ b/sig/parser.rbs @@ -76,7 +76,7 @@ module RBS # 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? + def self.parse_type: (Buffer | String, ?range: Range[Integer?], ?variables: Array[Symbol], ?require_eof: bool, ?void_allowed: bool, ?self_allowed: bool, ?classish_allowed: bool) -> Types::t? # Parse whole RBS file and return an array of declarations # @@ -130,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, bool self_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, bool classish_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 4719448ce..116a886ec 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, bool self_allowed); -static bool parse_simple(rbs_parser_t *parser, rbs_node_t **type, bool void_allowed, bool self_allowed); +static bool parse_optional(rbs_parser_t *parser, rbs_node_t **optional, bool void_allowed, bool self_allowed, bool classish_allowed); +static bool parse_simple(rbs_parser_t *parser, rbs_node_t **type, bool void_allowed, bool self_allowed, bool classish_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, bool self_allowed) { +static bool parse_type_list(rbs_parser_t *parser, enum RBSTokenType eol, rbs_node_list_t *types, bool void_allowed, bool self_allowed, bool classish_allowed) { while (true) { rbs_node_t *type; - CHECK_PARSE(rbs_parse_type(parser, &type, void_allowed, self_allowed)); + CHECK_PARSE(rbs_parse_type(parser, &type, void_allowed, self_allowed, classish_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, bool self_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, bool classish_allowed) { while (true) { rbs_node_t *type; - CHECK_PARSE(rbs_parse_type(parser, &type, void_allowed, self_allowed)); + CHECK_PARSE(rbs_parse_type(parser, &type, void_allowed, self_allowed, classish_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, bool self_allowed) { +static bool parse_function_param(rbs_parser_t *parser, rbs_types_function_param_t **function_param, bool self_allowed, bool classish_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, self_allowed)); + CHECK_PARSE(rbs_parse_type(parser, &type, false, self_allowed, classish_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, bool self_allowed) { +static bool parse_keyword(rbs_parser_t *parser, rbs_hash_t *keywords, rbs_hash_t *memo, bool self_allowed, bool classish_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, self_allowed)); + CHECK_PARSE(parse_function_param(parser, ¶m, self_allowed, classish_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, bool self_allowed) { +static bool parse_params(rbs_parser_t *parser, method_params *params, bool self_allowed, bool classish_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, bool self_ } rbs_types_function_param_t *param = NULL; - CHECK_PARSE(parse_function_param(parser, ¶m, self_allowed)); + CHECK_PARSE(parse_function_param(parser, ¶m, self_allowed, classish_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, bool self_ rbs_parser_advance(parser); if (is_keyword(parser)) { - CHECK_PARSE(parse_keyword(parser, params->optional_keywords, memo, self_allowed)); + CHECK_PARSE(parse_keyword(parser, params->optional_keywords, memo, self_allowed, classish_allowed)); parser_advance_if(parser, pCOMMA); goto PARSE_KEYWORDS; } rbs_types_function_param_t *param = NULL; - CHECK_PARSE(parse_function_param(parser, ¶m, self_allowed)); + CHECK_PARSE(parse_function_param(parser, ¶m, self_allowed, classish_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, bool self_ if (parser->next_token.type == pSTAR) { rbs_parser_advance(parser); rbs_types_function_param_t *param = NULL; - CHECK_PARSE(parse_function_param(parser, ¶m, self_allowed)); + CHECK_PARSE(parse_function_param(parser, ¶m, self_allowed, classish_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, bool self_ } rbs_types_function_param_t *param = NULL; - CHECK_PARSE(parse_function_param(parser, ¶m, self_allowed)); + CHECK_PARSE(parse_function_param(parser, ¶m, self_allowed, classish_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, bool self_ case pQUESTION: rbs_parser_advance(parser); if (is_keyword(parser)) { - CHECK_PARSE(parse_keyword(parser, params->optional_keywords, memo, self_allowed)); + CHECK_PARSE(parse_keyword(parser, params->optional_keywords, memo, self_allowed, classish_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, bool self_ case pSTAR2: rbs_parser_advance(parser); rbs_types_function_param_t *param = NULL; - CHECK_PARSE(parse_function_param(parser, ¶m, self_allowed)); + CHECK_PARSE(parse_function_param(parser, ¶m, self_allowed, classish_allowed)); params->rest_keywords = (rbs_node_t *) param; break; @@ -630,7 +630,7 @@ static bool parse_params(rbs_parser_t *parser, method_params *params, bool self_ case tBANGIDENT: KEYWORD_CASES if (is_keyword(parser)) { - CHECK_PARSE(parse_keyword(parser, params->required_keywords, memo, self_allowed)); + CHECK_PARSE(parse_keyword(parser, params->required_keywords, memo, self_allowed, classish_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, bool self_ | {} simple_type <`?`> */ NODISCARD -static bool parse_optional(rbs_parser_t *parser, rbs_node_t **optional, bool void_allowed, bool self_allowed) { +static bool parse_optional(rbs_parser_t *parser, rbs_node_t **optional, bool void_allowed, bool self_allowed, bool classish_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, self_allowed)); + CHECK_PARSE(parse_simple(parser, &type, void_allowed, self_allowed, classish_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, bool self_allowed) { +static bool parse_self_type_binding(rbs_parser_t *parser, rbs_node_t **self_type, bool self_allowed, bool classish_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, self_allowed)); + CHECK_PARSE(rbs_parse_type(parser, &type, false, self_allowed, classish_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, bool self_allowed) { +static bool parse_function(rbs_parser_t *parser, bool accept_type_binding, parse_function_result **result, bool self_allowed, bool classish_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, self_allowed)); + CHECK_PARSE(parse_params(parser, ¶ms, self_allowed, classish_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, self_allowed)); + CHECK_PARSE(parse_self_type_binding(parser, &function_self_type, self_allowed, classish_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, self_allowed)); + CHECK_PARSE(parse_params(parser, &block_params, self_allowed, classish_allowed)); ADVANCE_ASSERT(parser, pRPAREN); } rbs_node_t *self_type = NULL; - CHECK_PARSE(parse_self_type_binding(parser, &self_type, self_allowed)); + CHECK_PARSE(parse_self_type_binding(parser, &self_type, self_allowed, classish_allowed)); ADVANCE_ASSERT(parser, pARROW); rbs_node_t *block_return_type = NULL; - CHECK_PARSE(parse_optional(parser, &block_return_type, true, self_allowed)); + CHECK_PARSE(parse_optional(parser, &block_return_type, true, self_allowed, classish_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, self_allowed)); + CHECK_PARSE(parse_optional(parser, &type, true, self_allowed, classish_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, bool self_allowed) { +static bool parse_proc_type(rbs_parser_t *parser, rbs_types_proc_t **proc, bool self_allowed, bool classish_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, self_allowed)); + CHECK_PARSE(parse_function(parser, true, &result, self_allowed, classish_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, bool self_allowed) { +static bool parse_record_attributes(rbs_parser_t *parser, rbs_hash_t **fields, bool self_allowed, bool classish_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, b case kTRUE: case kFALSE: { rbs_node_t *type = NULL; - CHECK_PARSE(parse_simple(parser, &type, false, self_allowed)); + CHECK_PARSE(parse_simple(parser, &type, false, self_allowed, classish_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, b field_range.start = parser->current_token.range.end; rbs_node_t *type; - CHECK_PARSE(rbs_parse_type(parser, &type, false, self_allowed)); + CHECK_PARSE(rbs_parse_type(parser, &type, false, self_allowed, classish_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, true)); + CHECK_PARSE(parse_type_list(parser, pRBRACKET, types, true, 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, bool self_allowed) { +static bool parse_simple(rbs_parser_t *parser, rbs_node_t **type, bool void_allowed, bool self_allowed, bool classish_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, self_allowed)); + CHECK_PARSE(rbs_parse_type(parser, &lparen_type, false, self_allowed, classish_allowed)); ADVANCE_ASSERT(parser, pRPAREN); *type = lparen_type; return true; @@ -1141,11 +1141,21 @@ static bool parse_simple(rbs_parser_t *parser, rbs_node_t **type, bool void_allo return true; } case kCLASS: { + if (!classish_allowed) { + rbs_parser_set_error(parser, parser->current_token, true, "class type is not allowed here"); + return false; + } + rbs_location_t *loc = rbs_location_current_token(parser); *type = (rbs_node_t *) rbs_types_bases_class_new(ALLOCATOR(), loc); return true; } case kINSTANCE: { + if (!classish_allowed) { + rbs_parser_set_error(parser, parser->current_token, true, "instance type is not allowed here"); + return false; + } + rbs_location_t *loc = rbs_location_current_token(parser); *type = (rbs_node_t *) rbs_types_bases_instance_new(ALLOCATOR(), loc); return true; @@ -1264,7 +1274,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, self_allowed)); + CHECK_PARSE(parse_type_list(parser, pRBRACKET, types, false, self_allowed, classish_allowed)); } ADVANCE_ASSERT(parser, pRBRACKET); rg.end = parser->current_token.range.end; @@ -1282,7 +1292,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, self_allowed)); + CHECK_PARSE(parse_record_attributes(parser, &fields, self_allowed, classish_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 }); @@ -1291,7 +1301,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, self_allowed)); + CHECK_PARSE(parse_proc_type(parser, &value, self_allowed, classish_allowed)); *type = (rbs_node_t *) value; return true; } @@ -1306,12 +1316,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, bool self_allowed) { +static bool parse_intersection(rbs_parser_t *parser, rbs_node_t **type, bool void_allowed, bool self_allowed, bool classish_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, self_allowed)); + CHECK_PARSE(parse_optional(parser, &optional, void_allowed, self_allowed, classish_allowed)); *type = optional; rbs_node_list_t *intersection_types = rbs_node_list_new(ALLOCATOR()); @@ -1325,7 +1335,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, self_allowed)); + CHECK_PARSE(parse_optional(parser, &type, false, self_allowed, classish_allowed)); rbs_node_list_append(intersection_types, type); } @@ -1343,12 +1353,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 self_allowed) { +bool rbs_parse_type(rbs_parser_t *parser, rbs_node_t **type, bool void_allowed, bool self_allowed, bool classish_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, self_allowed)); + CHECK_PARSE(parse_intersection(parser, type, void_allowed, self_allowed, classish_allowed)); rbs_node_list_append(union_types, *type); @@ -1360,7 +1370,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, self_allowed)); + CHECK_PARSE(parse_intersection(parser, &intersection, false, self_allowed, classish_allowed)); rbs_node_list_append(union_types, intersection); } @@ -1453,7 +1463,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, false)); + CHECK_PARSE(rbs_parse_type(parser, &upper_bound, false, false, false)); upper_bound_range.end = parser->current_token.range.end; break; @@ -1465,7 +1475,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, false)); + CHECK_PARSE(rbs_parse_type(parser, &lower_bound, false, false, false)); lower_bound_range.end = parser->current_token.range.end; break; @@ -1480,7 +1490,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, false)); + CHECK_PARSE(rbs_parse_type(parser, &default_type, true, false, false)); default_type_range.end = parser->current_token.range.end; required_param_allowed = false; @@ -1550,7 +1560,7 @@ static bool parser_pop_typevar_table(rbs_parser_t *parser) { method_type ::= {} type_params */ // TODO: Should this be NODISCARD? -bool rbs_parse_method_type(rbs_parser_t *parser, rbs_method_type_t **method_type) { +bool rbs_parse_method_type(rbs_parser_t *parser, rbs_method_type_t **method_type, bool classish_allowed) { rbs_parser_push_typevar_table(parser, false); rbs_range_t rg; @@ -1564,7 +1574,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, true)); + CHECK_PARSE(parse_function(parser, false, &result, true, classish_allowed)); rg.end = parser->current_token.range.end; type_range.end = rg.end; @@ -1599,7 +1609,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, false)); + CHECK_PARSE(rbs_parse_type(parser, &type, false, false, false)); decl_range.end = parser->current_token.range.end; rbs_location_t *loc = rbs_location_new(ALLOCATOR(), decl_range); @@ -1629,7 +1639,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, false)); + CHECK_PARSE(rbs_parse_type(parser, &type, false, false, false)); decl_range.end = parser->current_token.range.end; @@ -1669,7 +1679,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, false)); + CHECK_PARSE(rbs_parse_type(parser, &type, false, false, false)); decl_range.end = parser->current_token.range.end; @@ -1978,7 +1988,7 @@ static bool parse_member_def(rbs_parser_t *parser, bool instance_only, bool acce case pLBRACKET: case pQUESTION: { rbs_method_type_t *method_type = NULL; - CHECK_PARSE(rbs_parse_method_type(parser, &method_type)); + CHECK_PARSE(rbs_parse_method_type(parser, &method_type, !instance_only)); overload_range.end = parser->current_token.range.end; rbs_location_t *loc = rbs_location_new(ALLOCATOR(), overload_range); @@ -2053,7 +2063,7 @@ static bool parse_member_def(rbs_parser_t *parser, bool instance_only, bool acce * @param kind * */ NODISCARD -static bool class_instance_name(rbs_parser_t *parser, TypeNameKind kind, rbs_node_list_t *args, rbs_range_t *name_range, rbs_range_t *args_range, rbs_type_name_t **name) { +static bool class_instance_name(rbs_parser_t *parser, TypeNameKind kind, rbs_node_list_t *args, rbs_range_t *name_range, rbs_range_t *args_range, rbs_type_name_t **name, bool classish_allowed) { rbs_parser_advance(parser); rbs_type_name_t *type_name = NULL; @@ -2063,7 +2073,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, false)); + CHECK_PARSE(parse_type_list(parser, pRBRACKET, args, true, false, classish_allowed)); ADVANCE_ASSERT(parser, pRBRACKET); args_range->end = parser->current_token.range.end; } else { @@ -2124,7 +2134,8 @@ static bool parse_mixin_member(rbs_parser_t *parser, bool from_interface, rbs_po args, &name_range, &args_range, - &name + &name, + true )); CHECK_PARSE(parser_pop_typevar_table(parser)); @@ -2238,7 +2249,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, true)); + CHECK_PARSE(rbs_parse_type(parser, &type, false, true, true)); member_range.end = parser->current_token.range.end; rbs_location_t *loc = rbs_location_new(ALLOCATOR(), member_range); @@ -2261,7 +2272,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, false)); + CHECK_PARSE(rbs_parse_type(parser, &type, false, false, true)); CHECK_PARSE(parser_pop_typevar_table(parser)); @@ -2300,7 +2311,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, true)); + CHECK_PARSE(rbs_parse_type(parser, &type, false, true, true)); CHECK_PARSE(parser_pop_typevar_table(parser)); @@ -2441,7 +2452,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, true)); + CHECK_PARSE(rbs_parse_type(parser, &type, false, true, true)); CHECK_PARSE(parser_pop_typevar_table(parser)); @@ -2594,7 +2605,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, false)); + CHECK_PARSE(parse_type_list(parser, pRBRACKET, args, true, false, false)); rbs_parser_advance(parser); self_range.end = args_range.end = parser->current_token.range.end; } @@ -2829,7 +2840,7 @@ static bool parse_class_decl_super(rbs_parser_t *parser, rbs_range_t *lt_range, rbs_node_list_t *args = rbs_node_list_new(ALLOCATOR()); rbs_type_name_t *name = NULL; rbs_range_t name_range, args_range; - CHECK_PARSE(class_instance_name(parser, CLASS_NAME, args, &name_range, &args_range, &name)); + CHECK_PARSE(class_instance_name(parser, CLASS_NAME, args, &name_range, &args_range, &name, false)); super_range.end = parser->current_token.range.end; @@ -3584,7 +3595,7 @@ static bool parse_method_overload(rbs_parser_t *parser, rbs_node_list_t *annotat return false; } - return rbs_parse_method_type(parser, method_type); + return rbs_parse_method_type(parser, method_type, true); } /* @@ -3743,7 +3754,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, true)) { + if (!rbs_parse_type(parser, &return_type, true, true, true)) { return false; } @@ -3789,7 +3800,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, true)) { + if (!rbs_parse_type(parser, &type, false, true, true)) { return false; } @@ -3840,7 +3851,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, true)) { + if (!rbs_parse_type(parser, &type, true, true, true)) { return false; } @@ -3873,7 +3884,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, true)); + CHECK_PARSE(parse_type_list_with_commas(parser, pRBRACKET, type_args, comma_locations, true, true, false)); 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 36f25fec5..c37a2b4c4 100644 --- a/test/rbs/cli_test.rb +++ b/test/rbs/cli_test.rb @@ -665,42 +665,6 @@ def bar: () -> Nothing end end - def test_validate_multiple_with_exit_error_on_syntax_error - with_cli do |cli| - Dir.mktmpdir do |dir| - (Pathname(dir) + 'a.rbs').write(<<~RBS) - class Foo - type bar = instance - end - RBS - - 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:21: `instance` or `class` type is not allowed in this context (RBS::WillSyntaxError)" - end - end - end - - def test_validate_multiple_with_fail_fast_and_exit_error_on_syntax_error - with_cli do |cli| - Dir.mktmpdir do |dir| - (Pathname(dir) + 'a.rbs').write(<<~RBS) - class Foo - def foo: (T) -> void - def bar: (T) -> void - end - RBS - - refute_cli_success do - cli.run(["-I", dir, "--log-level=warn", "validate", "--fail-fast", "--exit-error-on-syntax-error"]) - end - assert_include stdout.string, "/a.rbs:2:12...2:13: Could not find T (RBS::NoTypeFoundError)" - assert_not_include stdout.string, "/a.rbs:3:12...3:13: Could not find T (RBS::NoTypeFoundError)" - end - end - end - def test_validate_multiple_with_many_errors with_cli do |cli| refute_cli_success do @@ -739,60 +703,6 @@ def test_validate_multiple_fail_fast end end - def test_validate_multiple_fail_fast_and_exit_error_on_syntax_error - with_cli do |cli| - refute_cli_success do - cli.run(%w(--log-level=warn -I test/multiple_error.rbs validate --fail-fast --exit-error-on-syntax-error)) - end - assert_include(stdout.string, "test/multiple_error.rbs:6:17...6:24: ::TypeArg expects parameters [T], but given args [] (RBS::InvalidTypeApplicationError)") - end - end - - def test_context_validation - tests = [ - <<~RBS, - class Bar[A] - end - class Foo < Bar[instance] - end - RBS - <<~RBS, - module Bar : _Each[instance] - end - RBS - <<~RBS, - type foo = instance - RBS - <<~RBS, - BAR: instance - RBS - <<~RBS, - $FOO: instance - RBS - ] - - tests.each do |rbs| - with_cli do |cli| - Dir.mktmpdir do |dir| - (Pathname(dir) + 'a.rbs').write(rbs) - - assert_cli_success do - cli.run(["-I", dir, "validate"]) - end - - assert_match(/void|self|instance|class/, stdout.string) - - assert_cli_success do - cli.run(["-I", dir, "validate", "--no-exit-error-on-syntax-error"]) - end - refute_cli_success do - cli.run(["-I", dir, "validate", "--exit-error-on-syntax-error"]) - end - end - end - end - end - def test_validate_878 with_cli do |cli| Dir.mktmpdir do |dir| diff --git a/test/rbs/inline_annotation_parsing_test.rb b/test/rbs/inline_annotation_parsing_test.rb index 4cea75cd3..3c7801e05 100644 --- a/test/rbs/inline_annotation_parsing_test.rb +++ b/test/rbs/inline_annotation_parsing_test.rb @@ -12,6 +12,20 @@ def test_parse__trailing_assertion assert_equal ":", annot.prefix_location.source assert_equal "String", annot.type.location.source end + + Parser.parse_inline_trailing_annotation(": void", 0...).tap do |annot| + assert_instance_of AST::Ruby::Annotations::NodeTypeAssertion, annot + assert_equal ": void", annot.location.source + assert_equal ":", annot.prefix_location.source + assert_equal "void", annot.type.location.source + end + + Parser.parse_inline_trailing_annotation(": self | class | instance", 0...).tap do |annot| + assert_instance_of AST::Ruby::Annotations::NodeTypeAssertion, annot + assert_equal ": self | class | instance", annot.location.source + assert_equal ":", annot.prefix_location.source + assert_equal "self | class | instance", annot.type.location.source + end end def test_error__trailing_assertion @@ -106,12 +120,12 @@ def test_parse__return assert_nil annot.comment_location end - Parser.parse_inline_leading_annotation("@rbs return: self -- some comment here", 0...).tap do |annot| + Parser.parse_inline_leading_annotation("@rbs return: self | class | instance -- some comment here", 0...).tap do |annot| assert_instance_of AST::Ruby::Annotations::ReturnTypeAnnotation, annot - assert_equal "@rbs return: self -- some comment here", annot.location.source + assert_equal "@rbs return: self | class | instance -- some comment here", annot.location.source assert_equal "return", annot.return_location.source assert_equal ":", annot.colon_location.source - assert_equal "self", annot.return_type.location.source + assert_equal "self | class | instance", annot.return_type.location.source assert_equal "-- some comment here", annot.comment_location.source end end @@ -191,14 +205,14 @@ def test_parse__instance_variable assert_nil annot.comment_location end - Parser.parse_inline_leading_annotation("@rbs @self: self", 0...).tap do |annot| + Parser.parse_inline_leading_annotation("@rbs @sci: self | class | instance", 0...).tap do |annot| assert_instance_of AST::Ruby::Annotations::InstanceVariableAnnotation, annot - assert_equal "@rbs @self: self", annot.location.source + assert_equal "@rbs @sci: self | class | instance", annot.location.source assert_equal "@rbs", annot.prefix_location.source - assert_equal "@self", annot.ivar_name_location.source - assert_equal :@self, annot.ivar_name + assert_equal "@sci", annot.ivar_name_location.source + assert_equal :@sci, annot.ivar_name assert_equal ":", annot.colon_location.source - assert_equal "self", annot.type.location.source + assert_equal "self | class | instance", annot.type.location.source assert_nil annot.comment_location end end diff --git a/test/rbs/signature_parsing_test.rb b/test/rbs/signature_parsing_test.rb index bd8ad4654..4167f7359 100644 --- a/test/rbs/signature_parsing_test.rb +++ b/test/rbs/signature_parsing_test.rb @@ -2387,6 +2387,7 @@ def foo: (Array[void]) -> void def foo: (self) -> self def foo: (class) -> class def foo: (instance) -> instance + def foo: () -> A[void, self, class, instance] end RBS end @@ -2483,6 +2484,46 @@ def foo: () -> ^(void) -> void end assert_equal [2, 19], ex.location.start_loc assert_equal [2, 23], ex.location.end_loc + + ex = assert_raises RBS::ParsingError do + Parser.parse_signature(<<~RBS) + interface _Foo + def foo: () -> class + end + RBS + end + assert_equal [2, 17], ex.location.start_loc + assert_equal [2, 22], ex.location.end_loc + + ex = assert_raises RBS::ParsingError do + Parser.parse_signature(<<~RBS) + interface _Foo + def foo: () -> ^() -> class + end + RBS + end + assert_equal [2, 24], ex.location.start_loc + assert_equal [2, 29], ex.location.end_loc + + ex = assert_raises RBS::ParsingError do + Parser.parse_signature(<<~RBS) + interface _Foo + def foo: () -> instance + end + RBS + end + assert_equal [2, 17], ex.location.start_loc + assert_equal [2, 25], ex.location.end_loc + + ex = assert_raises RBS::ParsingError do + Parser.parse_signature(<<~RBS) + interface _Foo + def foo: () { () -> instance } -> void + end + RBS + end + assert_equal [2, 22], ex.location.start_loc + assert_equal [2, 30], ex.location.end_loc end def test_context_syntax_error_attribute @@ -2537,6 +2578,18 @@ def test_context_syntax_error_super_class 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("class Foo < Array[class] end") + end + assert_equal [1, 18], ex.location.start_loc + assert_equal [1, 23], ex.location.end_loc + + ex = assert_raises RBS::ParsingError do + Parser.parse_signature("class Foo < Array[instance] end") + end + assert_equal [1, 18], ex.location.start_loc + assert_equal [1, 26], ex.location.end_loc end def test_context_syntax_error_module_self_type @@ -2555,6 +2608,18 @@ def test_context_syntax_error_module_self_type 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("module Foo : Array[class] end") + end + assert_equal [1, 19], ex.location.start_loc + assert_equal [1, 24], ex.location.end_loc + + ex = assert_raises RBS::ParsingError do + Parser.parse_signature("module Foo : Array[instance] end") + end + assert_equal [1, 19], ex.location.start_loc + assert_equal [1, 27], ex.location.end_loc end def test_context_syntax_error_global @@ -2569,6 +2634,18 @@ 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: class") + end + assert_equal [1, 7], ex.location.start_loc + assert_equal [1, 12], ex.location.end_loc + + ex = assert_raises RBS::ParsingError do + Parser.parse_signature("$glob: instance") + end + assert_equal [1, 7], ex.location.start_loc + assert_equal [1, 15], ex.location.end_loc end def test_context_syntax_error_constant @@ -2583,6 +2660,18 @@ 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: class") + end + assert_equal [1, 7], ex.location.start_loc + assert_equal [1, 12], ex.location.end_loc + + ex = assert_raises RBS::ParsingError do + Parser.parse_signature("CONST: instance") + end + assert_equal [1, 7], ex.location.start_loc + assert_equal [1, 15], ex.location.end_loc end def test_context_syntax_error_type_alias @@ -2597,6 +2686,18 @@ 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 = class") + end + assert_equal [1, 9], ex.location.start_loc + assert_equal [1, 14], ex.location.end_loc + + ex = assert_raises RBS::ParsingError do + Parser.parse_signature("type a = instance") + end + assert_equal [1, 9], ex.location.start_loc + assert_equal [1, 17], ex.location.end_loc end def test_context_syntax_error_mixin @@ -2607,6 +2708,12 @@ class C include M[class] include M[instance] end + + interface _C + include _M[void] + include _M[class] + include _M[instance] + end SIG end @@ -2689,6 +2796,18 @@ 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 < class] end") + end + assert_equal [1, 12], ex.location.start_loc + assert_equal [1, 17], ex.location.end_loc + + ex = assert_raises RBS::ParsingError do + Parser.parse_signature("class C[T < instance] end") + end + assert_equal [1, 12], ex.location.start_loc + assert_equal [1, 20], ex.location.end_loc + ex = assert_raises RBS::ParsingError do Parser.parse_signature("module M[T < void] end") end @@ -2701,6 +2820,18 @@ module M[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("module M[T < class] end") + end + assert_equal [1, 13], ex.location.start_loc + assert_equal [1, 18], ex.location.end_loc + + ex = assert_raises RBS::ParsingError do + Parser.parse_signature("module M[T < instance] end") + end + assert_equal [1, 13], ex.location.start_loc + assert_equal [1, 21], ex.location.end_loc + ex = assert_raises RBS::ParsingError do Parser.parse_signature("interface _I[T < void] end") end @@ -2713,6 +2844,18 @@ module M[T < Array[void]] 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 < class] end") + end + assert_equal [1, 17], ex.location.start_loc + assert_equal [1, 22], ex.location.end_loc + + ex = assert_raises RBS::ParsingError do + Parser.parse_signature("interface _I[T < instance] end") + end + assert_equal [1, 17], ex.location.start_loc + assert_equal [1, 25], ex.location.end_loc + ex = assert_raises RBS::ParsingError do Parser.parse_signature("type a[T < void] = 1") end @@ -2724,6 +2867,18 @@ module M[T < Array[void]] 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 < class] = 1") + end + assert_equal [1, 11], ex.location.start_loc + assert_equal [1, 16], ex.location.end_loc + + ex = assert_raises RBS::ParsingError do + Parser.parse_signature("type a[T < instance] = 1") + end + assert_equal [1, 11], ex.location.start_loc + assert_equal [1, 19], ex.location.end_loc end def test_context_syntax_error_lower_bound @@ -2751,6 +2906,22 @@ 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 > class] end") + end + assert_equal [1, 12], ex.location.start_loc + assert_equal [1, 17], ex.location.end_loc + + ex = assert_raises RBS::ParsingError do + Parser.parse_signature("class C[T > instance] end") + end + assert_equal [1, 12], ex.location.start_loc + assert_equal [1, 20], ex.location.end_loc + + ex = assert_raises RBS::ParsingError do + Parser.parse_signature("class C[T > instance] end") + end + assert_equal [1, 12], ex.location.start_loc ex = assert_raises RBS::ParsingError do Parser.parse_signature("module M[T > void] end") end @@ -2763,6 +2934,22 @@ module M[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("module M[T > class] end") + end + assert_equal [1, 13], ex.location.start_loc + assert_equal [1, 18], ex.location.end_loc + + ex = assert_raises RBS::ParsingError do + Parser.parse_signature("module M[T > instance] end") + end + assert_equal [1, 13], ex.location.start_loc + assert_equal [1, 21], ex.location.end_loc + + ex = assert_raises RBS::ParsingError do + Parser.parse_signature("module M[T > instance] end") + end + assert_equal [1, 13], ex.location.start_loc ex = assert_raises RBS::ParsingError do Parser.parse_signature("interface _I[T > void] end") end @@ -2775,6 +2962,18 @@ module M[T > Array[void]] 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 > class] end") + end + assert_equal [1, 17], ex.location.start_loc + assert_equal [1, 22], ex.location.end_loc + + ex = assert_raises RBS::ParsingError do + Parser.parse_signature("interface _I[T > instance] end") + end + assert_equal [1, 17], ex.location.start_loc + assert_equal [1, 25], ex.location.end_loc + ex = assert_raises RBS::ParsingError do Parser.parse_signature("type a[T > void] = 1") end @@ -2786,6 +2985,18 @@ module M[T > Array[void]] 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 > class] = 1") + end + assert_equal [1, 11], ex.location.start_loc + assert_equal [1, 16], ex.location.end_loc + + ex = assert_raises RBS::ParsingError do + Parser.parse_signature("type a[T > instance] = 1") + end + assert_equal [1, 11], ex.location.start_loc + assert_equal [1, 19], ex.location.end_loc end def test_context_syntax_error_upper_and_lower_bound @@ -2858,6 +3069,18 @@ module MA[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 = class] end") + end + assert_equal [1, 12], ex.location.start_loc + assert_equal [1, 17], ex.location.end_loc + + ex = assert_raises RBS::ParsingError do + Parser.parse_signature("class C[T = instance] end") + end + assert_equal [1, 12], ex.location.start_loc + assert_equal [1, 20], ex.location.end_loc + ex = assert_raises RBS::ParsingError do Parser.parse_signature("module M[T = [void]] end") end @@ -2870,6 +3093,18 @@ 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("module M[T = class] end") + end + assert_equal [1, 13], ex.location.start_loc + assert_equal [1, 18], ex.location.end_loc + + ex = assert_raises RBS::ParsingError do + Parser.parse_signature("module M[T = instance] end") + end + assert_equal [1, 13], ex.location.start_loc + assert_equal [1, 21], ex.location.end_loc + ex = assert_raises RBS::ParsingError do Parser.parse_signature("interface _I[T = [void]] end") end @@ -2882,6 +3117,18 @@ module MA[T = Array[void]] 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 = class] end") + end + assert_equal [1, 17], ex.location.start_loc + assert_equal [1, 22], ex.location.end_loc + + ex = assert_raises RBS::ParsingError do + Parser.parse_signature("interface _I[T = instance] end") + end + assert_equal [1, 17], ex.location.start_loc + assert_equal [1, 25], ex.location.end_loc + ex = assert_raises RBS::ParsingError do Parser.parse_signature("type a[T = [void]] = 1") end @@ -2893,5 +3140,17 @@ module MA[T = Array[void]] 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 = class] = 1") + end + assert_equal [1, 11], ex.location.start_loc + assert_equal [1, 16], ex.location.end_loc + + ex = assert_raises RBS::ParsingError do + Parser.parse_signature("type a[T = instance] = 1") + end + assert_equal [1, 11], ex.location.start_loc + assert_equal [1, 19], ex.location.end_loc end end