-
Notifications
You must be signed in to change notification settings - Fork 351
[WIP] Autolink revamp - Round 2 #896
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
[WIP] Autolink revamp - Round 2 #896
Conversation
|
||
defp re(:f, :erlang) do | ||
~r{ | ||
# TODO: revise the erlang rules for function names |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO found
defp re(:m, :erlang) do | ||
~r{ | ||
: # prefix | ||
# TODO: revise the erlang rules for module names |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO found
""" | ||
|
||
refute Autolink.preprocess(string) === string | ||
assert Autolink.preprocess(string) |> Autolink.postprocess() === string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use a function call when a pipeline is only one function long
@doc false | ||
# The heart of the autolinking logic | ||
@spec replacement(String.t(), language, kind, String.t(), keyword) :: String.t() | ||
def replacement(string, language, kind, match, text \\ nil, options) do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Function is too complex (CC is 21, max is 9).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this function public too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sorry I forgot to make it private
end | ||
|
||
:function -> | ||
cond do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Function body is nested too deep (max depth is 2, was 3).
a0fb3b0
to
098481a
Compare
# with a token | ||
@doc false | ||
@spec link(String.t(), language, kind, keyword) :: String.t() | ||
def link(string, language, kind, options) do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this function public?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
forgot to make it private
|> link_process(:preprocess, options[:preprocess?]) | ||
|> link(language, kind, :custom, options) | ||
|> link(language, kind, :normal, options) | ||
|> link_process(:postprocess, options[:preprocess?]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wrong option here. It seems we do not have tests for this then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, what is wrong here?
end | ||
|
||
term | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove debugging code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
end | ||
|
||
@doc false | ||
# Replaces all backticks inside the text of custom links with @backtick_token. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did we do pre-processing before? Why do we need it now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We didn't. But it fixes the bug of linking inside the custom text. Before it was only working if either the opening backtick is touching the opening bracket, or the closing backtick is touching the closing bracket.
This wouldn't pass before IIRC.
assert Autolink.erlang_functions("[the `:erlang.apply/2` function](other.html)") ==
"[the `:erlang.apply/2` function](other.html)"
So this behaviour was inconsistent. I think it worked for local and Elixir functions and it didn't work for the rest
module_id: module_id, | ||
locals: locals | ||
}) | ||
|> Map.to_list() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like that we are converting structured list into unstructured one. My suggestion is to keep using a map internally everywhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
case link_type do | ||
:normal -> | ||
fn all, match -> | ||
replacement(all, language, kind, match, options) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should merge replace_fun
and replacement
such that replace_fun
already returns a function considering the link_type
, language
and kind
. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, but after splitting replacement
into two functions clauses I cannot see how to merge it with replace_fun
I ended up having something like this
defp replace_fun(language, kind, :normal, options) do
fn all, match ->
replacement(all, language, kind, match, options)
end
end
defp replace_fun(language, kind, :custom, options) do
fn all, text, match ->
replacement(all, language, kind, match, text, options)
end
end
# The heart of the autolinking logic
defp replacement(string, language, kind, match, text \\ nil, options)
defp replacement(string, :erlang, kind, match, text, options) do
lib_dirs = Map.get(options, :lib_dirs, default_lib_dirs(:erlang))
pmfa = {_prefix, module, function, arity} = split_function(match)
text = text || default_text(:erlang, kind, match, pmfa)
if doc = module_docs(:erlang, module, lib_dirs) do
case kind do
:module ->
"[#{text}](#{doc}#{module}.html)"
:function ->
"[#{text}](#{doc}#{module}.html##{function}-#{arity})"
end
else
string
end
end
defp replacement(string, :elixir, kind, match, text, options) do
aliases = Map.get(options, :aliases, [])
docs_refs = Map.get(options, :docs_refs, [])
extension = Map.get(options, :extension, ".html")
lib_dirs = Map.get(options, :lib_dirs, default_lib_dirs(:elixir))
locals = Map.get(options, :locals, [])
module_id = Map.get(options, :module_id, nil)
modules_refs = Map.get(options, :modules_refs, [])
pmfa = {prefix, module, function, arity} = split_function(match)
text = text || default_text(:elixir, kind, match, pmfa)
elixir_docs = get_elixir_docs(aliases, lib_dirs)
case kind do
:module ->
cond do
match == module_id ->
"[`#{match}`](#{match}#{extension}#content)"
match in modules_refs ->
"[`#{match}`](#{match}#{extension})"
doc = module_docs(:elixir, match, lib_dirs) ->
"[`#{match}`](#{doc}#{match}.html)"
true ->
string
end
:function ->
cond do
match in locals ->
"[#{text}](##{prefix}#{enc_h(function)}/#{arity})"
match in docs_refs ->
"[#{text}](#{module}#{extension}##{prefix}#{enc_h(function)}/#{arity})"
match in @basic_type_strings ->
"[#{text}](#{elixir_docs}#{@basic_types_page})"
match in @built_in_type_strings ->
"[#{text}](#{elixir_docs}#{@built_in_types_page})"
match in @kernel_function_strings ->
"[#{text}](#{elixir_docs}Kernel#{extension}##{prefix}#{enc_h(function)}/#{arity})"
match in @special_form_strings ->
"[#{text}](#{elixir_docs}Kernel.SpecialForms#{extension}##{prefix}#{enc_h(function)}/#{
arity
})"
doc = module_docs(:elixir, module, lib_dirs) ->
"[#{text}](#{doc}#{module}.html##{prefix}#{enc_h(function)}/#{arity})"
true ->
string
end
end
Thanks @eksperimental! I have reviewed the code and now I can see with more clarity the improvements it brings. However, I still believe we have some extra work to do. In particular, I think the |
098481a
to
b7a264a
Compare
|
||
@doc """ | ||
Helper function for autolinking elixir modules. | ||
defp replacement(string, :elixir, kind, match, text, options) do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Function is too complex (CC is 16, max is 9).
Ebert has finished reviewing this Pull Request and has found:
You can see more details about this review at https://ebertapp.io/github/elixir-lang/ex_doc/pulls/896. |
@josevalim thank you for reviewing my code. I have implemented all the changes you suggested, except here and here |
❤️ 💚 💙 💛 💜 |
@eksperimental I have applied the Note I have also removed preprocess/postprocess, because they are testing implementation details and not behaviour. Namely, we don't care how we handle the backticks, as long as we handle it correctly, and that's what we need to test. I believe now we can do the second part of your PR which is to rewrite the tests. Basically, right now we are testing elixir_functions, locals and so on, but the code does not actually call any of those functions. I think we need to change all of the Autolink tests to go exclusively through |
The tests for the preprocess/postprocess were there because I found bugs in my previous code. I will go through your commit whenever I getg some free time and get back if I have any comments. |
@wojtekmach great find! |
I agree!
--
*José Valimwww.plataformatec.com.br
<http://www.plataformatec.com.br/>Founder and Director of R&D*
|
ok. let's here from others and I will provide a PR as soon as possible |
@eksperimental sweet. what do you have in mind? instead of a for comprehensions that builds |
Pushed in 75d32db. |
Great, thanks everyone! |
Round 1 is here: [WIP] Autolink revamp #893
This PR doesn't change the API as requested by @josevalim in #893 (comment)