From 753c7dd578451f9d33d6d251e52f94a134d9d828 Mon Sep 17 00:00:00 2001 From: Thomas Marshall Date: Fri, 28 Nov 2025 16:34:56 +0000 Subject: [PATCH 1/2] Pass index configuration to entries This commit adds the index configuration to entries which will later be used to fix an issue with magic comments appearing in documentation. --- .../lib/ruby_indexer/declaration_listener.rb | 19 ++++++ lib/ruby_indexer/lib/ruby_indexer/entry.rb | 58 ++++++++++--------- lib/ruby_indexer/lib/ruby_indexer/index.rb | 1 + .../lib/ruby_indexer/rbs_indexer.rb | 8 ++- 4 files changed, 58 insertions(+), 28 deletions(-) diff --git a/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb b/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb index 37adf9e4c7..174dc346ba 100644 --- a/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb +++ b/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb @@ -143,6 +143,7 @@ def on_singleton_class_node_enter(node) ) else entry = Entry::SingletonClass.new( + @index.configuration, real_nesting, @uri, Location.from_prism_location(node.location, @code_units_cache), @@ -326,6 +327,7 @@ def on_def_node_enter(node) signatures = [Entry::Signature.new(list_params(node.parameters))] @index.add(Entry::Method.new( + @index.configuration, method_name, @uri, location, @@ -340,6 +342,7 @@ def on_def_node_enter(node) singleton = @index.existing_or_new_singleton_class(owner.name) @index.add(Entry::Method.new( + @index.configuration, method_name, @uri, location, @@ -354,6 +357,7 @@ def on_def_node_enter(node) singleton = @index.existing_or_new_singleton_class(owner.name) @index.add(Entry::Method.new( + @index.configuration, method_name, @uri, Location.from_prism_location(node.location, @code_units_cache), @@ -433,6 +437,7 @@ def on_alias_method_node_enter(node) comments = collect_comments(node) @index.add( Entry::UnresolvedMethodAlias.new( + @index.configuration, method_name, node.old_name.slice, @owner_stack.last, @@ -473,6 +478,7 @@ def add_method(name, node_location, signatures, visibility: :public, comments: n location = Location.from_prism_location(node_location, @code_units_cache) @index.add(Entry::Method.new( + @index.configuration, name, @uri, location, @@ -490,6 +496,7 @@ def add_module(name, full_location, name_location, comments: nil) name_loc = Location.from_prism_location(name_location, @code_units_cache) entry = Entry::Module.new( + @index.configuration, Index.actual_nesting(@stack, name), @uri, location, @@ -504,6 +511,7 @@ def add_module(name, full_location, name_location, comments: nil) def add_class(name_or_nesting, full_location, name_location, parent_class_name: nil, comments: nil) nesting = name_or_nesting.is_a?(Array) ? name_or_nesting : Index.actual_nesting(@stack, name_or_nesting) entry = Entry::Class.new( + @index.configuration, nesting, @uri, Location.from_prism_location(full_location, @code_units_cache), @@ -548,6 +556,7 @@ def handle_global_variable(node, loc) comments = collect_comments(node) @index.add(Entry::GlobalVariable.new( + @index.configuration, name, @uri, Location.from_prism_location(loc, @code_units_cache), @@ -572,6 +581,7 @@ def handle_class_variable(node, loc) end @index.add(Entry::ClassVariable.new( + @index.configuration, name, @uri, Location.from_prism_location(loc, @code_units_cache), @@ -594,6 +604,7 @@ def handle_instance_variable(node, loc) end @index.add(Entry::InstanceVariable.new( + @index.configuration, name, @uri, Location.from_prism_location(loc, @code_units_cache), @@ -656,6 +667,7 @@ def handle_alias_method(node) comments = collect_comments(node) @index.add( Entry::UnresolvedMethodAlias.new( + @index.configuration, new_name_value, old_name_value, @owner_stack.last, @@ -675,6 +687,7 @@ def add_constant(node, name, value = nil) case value when Prism::ConstantReadNode, Prism::ConstantPathNode Entry::UnresolvedConstantAlias.new( + @index.configuration, value.slice, @stack.dup, name, @@ -688,6 +701,7 @@ def add_constant(node, name, value = nil) # If the right hand side is another constant assignment, we need to visit it because that constant has to be # indexed too Entry::UnresolvedConstantAlias.new( + @index.configuration, value.name.to_s, @stack.dup, name, @@ -699,6 +713,7 @@ def add_constant(node, name, value = nil) Prism::ConstantPathAndWriteNode Entry::UnresolvedConstantAlias.new( + @index.configuration, value.target.slice, @stack.dup, name, @@ -708,6 +723,7 @@ def add_constant(node, name, value = nil) ) else Entry::Constant.new( + @index.configuration, name, @uri, Location.from_prism_location(node.location, @code_units_cache), @@ -785,6 +801,7 @@ def handle_attribute(node, reader:, writer:) if reader @index.add(Entry::Accessor.new( + @index.configuration, name, @uri, Location.from_prism_location(loc, @code_units_cache), @@ -797,6 +814,7 @@ def handle_attribute(node, reader:, writer:) next unless writer @index.add(Entry::Accessor.new( + @index.configuration, "#{name}=", @uri, Location.from_prism_location(loc, @code_units_cache), @@ -879,6 +897,7 @@ def handle_module_function(node) singleton = @index.existing_or_new_singleton_class(entry_owner_name) location = Location.from_prism_location(argument.location, @code_units_cache) @index.add(Entry::Method.new( + @index.configuration, method_name, @uri, location, diff --git a/lib/ruby_indexer/lib/ruby_indexer/entry.rb b/lib/ruby_indexer/lib/ruby_indexer/entry.rb index bc595a042a..2b61ad4799 100644 --- a/lib/ruby_indexer/lib/ruby_indexer/entry.rb +++ b/lib/ruby_indexer/lib/ruby_indexer/entry.rb @@ -3,6 +3,9 @@ module RubyIndexer class Entry + #: Configuration + attr_reader :configuration + #: String attr_reader :name @@ -17,8 +20,9 @@ class Entry #: Symbol attr_accessor :visibility - #: (String name, URI::Generic uri, Location location, String? comments) -> void - def initialize(name, uri, location, comments) + #: (Configuration configuration, String name, URI::Generic uri, Location location, String? comments) -> void + def initialize(configuration, name, uri, location, comments) + @configuration = configuration @name = name @uri = uri @comments = comments @@ -121,13 +125,13 @@ class Namespace < Entry #: Location attr_reader :name_location - #: (Array[String] nesting, URI::Generic uri, Location location, Location name_location, String? comments) -> void - def initialize(nesting, uri, location, name_location, comments) + #: (Configuration configuration, Array[String] nesting, URI::Generic uri, Location location, Location name_location, String? comments) -> void + def initialize(configuration, nesting, uri, location, name_location, comments) # rubocop:disable Metrics/ParameterLists @name = nesting.join("::") #: String # The original nesting where this namespace was discovered @nesting = nesting - super(@name, uri, location, comments) + super(configuration, @name, uri, location, comments) @name_location = name_location end @@ -160,9 +164,9 @@ class Class < Namespace #: String? attr_reader :parent_class - #: (Array[String] nesting, URI::Generic uri, Location location, Location name_location, String? comments, String? parent_class) -> void - def initialize(nesting, uri, location, name_location, comments, parent_class) # rubocop:disable Metrics/ParameterLists - super(nesting, uri, location, name_location, comments) + #: (Configuration configuration, Array[String] nesting, URI::Generic uri, Location location, Location name_location, String? comments, String? parent_class) -> void + def initialize(configuration, nesting, uri, location, name_location, comments, parent_class) # rubocop:disable Metrics/ParameterLists + super(configuration, nesting, uri, location, name_location, comments) @parent_class = parent_class end @@ -285,9 +289,9 @@ class Member < Entry #: Entry::Namespace? attr_reader :owner - #: (String name, URI::Generic uri, Location location, String? comments, Symbol visibility, Entry::Namespace? owner) -> void - def initialize(name, uri, location, comments, visibility, owner) # rubocop:disable Metrics/ParameterLists - super(name, uri, location, comments) + #: (Configuration configuration, String name, URI::Generic uri, Location location, String? comments, Symbol visibility, Entry::Namespace? owner) -> void + def initialize(configuration, name, uri, location, comments, visibility, owner) # rubocop:disable Metrics/ParameterLists + super(configuration, name, uri, location, comments) @visibility = visibility @owner = owner end @@ -341,9 +345,9 @@ class Method < Member #: Location attr_reader :name_location - #: (String name, URI::Generic uri, Location location, Location name_location, String? comments, Array[Signature] signatures, Symbol visibility, Entry::Namespace? owner) -> void - def initialize(name, uri, location, name_location, comments, signatures, visibility, owner) # rubocop:disable Metrics/ParameterLists - super(name, uri, location, comments, visibility, owner) + #: (Configuration configuration, String name, URI::Generic uri, Location location, Location name_location, String? comments, Array[Signature] signatures, Symbol visibility, Entry::Namespace? owner) -> void + def initialize(configuration, name, uri, location, name_location, comments, signatures, visibility, owner) # rubocop:disable Metrics/ParameterLists + super(configuration, name, uri, location, comments, visibility, owner) @signatures = signatures @name_location = name_location end @@ -366,9 +370,9 @@ class UnresolvedConstantAlias < Entry #: Array[String] attr_reader :nesting - #: (String target, Array[String] nesting, String name, URI::Generic uri, Location location, String? comments) -> void - def initialize(target, nesting, name, uri, location, comments) # rubocop:disable Metrics/ParameterLists - super(name, uri, location, comments) + #: (Configuration configuration, String target, Array[String] nesting, String name, URI::Generic uri, Location location, String? comments) -> void + def initialize(configuration, target, nesting, name, uri, location, comments) # rubocop:disable Metrics/ParameterLists + super(configuration, name, uri, location, comments) @target = target @nesting = nesting @@ -383,6 +387,7 @@ class ConstantAlias < Entry #: (String target, UnresolvedConstantAlias unresolved_alias) -> void def initialize(target, unresolved_alias) super( + unresolved_alias.configuration, unresolved_alias.name, unresolved_alias.uri, unresolved_alias.location, @@ -402,9 +407,9 @@ class ClassVariable < Entry #: Entry::Namespace? attr_reader :owner - #: (String name, URI::Generic uri, Location location, String? comments, Entry::Namespace? owner) -> void - def initialize(name, uri, location, comments, owner) - super(name, uri, location, comments) + #: (Configuration configuration, String name, URI::Generic uri, Location location, String? comments, Entry::Namespace? owner) -> void + def initialize(configuration, name, uri, location, comments, owner) # rubocop:disable Metrics/ParameterLists + super(configuration, name, uri, location, comments) @owner = owner end end @@ -414,9 +419,9 @@ class InstanceVariable < Entry #: Entry::Namespace? attr_reader :owner - #: (String name, URI::Generic uri, Location location, String? comments, Entry::Namespace? owner) -> void - def initialize(name, uri, location, comments, owner) - super(name, uri, location, comments) + #: (Configuration configuration, String name, URI::Generic uri, Location location, String? comments, Entry::Namespace? owner) -> void + def initialize(configuration, name, uri, location, comments, owner) # rubocop:disable Metrics/ParameterLists + super(configuration, name, uri, location, comments) @owner = owner end end @@ -431,9 +436,9 @@ class UnresolvedMethodAlias < Entry #: Entry::Namespace? attr_reader :owner - #: (String new_name, String old_name, Entry::Namespace? owner, URI::Generic uri, Location location, String? comments) -> void - def initialize(new_name, old_name, owner, uri, location, comments) # rubocop:disable Metrics/ParameterLists - super(new_name, uri, location, comments) + #: (Configuration configuration, String new_name, String old_name, Entry::Namespace? owner, URI::Generic uri, Location location, String? comments) -> void + def initialize(configuration, new_name, old_name, owner, uri, location, comments) # rubocop:disable Metrics/ParameterLists + super(configuration, new_name, uri, location, comments) @new_name = new_name @old_name = old_name @@ -456,6 +461,7 @@ def initialize(target, unresolved_alias) full_comments << target.comments super( + unresolved_alias.configuration, unresolved_alias.new_name, unresolved_alias.uri, unresolved_alias.location, diff --git a/lib/ruby_indexer/lib/ruby_indexer/index.rb b/lib/ruby_indexer/lib/ruby_indexer/index.rb index 28293bf314..4cf8895d69 100644 --- a/lib/ruby_indexer/lib/ruby_indexer/index.rb +++ b/lib/ruby_indexer/lib/ruby_indexer/index.rb @@ -714,6 +714,7 @@ def existing_or_new_singleton_class(name) attached_ancestor = self[name]&.first #: as !nil singleton = Entry::SingletonClass.new( + @configuration, [full_singleton_name], attached_ancestor.uri, attached_ancestor.location, diff --git a/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb b/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb index 3cb1eddb56..2f3922bb88 100644 --- a/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb +++ b/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb @@ -52,9 +52,9 @@ def handle_class_or_module_declaration(declaration, pathname) comments = comments_to_string(declaration) entry = if declaration.is_a?(RBS::AST::Declarations::Class) parent_class = declaration.super_class&.name&.name&.to_s - Entry::Class.new(nesting, uri, location, location, comments, parent_class) + Entry::Class.new(@index.configuration, nesting, uri, location, location, comments, parent_class) else - Entry::Module.new(nesting, uri, location, location, comments) + Entry::Module.new(@index.configuration, nesting, uri, location, location, comments) end add_declaration_mixins_to_entry(declaration, entry) @@ -110,6 +110,7 @@ def handle_method(member, owner) real_owner = member.singleton? ? @index.existing_or_new_singleton_class(owner.name) : owner signatures = signatures(member) @index.add(Entry::Method.new( + @index.configuration, name, uri, location, @@ -243,6 +244,7 @@ def process_rest_keywords(function) def handle_constant(declaration, nesting, uri) fully_qualified_name = [*nesting, declaration.name.name.to_s].join("::") @index.add(Entry::Constant.new( + @index.configuration, fully_qualified_name, uri, to_ruby_indexer_location(declaration.location), @@ -258,6 +260,7 @@ def handle_global_variable(declaration, pathname) comments = comments_to_string(declaration) @index.add(Entry::GlobalVariable.new( + @index.configuration, name, uri, location, @@ -271,6 +274,7 @@ def handle_signature_alias(member, owner_entry) comments = comments_to_string(member) entry = Entry::UnresolvedMethodAlias.new( + @index.configuration, member.new_name.to_s, member.old_name.to_s, owner_entry, From d5c5d9294ab2a8f35955bc77131db3d5ae3eb2df Mon Sep 17 00:00:00 2001 From: Thomas Marshall Date: Fri, 28 Nov 2025 16:30:24 +0000 Subject: [PATCH 2/2] Exclude magic comments from documentation This commit ensures magic comments are excluded from documentation. They were already filtered out when eagerly indexing comments but the same logic wasn't applied when lazily loading comments. --- lib/ruby_indexer/lib/ruby_indexer/entry.rb | 2 +- .../test/classes_and_modules_test.rb | 20 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/lib/ruby_indexer/lib/ruby_indexer/entry.rb b/lib/ruby_indexer/lib/ruby_indexer/entry.rb index 2b61ad4799..e5946b9c29 100644 --- a/lib/ruby_indexer/lib/ruby_indexer/entry.rb +++ b/lib/ruby_indexer/lib/ruby_indexer/entry.rb @@ -86,7 +86,7 @@ def comments correct_group.filter_map do |comment| content = comment.slice.chomp - if content.valid_encoding? + if content.valid_encoding? && !content.match?(@configuration.magic_comment_regex) content.delete_prefix!("#") content.delete_prefix!(" ") content diff --git a/lib/ruby_indexer/test/classes_and_modules_test.rb b/lib/ruby_indexer/test/classes_and_modules_test.rb index 6a0ed097e9..349465921f 100644 --- a/lib/ruby_indexer/test/classes_and_modules_test.rb +++ b/lib/ruby_indexer/test/classes_and_modules_test.rb @@ -766,5 +766,25 @@ class Foo FileUtils.rm(path) end end + + def test_lazy_comments_ignores_magic_comments + path = File.join(Dir.pwd, "lib", "foo.rb") + source = <<~RUBY + # frozen_string_literal: true + + class Foo + end + RUBY + File.write(path, source) + @index.index_single(URI::Generic.from_path(path: path), source, collect_comments: false) + + entry = @index["Foo"]&.first #: as !nil + + begin + assert_empty(entry.comments) + ensure + FileUtils.rm(path) + end + end end end