Packages
styler
0.11.4
1.11.0
1.10.1
1.10.0
1.9.1
1.9.0
1.8.0
1.7.0
1.6.0
1.5.1
1.5.0
1.4.2
1.4.1
1.4.0
1.3.3
1.3.2
1.3.1
1.3.0
1.2.1
1.2.0
1.1.2
1.1.1
1.1.0
1.0.0
1.0.0-rc.2
1.0.0-rc.1
1.0.0-rc.0
1.0.0-alpha.0
0.11.9
0.11.8
0.11.7
0.11.6
0.11.5
0.11.4
0.11.3
0.11.2
0.11.1
0.11.0
0.10.5
0.10.4
retired
0.10.3
0.10.2
0.10.1
0.10.0
0.9.7
0.9.6
0.9.5
0.9.4
0.9.3
0.9.2
retired
0.9.1
retired
0.9.0
0.8.5
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.14
0.7.13
0.7.12
0.7.11
0.7.10
0.7.9
0.7.8
0.7.7
0.7.6
0.7.5
0.7.4
0.7.3
0.7.2
0.7.1
0.7.0
0.6.1
0.6.0
0.5.2
0.5.1
0.5.0
0.4.1
0.4.0
0.3.1
0.3.0
0.2.0
0.1.1
0.1.0
A code-style enforcer that will just FIFY instead of complaining
Current section
Files
Jump to
Current section
Files
lib/style/deprecations.ex
# Copyright 2024 Adobe. All rights reserved.
# This file is licensed to you under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. You may obtain a copy
# of the License at http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software distributed under
# the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
# OF ANY KIND, either express or implied. See the License for the specific language
# governing permissions and limitations under the License.
defmodule Styler.Style.Deprecations do
@moduledoc """
Transformations to soft or hard deprecations introduced on newer Elixir releases
"""
@behaviour Styler.Style
def run({node, meta}, ctx), do: {:cont, {style(node), meta}, ctx}
# Logger.warn => Logger.warning
# Started to emit warning after Elixir 1.15.0
defp style({{:., dm, [{:__aliases__, am, [:Logger]}, :warn]}, funm, args}),
do: {{:., dm, [{:__aliases__, am, [:Logger]}, :warning]}, funm, args}
# Path.safe_relative_to/2 => Path.safe_relative/2
# Path.safe_relative/2 is available since v1.14
# TODO: Remove after Elixir v1.19
defp style({{:., dm, [{_, _, [:Path]} = mod, :safe_relative_to]}, funm, args}),
do: {{:., dm, [mod, :safe_relative]}, funm, args}
# Path.safe_relative_to/2 => Path.safe_relative/2
# Path.safe_relative/2 is available since v1.14
# TODO: Remove after Elixir v1.19
defp style({:|>, m, [lhs, {{:., dm, [{:__aliases__, am, [:Path]}, :safe_relative_to]}, funm, args}]}),
do: {:|>, m, [lhs, {{:., dm, [{:__aliases__, am, [:Path]}, :safe_relative]}, funm, args}]}
if Version.match?(System.version(), ">= 1.16.0-dev") do
# File.stream!(file, options, line_or_bytes) => File.stream!(file, line_or_bytes, options)
defp style({{:., _, [{_, _, [:File]}, :stream!]} = f, fm, [path, {:__block__, _, [modes]} = opts, lob]})
when is_list(modes),
do: {f, fm, [path, lob, opts]}
# For ranges where `start > stop`, you need to explicitly include the step
# Enum.slice(enumerable, 1..-2) => Enum.slice(enumerable, 1..-2//1)
# String.slice("elixir", 2..-1) => String.slice("elixir", 2..-1//1)
defp style({{:., _, [{_, _, [module]}, :slice]} = f, funm, [enumerable, {:.., _, [_, _]} = range]})
when module in [:Enum, :String],
do: {f, funm, [enumerable, add_step_to_decreasing_range(range)]}
# File.stream!(file, options, line_or_bytes) => File.stream!(file, line_or_bytes, options)
defp style({:|>, m, [lhs, {{_, _, [{_, _, [:File]}, :stream!]} = f, fm, [{:__block__, _, [modes]} = opts, lob]}]})
when is_list(modes),
do: {:|>, m, [lhs, {f, fm, [lob, opts]}]}
# For ranges where `start > stop`, you need to explicitly include the step
# Enum.slice(enumerable, 1..-2) => Enum.slice(enumerable, 1..-2//1)
# String.slice("elixir", 2..-1) => String.slice("elixir", 2..-1//1)
defp style({:|>, m, [lhs, {{:., _, [{_, _, [mod]}, :slice]} = f, funm, [{:.., _, [_, _]} = range]}]})
when mod in [:Enum, :String],
do: {:|>, m, [lhs, {f, funm, [add_step_to_decreasing_range(range)]}]}
end
defp style(node), do: node
# silences "function is unused warnings" on ex < 1.16
if Version.match?(System.version(), ">= 1.16.0-dev") do
defp add_step_to_decreasing_range({:.., rm, [first, {_, lm, _} = last]} = range) do
start = extract_value_from_range(first)
stop = extract_value_from_range(last)
if start > stop do
step = {:__block__, [token: "1", line: lm[:line]], [1]}
{:"..//", rm, [first, last, step]}
else
range
end
end
# Extracts the positive or negative integer from the given range block
defp extract_value_from_range({:__block__, _, [value]}), do: value
defp extract_value_from_range({:-, _, [{:__block__, _, [value]}]}), do: -value
end
end