Skip to content

Fix broken sidebar links for chained class aliases#1675

Open
st0012 wants to merge 1 commit intomasterfrom
fix-chained-alias-nav-link
Open

Fix broken sidebar links for chained class aliases#1675
st0012 wants to merge 1 commit intomasterfrom
fix-chained-alias-nav-link

Conversation

@st0012
Copy link
Copy Markdown
Member

@st0012 st0012 commented Apr 6, 2026

Summary

  • Fixes broken sidebar links when class aliases chain through other aliases (e.g., HTTPRequestURITooLarge = HTTPRequestURITooLong = HTTPURITooLong in net/http)
  • The outermost alias's sidebar link pointed to the intermediate alias's HTML file, which is never generated since aliases don't get their own pages
  • Resolve the alias chain in update_aliases by looking up the current store entry to follow already-processed aliases back to the real class
  • Also make name_for_path follow the chain recursively as a defensive measure

Fixes #1664

@matzbot
Copy link
Copy Markdown
Collaborator

matzbot commented Apr 6, 2026

🚀 Preview deployment available at: https://7bedae16.rdoc-6cd.pages.dev (commit: de9f6ac)

@st0012 st0012 marked this pull request as ready for review April 9, 2026 17:10
@st0012 st0012 requested a review from Copilot April 9, 2026 17:10
@st0012 st0012 added the bug label Apr 9, 2026
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes broken Darkfish sidebar links for class/module aliases when aliases chain through other aliases (e.g., A = B = C) by ensuring navigation URLs resolve to the underlying real class/module page (since alias pages are not generated).

Changes:

  • Make RDoc::ClassModule#name_for_path follow alias chains recursively.
  • Resolve chained class/module aliases to the real target during RDoc::ClassModule#update_aliases.
  • Add a Darkfish generator test intended to reproduce #1664.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
lib/rdoc/code_object/class_module.rb Resolve alias chains when computing paths and when updating constant aliases in the store.
test/rdoc/generator/darkfish_test.rb Adds a regression test for sidebar links involving chained aliases.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +624 to +637
direct_alias_const = RDoc::Constant.new 'DirectAlias', nil, ''
direct_alias_const.record_location @top_level
direct_alias_const.is_alias_for = original
parent.add_constant direct_alias_const
parent.update_aliases

direct_alias = @store.find_class_or_module 'Parent::DirectAlias'

chained_alias_const = RDoc::Constant.new 'ChainedAlias', nil, ''
chained_alias_const.record_location @top_level
chained_alias_const.is_alias_for = direct_alias
parent.add_constant chained_alias_const
parent.update_aliases

Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test setup doesn’t closely match the production code path that triggered #1664: here ChainedAlias is set to alias an already-processed store entry (direct_alias), so it primarily exercises the cm = cm.is_alias_for while ... part, but not the new @store.find_class_or_module(cm.full_name) lookup that’s intended to resolve a chain when const.is_alias_for still points at the pre-update_aliases placeholder object for the intermediate alias.

Consider restructuring to add both alias constants before a single parent.update_aliases (or using Context#add_module_alias to build DirectAlias/ChainedAlias the way the parser does) and ensure ChainedAlias initially aliases the intermediate non-alias object, so this test fails if the store-lookup chain resolution regresses.

Copilot uses AI. Check for mistakes.
Comment on lines +854 to +855
cm = cm.is_alias_for while cm.is_alias_for

Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cm = cm.is_alias_for while cm.is_alias_for calls is_alias_for twice per loop iteration (once for the condition, once for the assignment). Consider rewriting this loop to only evaluate is_alias_for once per iteration for clarity and to avoid redundant calls.

Suggested change
cm = cm.is_alias_for while cm.is_alias_for
while (next_cm = cm.is_alias_for)
cm = next_cm
end

Copilot uses AI. Check for mistakes.
When Ruby defines chained aliases like `A = B = C` (e.g.,
`HTTPRequestURITooLarge = HTTPRequestURITooLong = HTTPURITooLong`
in net/http), the sidebar link for the outermost alias pointed to
the intermediate alias's HTML file, which is never generated.

The root cause: `update_aliases` creates ClassModule objects whose
`is_alias_for` references stale intermediate objects from
`add_module_alias` that don't know they are aliases. Resolve through
the store to follow already-processed aliases back to the real class.

Also make `name_for_path` follow the alias chain recursively as a
defensive measure.

Fixes #1664.
@st0012 st0012 force-pushed the fix-chained-alias-nav-link branch from 9e7ccd1 to de9f6ac Compare April 9, 2026 20:55
Copy link
Copy Markdown
Member

@kou kou left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Broken link in class nav

4 participants