From 2339b52680dfa24dd2491db1c4cb757f4f801e04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Samson?= Date: Fri, 5 Jan 2024 17:07:22 +0100 Subject: [PATCH] Heex parse (#1047) * heex parsing parse html-eex with phoenix eex engine * update comment --- .../lib/language_server/parser.ex | 82 ++++++++++++++++--- 1 file changed, 72 insertions(+), 10 deletions(-) diff --git a/apps/language_server/lib/language_server/parser.ex b/apps/language_server/lib/language_server/parser.ex index 481e50414..773f2ccbd 100644 --- a/apps/language_server/lib/language_server/parser.ex +++ b/apps/language_server/lib/language_server/parser.ex @@ -319,8 +319,8 @@ defmodule ElixirLS.LanguageServer.Parser do end defp should_parse?(uri, source_file) do - String.ends_with?(uri, [".ex", ".exs", ".eex"]) or - source_file.language_id in ["elixir", "eex", "html-eex"] + String.ends_with?(uri, [".ex", ".exs", ".eex", ".heex"]) or + source_file.language_id in ["elixir", "eex", "html-eex", "phoenix-heex"] end defp maybe_fix_missing_env(%Context{} = file, nil), do: file @@ -506,6 +506,16 @@ defmodule ElixirLS.LanguageServer.Parser do (is_binary(file) and String.ends_with?(file, ".eex")) or language_id in ["eex", "html-eex"] end + defp html_eex?(file, language_id) do + (is_binary(file) and + (String.ends_with?(file, ".html.eex") or String.ends_with?(file, ".htm.eex"))) or + language_id in ["html-eex"] + end + + defp heex?(file, language_id) do + (is_binary(file) and String.ends_with?(file, ".heex")) or language_id in ["phoenix-heex"] + end + defp parse_file(text, file, language_id) do {result, raw_diagnostics} = Build.with_diagnostics([log: false], fn -> @@ -517,18 +527,70 @@ defmodule ElixirLS.LanguageServer.Parser do ] ast = - if eex?(file, language_id) do - EEx.compile_string(text, - file: file, - parser_options: parser_options - ) - else - Code.string_to_quoted!(text, parser_options) + cond do + eex?(file, language_id) -> + EEx.compile_string(text, + file: file, + parser_options: parser_options + ) + + html_eex?(file, language_id) -> + if Code.ensure_loaded?(Phoenix.HTML.Engine) do + EEx.compile_string(text, + file: file, + parser_options: parser_options, + engine: Phoenix.HTML.Engine + ) + else + EEx.compile_string(text, + file: file, + parser_options: parser_options + ) + end + + heex?(file, language_id) -> + cond do + Code.ensure_loaded?(Phoenix.LiveView.TagEngine) -> + # LV 0.18+ + EEx.compile_string(text, + file: file, + parser_options: parser_options, + source: text, + caller: __ENV__, + engine: Phoenix.LiveView.TagEngine, + tag_handler: Phoenix.LiveView.HTMLEngine + ) + + Code.ensure_loaded?(Phoenix.LiveView.HTMLEngine) -> + # LV <= 0.18.17 + EEx.compile_string(text, + file: file, + parser_options: parser_options, + source: text, + caller: __ENV__, + engine: Phoenix.LiveView.HTMLEngine + ) + + true -> + EEx.compile_string(text, + file: file, + parser_options: parser_options + ) + end + + true -> + Code.string_to_quoted!(text, parser_options) end {:ok, ast} rescue - e in [EEx.SyntaxError, SyntaxError, TokenMissingError, MismatchedDelimiterError] -> + e in [ + EEx.SyntaxError, + SyntaxError, + TokenMissingError, + MismatchedDelimiterError, + Phoenix.LiveView.Tokenizer.ParseError + ] -> diagnostic = Diagnostics.from_error(:error, e, __STACKTRACE__, file, :no_stacktrace) {:error, diagnostic}