Skip to content

Commit 816b171

Browse files
authored
Warn when referencing functions/callbacks/types from filtered out modules (#1824)
1 parent 7fd5238 commit 816b171

File tree

5 files changed

+88
-24
lines changed

5 files changed

+88
-24
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
* Support `m:SomeModule` for explicitly linking to a module
1313
* Add `noindex` meta tag to 404 and Search pages
1414
* Move search to the main content so we can display more results
15+
* Warn when referencing functions, types, and callbacks from filtered out modules
1516

1617
* Bug fixes
1718
* Fix search for words with hyphens in them

lib/ex_doc/autolink.ex

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,23 @@ defmodule ExDoc.Autolink do
8787
nil
8888
end
8989

90+
defp string_app_module_url(string, tool, module, anchor, config) do
91+
if Enum.any?(config.filtered_modules, &(&1.module == module)) do
92+
# TODO: Remove on Elixir v1.14
93+
prefix =
94+
if unquote(Version.match?(System.version(), ">= 1.14.0")) do
95+
""
96+
else
97+
~s|"#{string}" |
98+
end
99+
100+
warn(config, prefix <> "reference to a filtered module")
101+
nil
102+
else
103+
app_module_url(tool, module, anchor, config)
104+
end
105+
end
106+
90107
# TODO: make more generic
91108
@doc false
92109
def ex_doc_app_url(module, config, path, ext, suffix) do
@@ -260,7 +277,7 @@ defmodule ExDoc.Autolink do
260277

261278
case {mode, Refs.get_visibility(ref)} do
262279
{_link_type, visibility} when visibility in [:public, :limited] ->
263-
app_module_url(tool(module, config), module, anchor, config)
280+
string_app_module_url(string, tool(module, config), module, anchor, config)
264281

265282
{:regular_link, :undefined} ->
266283
nil
@@ -468,7 +485,8 @@ defmodule ExDoc.Autolink do
468485
if same_module? do
469486
fragment(tool, kind, name, arity)
470487
else
471-
app_module_url(tool, module, config) <> fragment(tool, kind, name, arity)
488+
url = string_app_module_url(original_text, tool, module, nil, config)
489+
url && url <> fragment(tool, kind, name, arity)
472490
end
473491

474492
{:regular_link, module_visibility, :undefined}

lib/ex_doc/language/elixir.ex

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -663,16 +663,12 @@ defmodule ExDoc.Language.Elixir do
663663
(\(.*\)) # Arguments <rest />
664664
}x
665665

666-
Regex.replace(regex, string, fn all, call_string, module_string, name_string, rest ->
666+
Regex.replace(regex, string, fn _all, call_string, module_string, name_string, rest ->
667667
module = string_to_module(module_string)
668668
name = String.to_atom(name_string)
669669
arity = count_args(rest, 0, 0)
670670
original_text = call_string <> "()"
671671

672-
if Enum.any?(config.filtered_modules, &(&1.id == module_string)) do
673-
Autolink.warn(config, "typespec references filtered module: #{all}")
674-
end
675-
676672
url =
677673
if module do
678674
Autolink.remote_url({:type, module, name, arity}, config, original_text)

test/ex_doc/language/elixir_test.exs

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
defmodule ExDoc.Language.ElixirTest do
22
# ExDoc.Refs is global
33
use ExUnit.Case, async: false
4-
54
doctest ExDoc.Autolink
65

76
describe "autolink_doc/2" do
@@ -36,21 +35,14 @@ defmodule ExDoc.Language.ElixirTest do
3635
end
3736

3837
test "project-local module" do
39-
ExDoc.Refs.insert([
40-
{{:module, AutolinkTest.Foo}, :public}
41-
])
42-
43-
assert autolink_doc("`AutolinkTest.Foo`") ==
44-
~s|<a href="AutolinkTest.Foo.html"><code class="inline">AutolinkTest.Foo</code></a>|
38+
assert autolink_doc("`ExDoc.Markdown`") ==
39+
~s|<a href="ExDoc.Markdown.html"><code class="inline">ExDoc.Markdown</code></a>|
4540

46-
assert autolink_doc("`m:AutolinkTest.Foo`") ==
47-
~s|<a href="AutolinkTest.Foo.html"><code class="inline">AutolinkTest.Foo</code></a>|
41+
assert autolink_doc("`m:ExDoc.Markdown`") ==
42+
~s|<a href="ExDoc.Markdown.html"><code class="inline">ExDoc.Markdown</code></a>|
4843

4944
assert autolink_doc("`String`", apps: [:elixir]) ==
5045
~s|<a href="String.html"><code class="inline">String</code></a>|
51-
52-
assert autolink_doc("`AutolinkTest.Foo`", current_module: AutolinkTest.Foo) ==
53-
~s|<a href="AutolinkTest.Foo.html#content"><code class="inline">AutolinkTest.Foo</code></a>|
5446
end
5547

5648
test "remote function" do
@@ -564,14 +556,35 @@ defmodule ExDoc.Language.ElixirTest do
564556
assert autolink_doc("[text](`t:supervisor.child_spec/0`)", opts) == "text"
565557
end) =~ ~s|documentation references "t:supervisor.child_spec/0" but it is invalid|
566558

559+
## filtered_modules
560+
567561
assert warn(fn ->
568-
autolink_spec(quote(do: t() :: String.bad()), opts)
569-
end) =~ ~s|documentation references type "String.bad()"|
562+
opts = opts ++ [filtered_modules: [%ExDoc.ModuleNode{module: String}]]
563+
564+
assert autolink_doc("`String`", opts) ==
565+
~s|<code class="inline">String</code>|
566+
end) =~ "reference to a filtered module"
570567

