Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve handling of constants that are just aliases #1466

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions lib/yard/code_objects/constant_object.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,23 @@ class ConstantObject < Base
def value=(value)
@value = format_source(value)
end

# @return [Base, nil] the target object the constant points to
def target
return @target if instance_variable_defined?(:@target)

if !value.empty? &&
(target = P(namespace, value)) &&
!target.is_a?(YARD::CodeObjects::Proxy) &&
target != self
@target = target
else
@target = nil
end
@target
rescue YARD::Parser::UndocumentableError
# means the value isn't an alias to another object
@target = nil
end
end
end
11 changes: 11 additions & 0 deletions lib/yard/templates/helpers/html_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,17 @@ def insert_include(text, markup = options.markup)
def link_object(obj, title = nil, anchor = nil, relative = true)
return title if obj.nil?
obj = Registry.resolve(object, obj, true, true) if obj.is_a?(String)

was_const = false
# Re-link references to constants that are aliases to their target. But keep
# their current title.
while obj.is_a?(CodeObjects::ConstantObject) && obj.target
title ||= h(object.relative_path(obj)).to_s
was_const = true
obj = obj.target
end
return link_object(obj, title, anchor, relative) if was_const

if title
title = title.to_s
elsif object.is_a?(CodeObjects::Base)
Expand Down
48 changes: 48 additions & 0 deletions spec/code_objects/constant_object_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# frozen_string_literal: true
require File.dirname(__FILE__) + '/spec_helper'

RSpec.describe YARD::CodeObjects::ConstantObject do
before do
Registry.clear
end

describe "#target" do
it "resolves" do
const1 = ConstantObject.new(:root, :A)
const2 = ConstantObject.new(:root, :B)
const2.value = "A"
expect(const2.target).to eq const1
end

it "returns nil for an integer value" do
const = ConstantObject.new(:root, :A)
const.value = "1"
expect(const.target).to be_nil
end

it "returns nil for a string value" do
const = ConstantObject.new(:root, :A)
const.value = '"String"'
expect(const.target).to be_nil
end

it "returns nil for an empty value" do
const = ConstantObject.new(:root, :A)
const.value = ""
expect(const.target).to be_nil
end

it "returns nil for an explicit self-referential constant" do
const = ConstantObject.new(:root, :A)
const.value = "A"
expect(const.target).to be_nil
end

it "returns nil for an explicit self-referential constant" do
mod = ModuleObject.new(:root, :M)
const = ConstantObject.new(mod, :A)
const.value = "self"
expect(const.target).to be_nil
end
end
end
54 changes: 54 additions & 0 deletions spec/templates/examples/module006.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<h1>Module: A



</h1>
<div class="box_info">











<dl>
<dt>Defined in:</dt>
<dd>(stdin)</dd>
</dl>

</div>

<h2>Overview</h2><div class="docstring">
<div class="discussion">
Checkout BAR

</div>
</div>
<div class="tags">


</div>

<h2>
Constant Summary
<small><a href="#" class="constants_summary_toggle">collapse</a></small>
</h2>

<dl class="constants">

<dt id="FOO-constant" class="">FOO =

</dt>
<dd><pre class="code">1</pre></dd>

<dt id="BAR-constant" class="">BAR =

</dt>
<dd>FOO</dd>

</dl>

12 changes: 12 additions & 0 deletions spec/templates/module_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -200,4 +200,16 @@ module A
eof
html_equals(Registry.at('A').format(html_options), :module005)
end

it "renders constants that are aliases as links in html" do
Registry.clear
YARD.parse_string <<~RUBY
# Checkout {BAR}
module A
FOO = 1
BAR = FOO
end
RUBY
html_equals(Registry.at('A').format(html_options), :module006)
end
end
2 changes: 1 addition & 1 deletion templates/default/module/html/constant_summary.erb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<dt id="<%= anchor_for(cnst) %>" class="<%= cnst.has_tag?(:deprecated) ? 'deprecated' : '' %>"><%= cnst.name %> =
<%= yieldall :object => cnst %>
</dt>
<dd><pre class="code"><%= format_constant cnst.value %></pre></dd>
<dd><% if cnst.is_a?(YARD::CodeObjects::ConstantObject) && cnst.target %><%= linkify(cnst.target, cnst.value) %><% else %><pre class="code"><%= format_constant cnst.value %></pre><% end %></dd>
<% end %>
</dl>
<% end %>
Expand Down