Skip to content

Commit 80b15d4

Browse files
committed
Improve handling of constants that are just aliases
* In the constant summary, link to its target object * When linking from other locations, link directly to the target.
1 parent e167846 commit 80b15d4

File tree

6 files changed

+141
-1
lines changed

6 files changed

+141
-1
lines changed

lib/yard/code_objects/constant_object.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,23 @@ class ConstantObject < Base
1212
def value=(value)
1313
@value = format_source(value)
1414
end
15+
16+
# @return [Base, nil] the target object the constant points to
17+
def target
18+
return @target if instance_variable_defined?(:@target)
19+
20+
if !value.empty? &&
21+
(target = P(namespace, value)) &&
22+
!target.is_a?(YARD::CodeObjects::Proxy) &&
23+
target != self
24+
@target = target
25+
else
26+
@target = nil
27+
end
28+
@target
29+
rescue YARD::Parser::UndocumentableError
30+
# means the value isn't an alias to another object
31+
@target = nil
32+
end
1533
end
1634
end

lib/yard/templates/helpers/html_helper.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,14 @@ def insert_include(text, markup = options.markup)
301301
def link_object(obj, title = nil, anchor = nil, relative = true)
302302
return title if obj.nil?
303303
obj = Registry.resolve(object, obj, true, true) if obj.is_a?(String)
304+
305+
# Re-link references to constants that are aliases to their target. But keep
306+
# their current title.
307+
while obj.is_a?(CodeObjects::ConstantObject) && obj.target
308+
title ||= h(obj.title)
309+
obj = obj.target
310+
end
311+
304312
if title
305313
title = title.to_s
306314
elsif object.is_a?(CodeObjects::Base)
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# frozen_string_literal: true
2+
require File.dirname(__FILE__) + '/spec_helper'
3+
4+
RSpec.describe YARD::CodeObjects::ConstantObject do
5+
before do
6+
Registry.clear
7+
end
8+
9+
describe "#target" do
10+
it "resolves" do
11+
const1 = ConstantObject.new(:root, :A)
12+
const2 = ConstantObject.new(:root, :B)
13+
const2.value = "A"
14+
expect(const2.target).to eq const1
15+
end
16+
17+
it "returns nil for an integer value" do
18+
const = ConstantObject.new(:root, :A)
19+
const.value = "1"
20+
expect(const.target).to be_nil
21+
end
22+
23+
it "returns nil for a string value" do
24+
const = ConstantObject.new(:root, :A)
25+
const.value = '"String"'
26+
expect(const.target).to be_nil
27+
end
28+
29+
it "returns nil for an empty value" do
30+
const = ConstantObject.new(:root, :A)
31+
const.value = ""
32+
expect(const.target).to be_nil
33+
end
34+
35+
it "returns nil for an explicit self-referential constant" do
36+
const = ConstantObject.new(:root, :A)
37+
const.value = "A"
38+
expect(const.target).to be_nil
39+
end
40+
41+
it "returns nil for an explicit self-referential constant" do
42+
mod = ModuleObject.new(:root, :M)
43+
const = ConstantObject.new(mod, :A)
44+
const.value = "self"
45+
expect(const.target).to be_nil
46+
end
47+
end
48+
end
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<h1>Module: A
2+
3+
4+
5+
</h1>
6+
<div class="box_info">
7+
8+
9+
10+
11+
12+
13+
14+
15+
16+
17+
18+
<dl>
19+
<dt>Defined in:</dt>
20+
<dd>(stdin)</dd>
21+
</dl>
22+
23+
</div>
24+
25+
<h2>Overview</h2><div class="docstring">
26+
<div class="discussion">
27+
Checkout A::BAR
28+
29+
</div>
30+
</div>
31+
<div class="tags">
32+
33+
34+
</div>
35+
36+
<h2>
37+
Constant Summary
38+
<small><a href="#" class="constants_summary_toggle">collapse</a></small>
39+
</h2>
40+
41+
<dl class="constants">
42+
43+
<dt id="FOO-constant" class="">FOO =
44+
45+
</dt>
46+
<dd><pre class="code">1</pre></dd>
47+
48+
<dt id="BAR-constant" class="">BAR =
49+
50+
</dt>
51+
<dd>FOO</dd>
52+
53+
</dl>
54+

spec/templates/module_spec.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,4 +200,16 @@ module A
200200
eof
201201
html_equals(Registry.at('A').format(html_options), :module005)
202202
end
203+
204+
it "renders constants that are aliases as links in html" do
205+
Registry.clear
206+
YARD.parse_string <<~RUBY
207+
# Checkout {BAR}
208+
module A
209+
FOO = 1
210+
BAR = FOO
211+
end
212+
RUBY
213+
html_equals(Registry.at('A').format(html_options), :module006)
214+
end
203215
end

templates/default/module/html/constant_summary.erb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
<dt id="<%= anchor_for(cnst) %>" class="<%= cnst.has_tag?(:deprecated) ? 'deprecated' : '' %>"><%= cnst.name %> =
1111
<%= yieldall :object => cnst %>
1212
</dt>
13-
<dd><pre class="code"><%= format_constant cnst.value %></pre></dd>
13+
<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>
1414
<% end %>
1515
</dl>
1616
<% end %>

0 commit comments

Comments
 (0)