571568
assert warn(fn ->
572-
opts = opts ++ [filtered_modules: [%ExDoc.ModuleNode{id: "String"}]]
569+
opts = opts ++ [filtered_modules: [%ExDoc.ModuleNode{module: String}]]
570+
571+
assert autolink_doc("`String.upcase/1`", opts) ==
572+
~s|<code class="inline">String.upcase/1</code>|
573+
end) =~ "reference to a filtered module"
574+
575+
assert warn(fn ->
576+
opts = opts ++ [filtered_modules: [%ExDoc.ModuleNode{module: String}]]
577+
578+
assert autolink_doc("`t:String.t/0`", opts) ==
579+
~s|<code class="inline">t:String.t/0</code>|
580+
end) =~ "reference to a filtered module"
581+
582+
assert warn(fn ->
583+
opts = opts ++ [filtered_modules: [%ExDoc.ModuleNode{module: String}]]
573584
autolink_spec(quote(do: t() :: String.t()), opts)
574-
end) == "typespec references filtered module: String.t()"
585+
end) =~ "reference to a filtered module"
586+
587+
## typespecs
575588

576589
assert warn(fn ->
577590
autolink_spec(
@@ -640,7 +653,7 @@ defmodule ExDoc.Language.ElixirTest do
640653
## Helpers
641654

642655
@default_options [
643-
apps: [:myapp],
656+
apps: [:ex_doc],
644657
current_module: MyModule,
645658
module_id: "MyModule",
646659
file: "nofile",

test/ex_doc/language/erlang_test.exs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,24 @@ defmodule ExDoc.Language.ErlangTest do
192192
assert autolink_edoc("{@link //foo}", c) == ~s|<code>//foo</code>|
193193
end) =~ ~s|invalid reference: foo:index|
194194
end
195+
196+
test "filtered module", c do
197+
opts = [filtered_modules: [%ExDoc.ModuleNode{module: :lists, id: "lists"}]]
198+
199+
assert warn(fn ->
200+
assert autolink_edoc("{@link lists}", c, opts) ==
201+
~s|<code>lists</code>|
202+
end) == "reference to a filtered module"
203+
end
204+
205+
test "filtered module function", c do
206+
opts = [filtered_modules: [%ExDoc.ModuleNode{module: :lists, id: "lists"}]]
207+
208+
assert warn(fn ->
209+
assert autolink_edoc("{@link lists:all/2}", c, opts) ==
210+
~s|<code>lists:all/2</code>|
211+
end) == "reference to a filtered module"
212+
end
195213
end
196214

197215
describe "autolink_doc/2 for markdown" do
@@ -426,6 +444,24 @@ defmodule ExDoc.Language.ErlangTest do
426444
line: nil
427445
) =~ ~r/documentation references "e:extra.md" but it is invalid/
428446
end
447+
448+
test "filtered module", c do
449+
opts = [filtered_modules: [%ExDoc.ModuleNode{module: :lists, id: "lists"}]]
450+
451+
assert warn(fn ->
452+
assert autolink_doc("`m:lists`", c, opts) ==
453+
~s|<code class="inline">m:lists</code>|
454+
end) =~ "reference to a filtered module"
455+
end
456+
457+
test "filtered module callback", c do
458+
opts = [filtered_modules: [%ExDoc.ModuleNode{module: :gen_server, id: "gen_server"}]]
459+
460+
assert warn(fn ->
461+
assert autolink_doc("`c:gen_server:handle_call/3`", c, opts) ==
462+
~s|<code class="inline">c:gen_server:handle_call/3</code>|
463+
end) =~ "reference to a filtered module"
464+
end
429465
end
430466

431467
describe "autolink_doc/2 for extra" do

0 commit comments

Comments
 (0)