Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions lib/mix/lib/mix/compilers/elixir.ex
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,14 @@ defmodule Mix.Compilers.Elixir do
end
end

@doc """
Retrieves all diagnostics from the given manifest.
"""
def diagnostics(manifest, dest) do
{_, all_sources, _, _, _, _, _, _} = parse_manifest(manifest, dest)
previous_warnings(all_sources, false)
end

defp compiler_info_from_force(manifest, all_paths, all_modules, dest) do
# A config, path dependency or manifest has changed, let's just compile everything
for {module, _} <- all_modules,
Expand Down
8 changes: 8 additions & 0 deletions lib/mix/lib/mix/compilers/erlang.ex
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,14 @@ defmodule Mix.Compilers.Erlang do
manifest |> read_manifest() |> Enum.map(&elem(&1, 0))
end

@doc """
Retrieves all diagnostics from the given manifest.
"""
def diagnostics(manifest) do
entries = read_manifest(manifest)
manifest_warnings(entries)
end

defp extract_entries(src_dir, src_ext, dest_dir, dest_ext, force) do
files = Mix.Utils.extract_files(List.wrap(src_dir), List.wrap(src_ext))

Expand Down
64 changes: 63 additions & 1 deletion lib/mix/lib/mix/task.compiler.ex
Original file line number Diff line number Diff line change
Expand Up @@ -147,12 +147,17 @@ defmodule Mix.Task.Compiler do
"""
@callback manifests() :: [Path.t()]

@doc """
Lists persisted diagnostics from the compiler.
"""
@callback diagnostics() :: [Diagnostic.t()]

@doc """
Removes build artifacts and manifests.
"""
@callback clean() :: any

@optional_callbacks clean: 0, manifests: 0
@optional_callbacks clean: 0, manifests: 0, diagnostics: 0

@doc """
Adds a callback that runs after a given compiler.
Expand Down Expand Up @@ -184,6 +189,63 @@ defmodule Mix.Task.Compiler do
end
end

@doc """
Returns all compilers for the current project.
"""
def compilers(config \\ Mix.Project.config()) do
compilers = config[:compilers] || Mix.compilers()

if :xref in compilers do
IO.warn(
"the :xref compiler is deprecated, please remove it from your mix.exs :compilers options"
)

List.delete(compilers, :xref)
else
compilers
end
|> maybe_prepend(:leex)
|> maybe_prepend(:yecc)
end

defp maybe_prepend(compilers, compiler) do
if compiler in compilers do
compilers
else
[compiler | compilers]
end
end

@doc """
Lists manifest files for all compilers in the current project.
"""
def manifests(config \\ Mix.Project.config()) do
Enum.flat_map(compilers(config), fn compiler ->
module = Mix.Task.get("compile.#{compiler}")

if module && function_exported?(module, :manifests, 0) do
module.manifests()
else
[]
end
end)
end

@doc """
Lists persisted diagnostics from all compilers in the current project.
"""
def diagnostics(config \\ Mix.Project.config()) do
Enum.flat_map(compilers(config), fn compiler ->
module = Mix.Task.get("compile.#{compiler}")

if module && function_exported?(module, :diagnostics, 0) do
module.diagnostics()
else
[]
end
end)
end

# Normalize the compiler result to a diagnostic tuple.
@doc false
def normalize(result, name) do
Expand Down
2 changes: 1 addition & 1 deletion lib/mix/lib/mix/tasks/clean.ex
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ defmodule Mix.Tasks.Clean do
# First, we get the tasks. After that, we clean them.
# This is to avoid a task cleaning a compiler module.
tasks =
for compiler <- [:protocols] ++ Mix.Tasks.Compile.compilers(),
for compiler <- [:protocols] ++ Mix.Task.Compiler.compilers(),
module = Mix.Task.get("compile.#{compiler}"),
function_exported?(module, :clean, 0),
do: module
Expand Down
2 changes: 1 addition & 1 deletion lib/mix/lib/mix/tasks/compile.all.ex
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ defmodule Mix.Tasks.Compile.All do
Mix.Project.build_structure(config)

config
|> Mix.Tasks.Compile.compilers()
|> Mix.Task.Compiler.compilers()
|> compile(args, :noop, [])
end

Expand Down
6 changes: 6 additions & 0 deletions lib/mix/lib/mix/tasks/compile.elixir.ex
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,12 @@ defmodule Mix.Tasks.Compile.Elixir do
def manifests, do: [manifest()]
defp manifest, do: Path.join(Mix.Project.manifest_path(), @manifest)

