Skip to content

Commit 9dc8af5

Browse files
authored
Fix doc false for folding ranges (#580)
* Fix doc false for folding ranges Previously an invalid folding range would be returned * Formatting * Update changelog * handle `@typedoc false` also
1 parent 0be17f3 commit 9dc8af5

File tree

3 files changed

+92
-15
lines changed

3 files changed

+92
-15
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Bug Fixes:
1313
- Support exunit describe and test calls with unevaluated names (thanks [Jonathan Arnett](https://github.com/J3RN)) [#537](https://github.com/elixir-lsp/elixir-ls/pull/537)
1414
- Improve test runner to use exunit testPaths and testPattern (thanks [Étienne Lévesque](https://github.com/Blond11516)) [#500](https://github.com/elixir-lsp/elixir-ls/pull/500)
1515
- Fix race-condition in suggest contracts (thanks [Łukasz Samson](https://github.com/lukaszsamson)) [#544](https://github.com/elixir-lsp/elixir-ls/pull/544)
16+
- Fix `@doc false` and `@moduledoc false` for folding ranges (thanks [Jason Axelson](https://github.com/axelson/)) [#580](https://github.com/elixir-lsp/elixir-ls/pull/580)
1617

1718
Housekeeping:
1819
- Minor iteration/performance improvements (thanks [Andrew Summers](https://github.com/asummers)) [#527](https://github.com/elixir-lsp/elixir-ls/pull/527)

apps/language_server/lib/language_server/providers/folding_range/special_token.ex

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ defmodule ElixirLS.LanguageServer.Providers.FoldingRange.SpecialToken do
1818
:sigil
1919
]
2020

21+
@docs [:moduledoc, :typedoc, :doc]
22+
2123
@doc """
2224
Provides ranges based on "special" tokens
2325
@@ -55,23 +57,46 @@ defmodule ElixirLS.LanguageServer.Providers.FoldingRange.SpecialToken do
5557

5658
@spec group_tokens([Token.t()]) :: [[Token.t()]]
5759
defp group_tokens(tokens) do
58-
tokens
59-
|> Enum.reduce([], fn
60-
{:identifier, _, identifier} = token, acc when identifier in [:doc, :moduledoc] ->
61-
[[token] | acc]
60+
do_group_tokens(tokens, [])
61+
end
6262

63-
{k, _, _} = token, [[{:identifier, _, _}] = head | tail] when k in @kinds ->
64-
[[token | head] | tail]
63+
defp do_group_tokens([], acc), do: acc
6564

66-
{k, _, _} = token, acc when k in @kinds ->
67-
[[token] | acc]
65+
# Don't create folding ranges for docs
66+
defp do_group_tokens([{:identifier, _, doc_identifier}, {false, _, _} | rest], acc)
67+
when doc_identifier in @docs do
68+
do_group_tokens(rest, acc)
69+
end
6870

69-
{:eol, _, _} = token, [[{k, _, _} | _] = head | tail] when k in @kinds ->
70-
[[token | head] | tail]
71+
# Start a folding range for `@doc` and `@moduledoc`
72+
defp do_group_tokens([{:identifier, _, doc_identifier} = token | rest], acc)
73+
when doc_identifier in @docs do
74+
acc = [[token] | acc]
75+
do_group_tokens(rest, acc)
76+
end
7177

72-
_, acc ->
73-
acc
74-
end)
78+
# Amend the folding range
79+
defp do_group_tokens([{k, _, _} = token | rest], [[{:identifier, _, _}] = head | tail])
80+
when k in @kinds do
81+
acc = [[token | head] | tail]
82+
do_group_tokens(rest, acc)
83+
end
84+
85+
# Start a new folding range
86+
defp do_group_tokens([{k, _, _} = token | rest], acc) when k in @kinds do
87+
acc = [[token] | acc]
88+
do_group_tokens(rest, acc)
89+
end
90+
91+
# Finish the open folding range
92+
defp do_group_tokens([{:eol, _, _} = token | rest], [[{k, _, _} | _] = head | tail])
93+
when k in @kinds do
94+
acc = [[token | head] | tail]
95+
do_group_tokens(rest, acc)
96+
end
97+
98+
defp do_group_tokens([_unmatched_token | rest], acc) do
99+
do_group_tokens(rest, acc)
75100
end
76101

77102
@spec convert_groups_to_ranges([[Token.t()]]) :: [FoldingRange.t()]

apps/language_server/test/providers/folding_range_test.exs

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,57 @@ defmodule ElixirLS.LanguageServer.Providers.FoldingRangeTest do
479479
assert compare_condensed_ranges(ranges, expected, text)
480480
end
481481

482+
@tag text: """
483+
defmodule A do
484+
@doc false
485+
def init(_) do
486+
IO.puts("Hello World!")
487+
{:ok, []}
488+
end
489+
end
490+
"""
491+
test "@doc false does not create a folding range", %{ranges_result: ranges_result, text: text} do
492+
assert {:ok, ranges} = ranges_result
493+
expected = [{0, 5, :region}, {2, 4, :region}]
494+
assert compare_condensed_ranges(ranges, expected, text)
495+
end
496+
497+
@tag text: """
498+
defmodule A do
499+
@typedoc false
500+
@type t :: %{}
501+
502+
def init(_) do
503+
IO.puts("Hello World!")
504+
{:ok, []}
505+
end
506+
end
507+
"""
508+
test "@typedoc example", %{ranges_result: ranges_result, text: text} do
509+
assert {:ok, ranges} = ranges_result
510+
expected = [{0, 7, :region}, {4, 6, :region}]
511+
assert compare_condensed_ranges(ranges, expected, text)
512+
end
513+
514+
@tag text: """
515+
defmodule A do
516+
@moduledoc false
517+
518+
def init(_) do
519+
IO.puts("Hello World!")
520+
{:ok, []}
521+
end
522+
end
523+
"""
524+
test "@moduledoc false does not create a folding range", %{
525+
ranges_result: ranges_result,
526+
text: text
527+
} do
528+
assert {:ok, ranges} = ranges_result
529+
expected = [{0, 6, :region}, {3, 5, :region}]
530+
assert compare_condensed_ranges(ranges, expected, text)
531+
end
532+
482533
defp fold_text(%{text: _text} = context) do
483534
ranges_result = FoldingRange.provide(context)
484535
{:ok, Map.put(context, :ranges_result, ranges_result)}
@@ -537,12 +588,12 @@ defmodule ElixirLS.LanguageServer.Providers.FoldingRangeTest do
537588
end)
538589

539590
result_condensed
540-
|> Enum.map(fn {line_start, line_end, :any} ->
591+
|> Enum.map(fn {line_start, line_end, descriptor} ->
541592
out =
542593
Enum.slice(lines, line_start, line_end - line_start + 2)
543594
|> Enum.join("\n")
544595

545-
IO.puts("Folding lines #{line_start}, #{line_end}:")
596+
IO.puts("Folding lines #{line_start}, #{line_end} (#{descriptor}):")
546597
IO.puts(out)
547598
IO.puts("\n")
548599
end)

0 commit comments

Comments
 (0)