v1.0.0
1.0.0
Styler's two biggest outstanding bugs have been fixed, both related to compilation breaking during module directive organization. One was references to aliases being moved above where the aliases were declared, and the other was similarly module directives being moved after their uses in module directives.
In both cases, Styler is now smart enough to auto-apply the fixes we recommended in the old Readme.
Other than that, a slew of powerful new features have been added, the neatest one (in the author's opinion anyways) being Alias Lifting.
Thanks to everyone who reported bugs that contributed to all the fixes released in 1.0.0 as well.
Improvements
Alias Lifting
Along the lines of Credo.Check.Design.AliasUsage
, Styler now "lifts" deeply nested aliases (depth >= 3, ala A.B.C....
) that are used more than once.
Put plainly, this code:
defmodule A do
def lift_me() do
A.B.C.foo()
A.B.C.baz()
end
end
will become
defmodule A do
@moduledoc false
alias A.B.C
def lift_me do
C.foo()
C.baz()
end
end
To exclude modules ending in .Foo
from being lifted, add styler: [alias_lifting_exclude: [Foo]]
to your .formatter.exs
Module Attribute Lifting
A long outstanding breakage of a first pass with Styler was breaking directives that relied on module attributes which Styler moved after their uses. Styler now detects these potential breakages and automatically applies our suggested fix, which is creating a variable before the module. This usually happened when folks were using a library that autogenerated their moduledocs for them.
In code, this module:
defmodule MyGreatLibrary do
@library_options [...]
@moduledoc make_pretty_docs(@library_options)
use OptionsMagic, my_opts: @library_options
...
end
Will now be styled like so:
library_options = [...]
defmodule MyGreatLibrary do
@moduledoc make_pretty_docs(library_options)
use OptionsMagic, my_opts: unquote(library_options)
@library_options library_options
...
end
Mix Config File Organization
Styler now organizes Mix.Config.config/2,3
stanzas according to erlang term sorting. This helps manage large configuration files, removing the "where should I put this" burden from developers AND helping find duplicated configuration stanzas.
See the moduledoc for Styler.Style.Configs
for more.
Pipe Optimizations
Enum.into(x, [])
=>Enum.to_list(x)
Enum.into(x, [], mapper)
=>Enum.map(x, mapper)
a |> Enum.map(m) |> Enum.join()
tomap_join(a, m)
. we already did this forjoin/2
, but missed the case forjoin/1
lhs |> Enum.reverse() |> Kernel.++(enum)
=>lhs |> Enum.reverse(enum)
with
styles
- remove
with
structure with no left arrows in its head to be normal code (#174) with true <- x(), do: y
=>if x(), do: y
(#173)
Everything Else
if
/unless
: invert if and unless with!=
or!==
, like we do for!
andnot
#132@derive
: move@derive
beforedefstruct|schema|embedded_schema
declarations (fixes compiler warning!) #134- strings: rewrite double-quoted strings to use
~s
when there's 4+ escaped double-quotes
("\"\"\"\""
->~s("""")
) (Credo.Check.Readability.StringSigils
) #146 Map.drop(foo, [single_key])
=>Map.delete(foo, single_key)
#161 (also in pipes)Keyword.drop(foo, [single_key])
=>Keyword.delete(foo, single_key)
#161 (also in pipes)
Fixes
- don't blow up on
def function_head_with_no_body_nor_parens
(#185, h/t @ypconstante) - fix
with
arrow replacement + redundant body removal creating invalid statements (#184, h/t @JesseHerrick) - allow Kernel unary
!
andnot
as valid pipe starts (#183, h/t @nherzing) - fix
Map.drop(x, [a | b])
registering as a chance to refactor toMap.delete
alias
: expands aliases when moving an alias after another directive that relied on it (#137)- module directives: various fixes for unreported obscure crashes
- pipes: fix a comment-shifting scenario when unpiping
Timex.now/1
will no longer be rewritten toDateTime.now!/1
due to Timex accepting a wider domain of "timezones" than the stdlib (#145, h/t @ivymarkwell)with
: skip nodes which (unexpectedly) do not contain ado
body (#158, h/t @DavidB59)then(&fun/1)
: fix false positives on arithmetic&1 + x / 1
(#164, h/t @aenglisc)
Breaking Changes
- drop support for elixir
1.14
- ModuleDirectives: group callback attributes (
before_compile after_compile after_verify
) with nondirectives (previously, were grouped withuse
, their relative order maintained). to keep the desired behaviour, you can make newuse
macros that wrap these callbacks. Apologies if this makes using Styler untenable for your codebase, but it's probably not a good tool for macro-heavy libraries. - sorting configs for the first time can change your configuration; see Mix Configs docs for more