From ac4194e2a189a05847ca47cbb61758e1fa3be39f Mon Sep 17 00:00:00 2001 From: Lukasz Samson Date: Thu, 31 Aug 2023 08:15:49 +0200 Subject: [PATCH] leave parens in typespecs --- .../type_spec/contract_translator.ex | 1 - apps/language_server/test/dialyzer_test.exs | 6 +- .../type_spec/contract_translator_test.exs | 76 +++++++++++-------- 3 files changed, 48 insertions(+), 35 deletions(-) diff --git a/apps/language_server/lib/language_server/providers/code_lens/type_spec/contract_translator.ex b/apps/language_server/lib/language_server/providers/code_lens/type_spec/contract_translator.ex index bbfc033b0..faf5c4273 100644 --- a/apps/language_server/lib/language_server/providers/code_lens/type_spec/contract_translator.ex +++ b/apps/language_server/lib/language_server/providers/code_lens/type_spec/contract_translator.ex @@ -23,7 +23,6 @@ defmodule ElixirLS.LanguageServer.Providers.CodeLens.TypeSpec.ContractTranslator |> drop_macro_env(is_macro) |> improve_defprotocol_spec(mod, fun) |> Macro.to_string() - |> String.replace("()", "") |> Code.format_string!(line_length: :infinity) |> IO.iodata_to_binary() |> String.replace_prefix("foo", to_string(fun)) diff --git a/apps/language_server/test/dialyzer_test.exs b/apps/language_server/test/dialyzer_test.exs index 5e3d57eeb..49df44d99 100644 --- a/apps/language_server/test/dialyzer_test.exs +++ b/apps/language_server/test/dialyzer_test.exs @@ -458,12 +458,12 @@ defmodule ElixirLS.LanguageServer.DialyzerTest do "fun" => "myfun", "line" => 2, "mod" => "Elixir.C", - "spec" => "myfun :: 1", + "spec" => "myfun() :: 1", "uri" => ^file_c } ], "command" => command = "spec:" <> _, - "title" => "@spec myfun :: 1" + "title" => "@spec myfun() :: 1" }, "range" => %{ "end" => %{"character" => 0, "line" => 1}, @@ -485,7 +485,7 @@ defmodule ElixirLS.LanguageServer.DialyzerTest do "changes" => %{ ^file_c => [ %{ - "newText" => " @spec myfun :: 1\n", + "newText" => " @spec myfun() :: 1\n", "range" => %{ "end" => %{"character" => 0, "line" => 1}, "start" => %{"character" => 0, "line" => 1} diff --git a/apps/language_server/test/providers/code_lens/type_spec/contract_translator_test.exs b/apps/language_server/test/providers/code_lens/type_spec/contract_translator_test.exs index 44523388c..a52396db5 100644 --- a/apps/language_server/test/providers/code_lens/type_spec/contract_translator_test.exs +++ b/apps/language_server/test/providers/code_lens/type_spec/contract_translator_test.exs @@ -5,142 +5,154 @@ defmodule ElixirLS.LanguageServer.Providers.CodeLens.TypeSpec.ContractTranslator test "translate struct when struct.t type exists" do contract = ~c"() -> \#{'__struct__':='Elixir.DateTime'}" - assert "foo :: DateTime.t()" == + assert "foo() :: DateTime.t()" == ContractTranslator.translate_contract(:foo, contract, false, Atom) end test "don't translate struct when struct.t type does not exist" do contract = ~c"() -> \#{'__struct__':='Elixir.SomeOtherStruct'}" - assert "foo :: %SomeOtherStruct{}" == + assert "foo() :: %SomeOtherStruct{}" == ContractTranslator.translate_contract(:foo, contract, false, Atom) end test "struct" do contract = ~c"() -> \#{'__struct__':=atom(), atom()=>any()}" - assert "foo :: struct" == ContractTranslator.translate_contract(:foo, contract, false, Atom) + + assert "foo() :: struct()" == + ContractTranslator.translate_contract(:foo, contract, false, Atom) end test "drop macro env argument" do contract = ~c"(any(), integer()) -> integer()" - assert "foo(any, integer) :: integer" == + assert "foo(any(), integer()) :: integer()" == ContractTranslator.translate_contract(:foo, contract, false, Atom) - assert "foo(integer) :: integer" == + assert "foo(integer()) :: integer()" == ContractTranslator.translate_contract(:foo, contract, true, Atom) end test "atom :ok" do contract = ~c"(any()) -> ok" - assert "foo(any) :: :ok" == ContractTranslator.translate_contract(:foo, contract, false, Atom) + + assert "foo(any()) :: :ok" == + ContractTranslator.translate_contract(:foo, contract, false, Atom) end test "atom true" do contract = ~c"(any()) -> true" - assert "foo(any) :: true" == + assert "foo(any()) :: true" == ContractTranslator.translate_contract(:foo, contract, false, Atom) end test "atom _ substitution" do contract = ~c"(_) -> false" - assert "foo(any) :: false" == + assert "foo(any()) :: false" == ContractTranslator.translate_contract(:foo, contract, false, Atom) end test "do not drop when substitutions" do contract = ~c"(X) -> atom() when X :: any()" - assert "foo(x) :: atom when x: any" == + assert "foo(x) :: atom() when x: any()" == ContractTranslator.translate_contract(:foo, contract, false, Atom) end test "keyword" do contract = ~c"(any()) -> list({atom(), any()})" - assert "foo(any) :: keyword" == + assert "foo(any()) :: keyword()" == ContractTranslator.translate_contract(:foo, contract, false, Atom) contract = ~c"(any()) -> list({atom(), _})" - assert "foo(any) :: keyword" == + assert "foo(any()) :: keyword()" == ContractTranslator.translate_contract(:foo, contract, false, Atom) end test "keyword(t)" do contract = ~c"(any()) -> list({atom(), integer()})" - assert "foo(any) :: keyword(integer)" == + assert "foo(any()) :: keyword(integer())" == ContractTranslator.translate_contract(:foo, contract, false, Atom) end test "[type]" do contract = ~c"(any()) -> list(atom())" - assert "foo(any) :: [atom]" == + assert "foo(any()) :: [atom()]" == ContractTranslator.translate_contract(:foo, contract, false, Atom) end test "list" do contract = ~c"(any()) -> list(any())" - assert "foo(any) :: list" == + assert "foo(any()) :: list()" == ContractTranslator.translate_contract(:foo, contract, false, Atom) end test "empty list" do contract = ~c"(any()) -> []" - assert "foo(any) :: []" == ContractTranslator.translate_contract(:foo, contract, false, Atom) + + assert "foo(any()) :: []" == + ContractTranslator.translate_contract(:foo, contract, false, Atom) end test "[...]" do contract = ~c"(any()) -> nonempty_list(any())" - assert "foo(any) :: [...]" == + assert "foo(any()) :: [...]" == ContractTranslator.translate_contract(:foo, contract, false, Atom) contract = ~c"(any()) -> nonempty_list(_)" - assert "foo(any) :: [...]" == + assert "foo(any()) :: [...]" == ContractTranslator.translate_contract(:foo, contract, false, Atom) end test "[type, ...]" do contract = ~c"(any()) -> nonempty_list(atom())" - assert "foo(any) :: [atom, ...]" == + assert "foo(any()) :: [atom(), ...]" == ContractTranslator.translate_contract(:foo, contract, false, Atom) end test "undoes conversion of :_ to any inside bitstring" do contract = ~c"(any()) -> <<_:2, _:_*3>>" - assert "foo(any) :: <<_::2, _::_*3>>" == + assert "foo(any()) :: <<_::2, _::_*3>>" == ContractTranslator.translate_contract(:foo, contract, false, Atom) end test "function" do contract = ~c"(any()) -> fun((...) -> ok)" - assert "foo(any) :: (... -> :ok)" == + assert "foo(any()) :: (... -> :ok)" == ContractTranslator.translate_contract(:foo, contract, false, Atom) end test "fun" do contract = ~c"(any()) -> fun((...) -> any())" - assert "foo(any) :: fun" == ContractTranslator.translate_contract(:foo, contract, false, Atom) + + assert "foo(any()) :: fun()" == + ContractTranslator.translate_contract(:foo, contract, false, Atom) end test "empty map" do contract = ~c"(any()) -> \#{}" - assert "foo(any) :: %{}" == ContractTranslator.translate_contract(:foo, contract, false, Atom) + + assert "foo(any()) :: %{}" == + ContractTranslator.translate_contract(:foo, contract, false, Atom) end test "map" do contract = ~c"(any()) -> \#{any()=>any()}" - assert "foo(any) :: map" == ContractTranslator.translate_contract(:foo, contract, false, Atom) + + assert "foo(any()) :: map()" == + ContractTranslator.translate_contract(:foo, contract, false, Atom) end test "map with fields" do @@ -148,9 +160,9 @@ defmodule ElixirLS.LanguageServer.Providers.CodeLens.TypeSpec.ContractTranslator expected = if Version.match?(System.version(), "< 1.13.0") do - "foo(any) :: %{optional(integer) => any, 1 => atom, :abc => 4}" + "foo(any()) :: %{optional(integer()) => any(), 1 => atom(), :abc => 4}" else - "foo(any) :: %{optional(integer) => any, 1 => atom, abc: 4}" + "foo(any()) :: %{optional(integer()) => any(), 1 => atom(), abc: 4}" end assert expected == @@ -160,32 +172,34 @@ defmodule ElixirLS.LanguageServer.Providers.CodeLens.TypeSpec.ContractTranslator test "defprotocol type t" do contract = ~c"(any()) -> any()" - assert "foo(t) :: any" == + assert "foo(t()) :: any()" == ContractTranslator.translate_contract(:foo, contract, false, Enumerable) contract = ~c"(any(), any()) -> any()" - assert "foo(t, any) :: any" == + assert "foo(t(), any()) :: any()" == ContractTranslator.translate_contract(:foo, contract, false, Enumerable) contract = ~c"(any()) -> any()" - assert "foo(any) :: any" == ContractTranslator.translate_contract(:foo, contract, false, Atom) + + assert "foo(any()) :: any()" == + ContractTranslator.translate_contract(:foo, contract, false, Atom) contract = ~c"(any(), any()) -> any()" - assert "foo(any, any) :: any" == + assert "foo(any(), any()) :: any()" == ContractTranslator.translate_contract(:foo, contract, false, Atom) end test "defimpl first arg" do contract = ~c"(any()) -> any()" - assert "count(list) :: any" == + assert "count(list()) :: any()" == ContractTranslator.translate_contract(:count, contract, false, Enumerable.List) contract = ~c"(any()) -> any()" - assert "count(Date.Range.t()) :: any" == + assert "count(Date.Range.t()) :: any()" == ContractTranslator.translate_contract(:count, contract, false, Enumerable.Date.Range) end end