Skip to content
4 changes: 2 additions & 2 deletions .tool-versions
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
elixir 1.6.6-otp-20
erlang 20.2.4
elixir 1.7.4-otp-21
erlang 21.2.4
7 changes: 3 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ The Elixir Language Server provides a server that runs in the background, provid
- Debugger support (requires Erlang >= OTP 19)
- Automatic, incremental Dialyzer analysis (requires Erlang OTP 20)
- Automatic inline suggestion of @specs based on Dialyzer's inferred success typings
- Inline reporting of build warnings and errors (requires Elixir >= 1.6)
- Inline reporting of build warnings and errors
- Documentation lookup on hover
- Go-to-definition
- Code completion
- Code formatter (requries Elixir >= 1.6)
- Code formatter
- Find references to functions and modules (Thanks to @mattbaker)
- Quick symbol lookup in file (Thanks to @mattbaker)

Expand All @@ -21,8 +21,7 @@ The Elixir Language Server provides a server that runs in the background, provid

Elixir:

- 1.6.0 minimum
- \>= 1.6.6 recommended
- 1.7.0 minimum

Erlang:

Expand Down
2 changes: 1 addition & 1 deletion apps/debugger/mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ defmodule ElixirLS.Debugger.Mixfile do
config_path: "config/config.exs",
deps_path: "../../deps",
lockfile: "../../mix.lock",
elixir: ">= 1.6.5",
elixir: ">= 1.7.0",
build_embedded: false,
start_permanent: true,
build_per_environment: false,
Expand Down
4 changes: 2 additions & 2 deletions apps/elixir_ls_utils/mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ defmodule ElixirLS.Utils.Mixfile do
deps_path: "../../deps",
elixirc_paths: ["lib", "test/support"],
lockfile: "../../mix.lock",
elixir: ">= 1.6.5",
elixir: ">= 1.7.0",
build_embedded: false,
start_permanent: false,
build_per_environment: false,
Expand Down Expand Up @@ -41,6 +41,6 @@ defmodule ElixirLS.Utils.Mixfile do
#
# Type "mix help deps" for more examples and options
defp deps do
[{:jason, "~> 1.0"}, {:mix_task_archive_deps, "~> 0.4.0"}]
[{:jason, "~> 1.0"}, {:mix_task_archive_deps, github: "JakeBecker/mix_task_archive_deps"}]
end
end
23 changes: 15 additions & 8 deletions apps/language_server/lib/language_server/build.ex
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,14 @@ defmodule ElixirLS.LanguageServer.Build do
:timer.tc(fn ->
IO.puts("Compiling with Mix env #{Mix.env()}")

prev_deps = Mix.Dep.loaded([])
clear_deps_cache()
prev_deps = cached_deps()
Mix.Dep.clear_cached()

case reload_project() do
{:ok, mixfile_diagnostics} ->
if fetch_deps? and Mix.Dep.loaded([]) != prev_deps, do: fetch_deps()
if fetch_deps? and Mix.Dep.load_on_environment([]) != prev_deps,
do: fetch_deps()

{status, diagnostics} = compile()
Server.build_finished(parent, {status, mixfile_diagnostics ++ diagnostics})

Expand Down Expand Up @@ -171,13 +173,18 @@ defmodule ElixirLS.LanguageServer.Build do
end
end

defp clear_deps_cache do
Mix.ProjectStack.write_cache({:cached_deps, Mix.env(), Mix.Project.get()}, nil)
defp cached_deps do
try do
Mix.Dep.cached()
rescue
_ ->
[]
end
end

defp fetch_deps do
missing_deps =
Mix.Dep.loaded([])
Mix.Dep.load_on_environment([])
|> Enum.filter(fn %Mix.Dep{status: status} ->
case status do
{:unavailable, _} -> true
Expand Down Expand Up @@ -227,11 +234,11 @@ defmodule ElixirLS.LanguageServer.Build do
}
end

defp range(nil, nil) do
defp range(_, nil) do
%{"start" => %{"line" => 0, "character" => 0}, "end" => %{"line" => 0, "character" => 0}}
end

defp range(nil, source_file) do
defp range(_, source_file) do
SourceFile.full_range(source_file)
end
end
52 changes: 27 additions & 25 deletions apps/language_server/lib/language_server/dialyzer.ex
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ defmodule ElixirLS.LanguageServer.Dialyzer do
end

def analyze(parent \\ self(), build_ref, warn_opts) do
GenServer.call({:global, {parent, __MODULE__}}, {:analyze, build_ref, warn_opts}, :infinity)
GenServer.cast({:global, {parent, __MODULE__}}, {:analyze, build_ref, warn_opts})
end

def analysis_finished(server, status, active_plt, mod_deps, md5, warnings, timestamp, build_ref) do
Expand Down Expand Up @@ -144,35 +144,37 @@ defmodule ElixirLS.LanguageServer.Dialyzer do
{:reply, :ok, state}
end

def handle_call({:analyze, build_ref, warn_opts}, _from, state) do
def handle_call({:suggest_contracts, files}, _from, %{plt: plt} = state) do
specs = if is_nil(plt), do: [], else: SuccessTypings.suggest_contracts(plt, files)
{:reply, specs, state}
end

def handle_cast({:analyze, build_ref, warn_opts}, state) do
state =
if Mix.Project.get() do
JsonRpc.log_message(:info, "[ElixirLS Dialyzer] Checking for stale beam files")
new_timestamp = adjusted_timestamp()
ElixirLS.LanguageServer.Build.with_build_lock(fn ->
if Mix.Project.get() do
JsonRpc.log_message(:info, "[ElixirLS Dialyzer] Checking for stale beam files")
new_timestamp = adjusted_timestamp()

{removed_files, file_changes} =
update_stale(state.md5, state.removed_files, state.file_changes, state.timestamp)
{removed_files, file_changes} =
update_stale(state.md5, state.removed_files, state.file_changes, state.timestamp)

state = %{
state
| warn_opts: warn_opts,
timestamp: new_timestamp,
removed_files: removed_files,
file_changes: file_changes,
build_ref: build_ref
}

trigger_analyze(state)
else
state
end
state = %{
state
| warn_opts: warn_opts,
timestamp: new_timestamp,
removed_files: removed_files,
file_changes: file_changes,
build_ref: build_ref
}

{:reply, :ok, state}
end
trigger_analyze(state)
else
state
end
end)

def handle_call({:suggest_contracts, files}, _from, %{plt: plt} = state) do
specs = if is_nil(plt), do: [], else: SuccessTypings.suggest_contracts(plt, files)
{:reply, specs, state}
{:noreply, state}
end

def handle_info({:"ETS-TRANSFER", _, _, _}, state) do
Expand Down
4 changes: 2 additions & 2 deletions apps/language_server/lib/language_server/server.ex
Original file line number Diff line number Diff line change
Expand Up @@ -552,10 +552,10 @@ defmodule ElixirLS.LanguageServer.Server do
end

defp show_version_warnings do
unless Version.match?(System.version(), ">= 1.6.0") do
unless Version.match?(System.version(), ">= 1.7.0") do
JsonRpc.show_message(
:warning,
"Elixir versions below 1.6 are not supported. (Currently v#{System.version()})"
"Elixir versions below 1.7 are not supported. (Currently v#{System.version()})"
)
end

Expand Down
2 changes: 1 addition & 1 deletion apps/language_server/mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ defmodule ElixirLS.LanguageServer.Mixfile do
[
app: :language_server,
version: "0.2.24",
elixir: ">= 1.6.5",
elixir: ">= 1.7.0",
build_path: "../../_build",
config_path: "config/config.exs",
deps_path: "../../deps",
Expand Down
2 changes: 1 addition & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ defmodule ElixirLS.Mixfile do
start_permanent: Mix.env() == :prod,
build_per_environment: false,
deps: deps(),
elixir: ">= 1.6.0-dev"
elixir: ">= 1.7.0"
]
end

Expand Down
2 changes: 1 addition & 1 deletion mix.lock
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"logger_file_backend": {:hex, :logger_file_backend, "0.0.9", "5c2f7d4a28431e695cdf94d191523dbafe609321a67bb654254897f546c393db", [:mix], []},
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], []},
"mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], []},
"mix_task_archive_deps": {:hex, :mix_task_archive_deps, "0.4.0", "95cf15d1b04e10c6319e16a82b88109db2e8164f63e733c1742dfaf8ed9cace5", [:mix], [], "hexpm"},
"mix_task_archive_deps": {:git, "https://github.com/JakeBecker/mix_task_archive_deps.git", "0f71e526e53c96626df80b03d595c58d616f363f", []},
"poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm"},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], []},
}