Skip to content

Commit

Permalink
Improve handling of constants that are just aliases
Browse files Browse the repository at this point in the history
 * In the constant summary, link to its target object
 * When linking from other locations, link directly to the
   target.
  • Loading branch information
ccutrer committed Nov 14, 2022
1 parent e167846 commit e4ef2da
Show file tree
Hide file tree
Showing 6 changed files with 144 additions and 1 deletion.
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

0 comments on commit e4ef2da

Please sign in to comment.