From 0c98e656cf60d4b693376a2013a312039560b95d Mon Sep 17 00:00:00 2001 From: Zach Allaun Date: Sat, 3 Aug 2024 02:46:57 -0700 Subject: [PATCH] Do a runtime check for `Macro.classify_atom/1` (#294) --- .../providers/completion/completion_engine.ex | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/lib/elixir_sense/providers/completion/completion_engine.ex b/lib/elixir_sense/providers/completion/completion_engine.ex index 36ed51bd..5d67ccd0 100644 --- a/lib/elixir_sense/providers/completion/completion_engine.ex +++ b/lib/elixir_sense/providers/completion/completion_engine.ex @@ -850,19 +850,18 @@ defmodule ElixirSense.Providers.Completion.CompletionEngine do ## Helpers - # Version.match? is slow, we need to avoid it in a hot loop - if Version.match?(System.version(), ">= 1.14.0-dev") do - defp usable_as_unquoted_module?(name) do - # Conversion to atom is not a problem because - # it is only called with existing modules names. - # credo:disable-for-lines:7 - Macro.classify_atom(String.to_atom(name)) in [:identifier, :unquoted] and - not String.starts_with?(name, "Elixir.") - end - else - defp usable_as_unquoted_module?(name) do - Code.Identifier.classify(String.to_atom(name)) != :other and - not String.starts_with?(name, "Elixir.") + defp usable_as_unquoted_module?(name) do + unquoted_atom_or_identifier?(String.to_atom(name)) and + not String.starts_with?(name, "Elixir.") + end + + defp unquoted_atom_or_identifier?(atom) when is_atom(atom) do + # Macro.classify_atom/1 was introduced in 1.14.0. If it's not available, + # assume we're on an older version and fall back to a private API. + if function_exported?(Macro, :classify_atom, 1) do + apply(Macro, :classify_atom, [atom]) in [:identifier, :unquoted] + else + apply(Code.Identifier, :classify, [atom]) != :other end end