Skip to content

Commit ecd479f

Browse files
committed
Clean up stale comment_location placeholders after re-parse
When keep_position: true is used during server re-parse, empty placeholder entries persist in comment_location if the re-parsed file no longer defines that class. Add Store#cleanup_stale_contributions to remove empty entries and stale in_files references after all re-parsing is complete. If a class has no remaining contributions, it is removed from the store.
1 parent 9511fd0 commit ecd479f

File tree

3 files changed

+80
-0
lines changed

3 files changed

+80
-0
lines changed

lib/rdoc/server.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,8 @@ def reparse_and_refresh(changed_files, removed_files)
363363
$stderr.puts "Error parsing #{f}: #{e.message}"
364364
end
365365
end
366+
367+
@store.cleanup_stale_contributions
366368
end
367369

368370
@store.complete(@options.visibility)

lib/rdoc/store.rb

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,35 @@ def clear_file_contributions(relative_name, keep_position: false)
279279
top_level.classes_or_modules.clear
280280
end
281281

282+
##
283+
# Removes stale empty placeholders left by +clear_file_contributions+ with
284+
# <tt>keep_position: true</tt>. After re-parsing, a file may no longer
285+
# define a class it previously contributed to, leaving an empty entry in
286+
# +comment_location+ and a stale +in_files+ reference. Call this after
287+
# all re-parsing is complete.
288+
289+
def cleanup_stale_contributions
290+
all_classes_and_modules.each do |cm|
291+
cm.comment_location.delete_if { |_, comments| comments.empty? }
292+
cm.rebuild_comment_from_location
293+
294+
cm.in_files.select! { |tl| cm.comment_location.key?(tl) ||
295+
cm.method_list.any? { |m| m.file == tl } ||
296+
cm.attributes.any? { |a| a.file == tl } ||
297+
cm.constants.any? { |c| c.file == tl } }
298+
299+
if cm.in_files.empty?
300+
if cm.is_a?(RDoc::NormalModule)
301+
@modules_hash.delete(cm.full_name)
302+
else
303+
@classes_hash.delete(cm.full_name)
304+
end
305+
cm.parent&.classes_hash&.delete(cm.name)
306+
cm.parent&.modules_hash&.delete(cm.name)
307+
end
308+
end
309+
end
310+
282311
##
283312
# Make sure any references to C variable names are resolved to the corresponding class.
284313
#

test/rdoc/rdoc_store_test.rb

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1255,4 +1255,53 @@ def test_clear_file_contributions_keep_position
12551255
assert_equal 'updated comment from a', klass.comment_location[file_a].first.to_s
12561256
end
12571257

1258+
def test_cleanup_stale_comment_locations
1259+
file_a = @s.add_file 'a.rb'
1260+
file_b = @s.add_file 'b.rb'
1261+
1262+
klass = file_a.add_class RDoc::NormalClass, 'StaleClass'
1263+
klass.record_location file_a
1264+
klass.record_location file_b
1265+
file_a.add_to_classes_or_modules klass
1266+
file_b.add_to_classes_or_modules klass
1267+
1268+
klass.add_comment 'comment from a', file_a
1269+
klass.add_comment 'comment from b', file_b
1270+
1271+
# Simulate keep_position clearing followed by re-parse that no longer
1272+
# defines StaleClass in a.rb (no add_comment called for file_a)
1273+
@s.clear_file_contributions 'a.rb', keep_position: true
1274+
1275+
# Stale placeholder exists
1276+
assert_equal [], klass.comment_location[file_a]
1277+
1278+
# Cleanup should remove the stale entry
1279+
@s.cleanup_stale_contributions
1280+
1281+
assert_not_include klass.comment_location.keys, file_a
1282+
assert_not_include klass.in_files, file_a
1283+
assert_includes klass.comment_location.keys, file_b
1284+
assert_includes klass.in_files, file_b
1285+
end
1286+
1287+
def test_cleanup_stale_contributions_removes_empty_class
1288+
file_a = @s.add_file 'a.rb'
1289+
1290+
klass = file_a.add_class RDoc::NormalClass, 'GoneClass'
1291+
klass.record_location file_a
1292+
file_a.add_to_classes_or_modules klass
1293+
1294+
klass.add_comment 'comment from a', file_a
1295+
1296+
@s.clear_file_contributions 'a.rb', keep_position: true
1297+
1298+
# Stale placeholder exists, class still in store
1299+
assert_includes @s.classes_hash, 'GoneClass'
1300+
1301+
@s.cleanup_stale_contributions
1302+
1303+
# Class should be removed from store
1304+
assert_not_include @s.classes_hash, 'GoneClass'
1305+
end
1306+
12581307
end

0 commit comments

Comments
 (0)