From 892bd387aaf1294ab66ff91ceb5546c3a35261b4 Mon Sep 17 00:00:00 2001 From: IG Date: Thu, 10 Sep 2026 04:26:13 +0400 Subject: [PATCH] Report a malformed class instance variable as a syntax error The `kSELF` branch of `parse_variable_member` reported a missing or invalid variable name by calling `rbs_parser_set_error` with `syntax_error` set to `false`. `raise_error` discards the location, token and message in that case and raises a bare `RuntimeError`, so `class M self.` escaped `rescue RBS::ParsingError` and the CLI printed a Ruby backtrace instead of a formatted syntax error. Every other malformed member in the same position, and the same construct under `interface`, already reported an `RBS::ParsingError`. Pass `syntax_error` and a specific message, as the other syntax error sites do. Set the error on `next_token`, which is the token the branch tests and therefore the offending one; `current_token` would point the caret at the dot. --- src/parser.c | 2 +- test/rbs/errors_test.rb | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/parser.c b/src/parser.c index 5effb219e4..de7e82dc23 100644 --- a/src/parser.c +++ b/src/parser.c @@ -2350,7 +2350,7 @@ static bool parse_variable_member(rbs_parser_t *parser, rbs_position_t comment_p if (parser->next_token.type == tAIDENT || parser->next_token.type == kATRBS) { rbs_parser_advance(parser); } else { - rbs_parser_set_error(parser, parser->current_token, false, "Unexpected error"); + rbs_parser_set_error(parser, parser->next_token, true, "unexpected token for class instance variable name"); return false; } diff --git a/test/rbs/errors_test.rb b/test/rbs/errors_test.rb index 6aed3fbb06..a152b5ba3f 100644 --- a/test/rbs/errors_test.rb +++ b/test/rbs/errors_test.rb @@ -24,6 +24,29 @@ class Foo end end + def test_parse_signature_with_malformed_class_instance_variable + ["class M self.", "module M self.", "class M self.5", %q{class M self."x"}].each do |source| + assert_raises RBS::ParsingError, "#{source.inspect} should raise RBS::ParsingError" do + RBS::Parser.parse_signature(buffer(source)) + end + end + end + + def test_parse_signature_with_malformed_class_instance_variable_detailed_message + omit "Exception#detailed_message does not supported" unless Exception.method_defined?(:detailed_message) + + assert_raises RBS::ParsingError do + RBS::Parser.parse_signature(buffer("class M self.5")) + end.tap do |exn| + assert_equal <<~DETAILED_MESSAGE, exn.detailed_message + test.rbs:1:13...1:14: Syntax error: unexpected token for class instance variable name, token=`5` (tINTEGER) (RBS::ParsingError) + + class M self.5 + ^ + DETAILED_MESSAGE + end + end + def test_parse_type_with_parsing_error_detailed_message omit "Exception#detailed_message does not supported" unless Exception.method_defined?(:detailed_message)