Skip to content

Commit

Permalink
Support Elixir 1.18 (#849)
Browse files Browse the repository at this point in the history
1.18 support. 

Updated elixir_sense to support 1.18. 
Noticed some slowdowns pertaining to the version checks we do internally, so I cached them in persistent_term, since the erlang or elixir versions can't change while the VM is running. 


Co-authored-by: scohen <[email protected]>
  • Loading branch information
scohen and scohen authored Feb 18, 2025
1 parent d0f3d1c commit 477e8b4
Show file tree
Hide file tree
Showing 26 changed files with 524 additions and 461 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/elixir.yml
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,10 @@ jobs:
# and running the workflow steps.
matrix:
include:
- elixir: "1.18.1"
otp: "27"
- elixir: "1.18.1"
otp: "26"
- elixir: "1.17"
otp: "27"
- elixir: "1.17"
Expand Down
10 changes: 5 additions & 5 deletions apps/common/lib/elixir/features.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,23 @@ defmodule Elixir.Features do
end

def compile_keeps_current_directory? do
Version.match?(System.version(), ">= 1.15.0")
Versions.current_elixir_matches?(">= 1.15.0")
end

def after_verify? do
Version.match?(System.version(), ">= 1.14.0")
Versions.current_elixir_matches?(">= 1.14.0")
end

def details_in_context? do
Version.match?(System.version(), ">= 1.16.0")
Versions.current_elixir_matches?(">= 1.16.0")
end

def span_in_diagnostic? do
Version.match?(System.version(), ">= 1.16.0")
Versions.current_elixir_matches?(">= 1.16.0")
end

def contains_set_theoretic_types? do
Version.match?(System.version(), ">= 1.17.0")
Versions.current_elixir_matches?(">= 1.17.0")
end

@doc """
Expand Down
59 changes: 36 additions & 23 deletions apps/common/lib/lexical/vm/versions.ex
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,16 @@ defmodule Lexical.VM.Versions do
@type t :: %{elixir: version_string(), erlang: version_string()}
@type versioned_t :: %{elixir: Version.t(), erlang: Version.t()}

defmacrop cache_in_persistent_term(key, do: materializer) do
quote do
with :not_found <- :persistent_term.get(unquote(key), :not_found) do
result = unquote(materializer)
:persistent_term.put(unquote(key), result)
result
end
end
end

@doc """
Returns the versions of elixir and erlang in the currently running VM
"""
Expand All @@ -27,6 +37,15 @@ defmodule Lexical.VM.Versions do
}
end

@doc """
Returns true if the current version of elixir matches the requirement
"""
def current_elixir_matches?(requirement) do
cache_in_persistent_term {:current_elixir_matches?, requirement} do
Version.match?(elixir_version(), requirement)
end
end

@doc """
Returns the compiled-in versions of elixir and erlang.
Expand Down Expand Up @@ -138,32 +157,26 @@ defmodule Lexical.VM.Versions do
end

defp elixir_version do
System.version()
cache_in_persistent_term {__MODULE__, :current_elixir} do
System.version()
end
end

defp erlang_version do
case :persistent_term.get({__MODULE__, :current_erlang}, :not_found) do
:not_found ->
major = :otp_release |> :erlang.system_info() |> List.to_string()
version_file = Path.join([:code.root_dir(), "releases", major, "OTP_VERSION"])

erlang_version =
try do
{:ok, contents} = read_file(version_file)
String.split(contents, "\n", trim: true)
else
[full] -> full
_ -> major
catch
:error ->
major
end

:persistent_term.put({__MODULE__, :current_erlang}, erlang_version)
erlang_version()

erlang_version ->
erlang_version
cache_in_persistent_term {__MODULE__, :current_erlang} do
major = :otp_release |> :erlang.system_info() |> List.to_string()
version_file = Path.join([:code.root_dir(), "releases", major, "OTP_VERSION"])

try do
{:ok, contents} = read_file(version_file)
String.split(contents, "\n", trim: true)
else
[full] -> full
_ -> major
catch
:error ->
major
end
end
end

Expand Down
6 changes: 3 additions & 3 deletions apps/common/mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ defmodule Common.MixProject do
{:lexical_shared, path: "../../projects/lexical_shared"},
{:lexical_test, path: "../../projects/lexical_test", only: :test},
{:snowflake, "~> 1.0"},
{:sourceror, "~> 1.4"},
{:stream_data, "~> 0.6", only: [:test], runtime: false},
{:patch, "~> 0.12", only: [:test], optional: true, runtime: false}
{:sourceror, "~> 1.7"},
{:stream_data, "~> 1.1", only: [:test], runtime: false},
{:patch, "~> 0.15", only: [:test], optional: true, runtime: false}
]
end
end
6 changes: 2 additions & 4 deletions apps/common/test/lexical/math_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,8 @@ defmodule Lexical.MathTest do
end

property "clamp works with all integers" do
check all(
ints <- uniq_list_of(integer(-100_000..100_000), min_length: 5, max_length: 20),
[low, mid, high] = low_mid_high(ints)
) do
check all(ints <- uniq_list_of(integer(-100_000..100_000), min_length: 5, max_length: 20)) do
[low, mid, high] = low_mid_high(ints)
assert Math.clamp(mid, low, high) == mid
assert Math.clamp(low, mid, high) == mid
assert Math.clamp(high, low, mid) == mid
Expand Down
2 changes: 1 addition & 1 deletion apps/protocol/mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ defmodule Lexical.Protocol.MixProject do
{:lexical_test, path: "../../projects/lexical_test", only: :test},
{:common, in_umbrella: true},
{:jason, "~> 1.4", optional: true},
{:patch, "~> 0.12", only: [:test]},
{:patch, "~> 0.15", only: [:test]},
{:proto, in_umbrella: true}
]
end
Expand Down
10 changes: 10 additions & 0 deletions apps/remote_control/benchmarks/versions_bench.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
alias Lexical.VM.Versions

Benchee.run(%{
"versions" => fn ->
Version.match?(Versions.current().elixir, ">=1.15.0")
end,
"current_versions_matches" => fn ->
Versions.current_elixir_matches?(">=1.15.0")
end
})
Loading

0 comments on commit 477e8b4

Please sign in to comment.