From 6a5ee7529cbe35399a8a15627248e210b49e7411 Mon Sep 17 00:00:00 2001 From: Soutaro Matsumoto Date: Mon, 6 Apr 2026 12:06:43 +0900 Subject: [PATCH 1/2] Process instance variable declaration in module --- lib/rbs/inline_parser.rb | 27 ++++++++++++++++++++++++++- test/rbs/inline_parser_test.rb | 22 ++++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/lib/rbs/inline_parser.rb b/lib/rbs/inline_parser.rb index 584a4f087..1202a1778 100644 --- a/lib/rbs/inline_parser.rb +++ b/lib/rbs/inline_parser.rb @@ -168,11 +168,36 @@ def visit_module_node(node) insert_declaration(module_decl) push_module_nesting(module_decl) do visit_child_nodes(node) + + node.child_nodes.each do |child_node| + if child_node + comments.each_enclosed_block(child_node) do |block| + report_unused_block(block) + end + end + end end comments.each_enclosed_block(node) do |block| - report_unused_block(block) + unused_annotations = [] #: Array[AST::Ruby::CommentBlock::AnnotationSyntaxError | AST::Ruby::Annotations::leading_annotation] + + block.each_paragraph([]) do |paragraph| + case paragraph + when AST::Ruby::Annotations::InstanceVariableAnnotation + module_decl.members << AST::Ruby::Members::InstanceVariableMember.new(buffer, paragraph) + when Location + # Skip + when AST::Ruby::CommentBlock::AnnotationSyntaxError + unused_annotations << paragraph + else + unused_annotations << paragraph + end + end + + report_unused_annotation(*unused_annotations) end + + module_decl.members.sort_by! { _1.location.start_line } end def visit_def_node(node) diff --git a/test/rbs/inline_parser_test.rb b/test/rbs/inline_parser_test.rb index 28c90aa72..7dc1c1f6e 100644 --- a/test/rbs/inline_parser_test.rb +++ b/test/rbs/inline_parser_test.rb @@ -1502,6 +1502,28 @@ def initialize(name, age) end end + def test_parse__instance_variable_in_module + result = parse(<<~RUBY) + module Foo + # @rbs @bar: String + end + RUBY + + assert_empty result.diagnostics + + result.declarations[0].tap do |decl| + assert_instance_of RBS::AST::Ruby::Declarations::ModuleDecl, decl + + assert_equal 1, decl.members.size + + decl.members[0].tap do |member| + assert_instance_of RBS::AST::Ruby::Members::InstanceVariableMember, member + assert_equal :@bar, member.name + assert_equal "String", member.type.to_s + end + end + end + def test_error__instance_variable_ignored result = parse(<<~RUBY) # @rbs @global_decl: String From e91773ef1ad378cddf912616db654398ffa7c7a7 Mon Sep 17 00:00:00 2001 From: Soutaro Matsumoto Date: Mon, 6 Apr 2026 12:40:19 +0900 Subject: [PATCH 2/2] Refactor inline_parser --- lib/rbs/inline_parser.rb | 43 ++++++++-------------------------------- sig/inline_parser.rbs | 2 ++ 2 files changed, 10 insertions(+), 35 deletions(-) diff --git a/lib/rbs/inline_parser.rb b/lib/rbs/inline_parser.rb index 1202a1778..aa92c58a1 100644 --- a/lib/rbs/inline_parser.rb +++ b/lib/rbs/inline_parser.rb @@ -119,38 +119,7 @@ def visit_class_node(node) class_decl = AST::Ruby::Declarations::ClassDecl.new(buffer, class_name, node, super_class) insert_declaration(class_decl) - push_module_nesting(class_decl) do - visit_child_nodes(node) - - node.child_nodes.each do |child_node| - if child_node - comments.each_enclosed_block(child_node) do |block| - report_unused_block(block) - end - end - end - end - - comments.each_enclosed_block(node) do |block| - unused_annotations = [] #: Array[AST::Ruby::CommentBlock::AnnotationSyntaxError | AST::Ruby::Annotations::leading_annotation] - - block.each_paragraph([]) do |paragraph| - case paragraph - when AST::Ruby::Annotations::InstanceVariableAnnotation - class_decl.members << AST::Ruby::Members::InstanceVariableMember.new(buffer, paragraph) - when Location - # Skip - when AST::Ruby::CommentBlock::AnnotationSyntaxError - unused_annotations << paragraph - else - unused_annotations << paragraph - end - end - - report_unused_annotation(*unused_annotations) - end - - class_decl.members.sort_by! { _1.location.start_line } + visit_class_or_module_body(class_decl, node) end def visit_module_node(node) @@ -166,7 +135,11 @@ def visit_module_node(node) module_decl = AST::Ruby::Declarations::ModuleDecl.new(buffer, module_name, node) insert_declaration(module_decl) - push_module_nesting(module_decl) do + visit_class_or_module_body(module_decl, node) + end + + def visit_class_or_module_body(decl, node) + push_module_nesting(decl) do visit_child_nodes(node) node.child_nodes.each do |child_node| @@ -184,7 +157,7 @@ def visit_module_node(node) block.each_paragraph([]) do |paragraph| case paragraph when AST::Ruby::Annotations::InstanceVariableAnnotation - module_decl.members << AST::Ruby::Members::InstanceVariableMember.new(buffer, paragraph) + decl.members << AST::Ruby::Members::InstanceVariableMember.new(buffer, paragraph) when Location # Skip when AST::Ruby::CommentBlock::AnnotationSyntaxError @@ -197,7 +170,7 @@ def visit_module_node(node) report_unused_annotation(*unused_annotations) end - module_decl.members.sort_by! { _1.location.start_line } + decl.members.sort_by! { _1.location.start_line } end def visit_def_node(node) diff --git a/sig/inline_parser.rbs b/sig/inline_parser.rbs index 13278dd5e..5811e9a4d 100644 --- a/sig/inline_parser.rbs +++ b/sig/inline_parser.rbs @@ -110,6 +110,8 @@ module RBS def report_unused_block: (AST::Ruby::CommentBlock) -> void + def visit_class_or_module_body: (module_context, Prism::ClassNode | Prism::ModuleNode) -> void + private def parse_mixin_call: (Prism::CallNode) -> void