@impl true
def diagnostics do
dest = Mix.Project.compile_path()
Mix.Compilers.Elixir.diagnostics(manifest(), dest)
end

@impl true
def clean do
dest = Mix.Project.compile_path()
Expand Down
5 changes: 5 additions & 0 deletions lib/mix/lib/mix/tasks/compile.erlang.ex
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,11 @@ defmodule Mix.Tasks.Compile.Erlang do
def manifests, do: [manifest()]
defp manifest, do: Path.join(Mix.Project.manifest_path(), @manifest)

@impl true
def diagnostics do
Mix.Compilers.Erlang.diagnostics(manifest())
end

@impl true
def clean do
Mix.Compilers.Erlang.clean(manifest())
Expand Down
45 changes: 6 additions & 39 deletions lib/mix/lib/mix/tasks/compile.ex
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
defmodule Mix.Tasks.Compile do
use Mix.Task.Compiler
use Mix.Task

@shortdoc "Compiles source files"

Expand Down Expand Up @@ -42,6 +42,7 @@ defmodule Mix.Tasks.Compile do
the paths set by the code loader from the `ERL_LIBS` environment as
well as explicitly listed by providing `-pa` and `-pz` options
to Erlang.

## Compilers

To see documentation for each specific compiler, you must
Expand Down Expand Up @@ -79,32 +80,8 @@ defmodule Mix.Tasks.Compile do

"""

@doc """
Returns all compilers for the current project.
"""
def compilers(config \\ Mix.Project.config()) do
compilers = config[:compilers] || Mix.compilers()

if :xref in compilers do
IO.warn(
"the :xref compiler is deprecated, please remove it from your mix.exs :compilers options"
)

List.delete(compilers, :xref)
else
compilers
end
|> maybe_prepend(:leex)
|> maybe_prepend(:yecc)
end

defp maybe_prepend(compilers, compiler) do
if compiler in compilers do
compilers
else
[compiler | compilers]
end
end
@deprecated "Use Mix.Task.Compiler.compilers/1 instead"
defdelegate compilers(config \\ Mix.Project.config()), to: Mix.Task.Compiler

@impl true
def run(["--list"]) do
Expand Down Expand Up @@ -228,18 +205,8 @@ defmodule Mix.Tasks.Compile do
end
end

@impl true
def manifests do
Enum.flat_map(compilers(), fn compiler ->
module = Mix.Task.get("compile.#{compiler}")

if module && function_exported?(module, :manifests, 0) do
module.manifests()
else
[]
end
end)
end
@deprecated "Use Mix.Task.Compiler.manifests/0 instead"
defdelegate manifests, to: Mix.Task.Compiler

## Consolidation handling

Expand Down
11 changes: 11 additions & 0 deletions lib/mix/test/mix/tasks/compile.elixir_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -1470,6 +1470,17 @@ defmodule Mix.Tasks.Compile.ElixirTest do
message: ^message
} = diagnostic
end)

assert [diagnostic] = Mix.Tasks.Compile.Elixir.diagnostics()

assert %Diagnostic{
file: ^file,
source: ^file,
severity: :warning,
position: {2, 13},
compiler_name: "Elixir",
message: ^message
} = diagnostic
end)
end

Expand Down
11 changes: 11 additions & 0 deletions lib/mix/test/mix/tasks/compile.erlang_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,17 @@ defmodule Mix.Tasks.Compile.ErlangTest do
capture_io(fn ->
assert {:ok, [diagnostic]} = Mix.Tasks.Compile.Erlang.run([])

assert %Mix.Task.Compiler.Diagnostic{
file: ^file,
source: ^file,
compiler_name: "erl_lint",
message: "function my_fn/0 is unused",
position: position(2, 1),
severity: :warning
} = diagnostic

assert [diagnostic] = Mix.Tasks.Compile.Erlang.diagnostics()

assert %Mix.Task.Compiler.Diagnostic{
file: ^file,
source: ^file,
Expand Down
2 changes: 1 addition & 1 deletion lib/mix/test/mix/tasks/compile_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ defmodule Mix.Tasks.CompileTest do

@tag project: [compilers: [:elixir, :app, :custom]]
test "compiles does not require all compilers available on manifest" do
assert Mix.Tasks.Compile.manifests() |> Enum.map(&Path.basename/1) ==
assert Mix.Task.Compiler.manifests() |> Enum.map(&Path.basename/1) ==
["compile.yecc", "compile.leex", "compile.elixir"]
end

Expand Down
Loading