From ef5916bb673b4e96be2ffd0588abc342ff7bf9e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Thu, 27 Oct 2022 23:29:09 +0200 Subject: [PATCH] Refactor and normalize format --- lib/eex/lib/eex/compiler.ex | 94 +++++++---------------------- lib/eex/test/eex/tokenizer_test.exs | 3 +- lib/eex/test/eex_test.exs | 33 ++++------ lib/elixir/src/elixir_parser.yrl | 3 +- 4 files changed, 35 insertions(+), 98 deletions(-) diff --git a/lib/eex/lib/eex/compiler.ex b/lib/eex/lib/eex/compiler.ex index bba196014d..23641bc1d7 100644 --- a/lib/eex/lib/eex/compiler.ex +++ b/lib/eex/lib/eex/compiler.ex @@ -60,22 +60,8 @@ defmodule EEx.Compiler do case expr(t, line, column + 2 + marker_length, state, []) do {:error, _line, _column, message} -> - code_snippet = code_snippet(state.source, %{line: line, column: column}, marker_length) - - message = - case code_snippet do - "" -> - message - - code_snippet -> - """ - #{message} - - #{code_snippet} - """ - end - - {:error, message, %{line: line, column: column}} + meta = %{line: line, column: column} + {:error, message <> code_snippet(state.source, meta, marker_length), meta} {:ok, expr, new_line, new_column, rest} -> {key, expr} = @@ -397,16 +383,10 @@ defmodule EEx.Compiler do end defp generate_buffer([{:middle_expr, _, chars, meta} | _tokens], _buffer, [], state) do - snippet = code_snippet(state.source, meta, 0) - - message = """ - unexpected middle of expression <%#{chars}%> - - #{snippet} - """ + message = "unexpected middle of expression <%#{chars}%>" raise EEx.SyntaxError, - message: message, + message: message <> code_snippet(state.source, meta, 0), file: state.file, line: meta.line, column: meta.column @@ -427,14 +407,10 @@ defmodule EEx.Compiler do end defp generate_buffer([{:end_expr, _, chars, meta} | _], _buffer, [], state) do - message = """ - unexpected end of expression <%#{chars}%> - - #{code_snippet(state.source, meta, 0)} - """ + message = "unexpected end of expression <%#{chars}%>" raise EEx.SyntaxError, - message: message, + message: message <> code_snippet(state.source, meta, 0), file: state.file, line: meta.line, column: meta.column @@ -445,16 +421,10 @@ defmodule EEx.Compiler do end defp generate_buffer([{:eof, meta}], _buffer, [{_content, content_meta} | _scope], state) do - snippet = code_snippet(state.source, content_meta, 1) - - message = """ - expected a closing '<% end %>' for block expression in EEx - - #{snippet} - """ + message = "expected a closing '<% end %>' for block expression in EEx" raise EEx.SyntaxError, - message: message, + message: message <> code_snippet(state.source, content_meta, 1), file: state.file, line: content_meta.line, column: meta.column @@ -529,42 +499,20 @@ defmodule EEx.Compiler do line_start = max(meta.line - 3, 1) line_end = meta.line - case String.split(source, ["\r\n", "\n"]) do - lines when length(lines) < line_start -> - "" + source + |> String.split(["\r\n", "\n"]) + |> Enum.slice(line_start-1..line_end-1) + |> Enum.map_reduce(line_start, fn + expr, line_number when line_number == line_end -> + arrow = String.duplicate(" ", meta.column + 2 + arrow_padding) <> "^" + {"#{line_number} | #{expr}\n | #{arrow}", line_number + 1} - lines -> - {offset_start, offset_end} = source_offset(lines, line_start, line_end) - - {snippet, _acc} = - source - |> binary_part(offset_start, offset_end - 1) - |> String.split(["\r\n", "\n"]) - |> Enum.map_reduce(line_start, fn - expr, line_number when line_number == line_end -> - arrow = String.duplicate(" ", meta.column + 2 + arrow_padding) <> "^" - {"#{line_number} | #{expr}\n | #{arrow}", line_number + 1} - - expr, line_number -> - {"#{line_number} | #{expr}", line_number + 1} - end) - - Enum.join([" |" | snippet], "\n") + expr, line_number -> + {"#{line_number} | #{expr}", line_number + 1} + end) + |> case do + {[], _} -> "" + {snippet, _} -> Enum.join(["\n |" | snippet], "\n") end end - - defp source_offset(lines, line_start, line_end) do - lines - |> Enum.with_index(1) - |> Enum.reduce({0, 0}, fn - {line, index}, {offset_start, offset_end} when index < line_start -> - {String.length(line) + offset_start + 1, offset_end} - - {line, index}, {offset_start, offset_end} when index <= line_end -> - {offset_start, String.length(line) + offset_end + 1} - - {_line, _index}, acc -> - acc - end) - end end diff --git a/lib/eex/test/eex/tokenizer_test.exs b/lib/eex/test/eex/tokenizer_test.exs index 8bc79f878a..a80f2b3daa 100644 --- a/lib/eex/test/eex/tokenizer_test.exs +++ b/lib/eex/test/eex/tokenizer_test.exs @@ -376,10 +376,9 @@ defmodule EEx.TokenizerTest do test "returns error when there is start mark and no end mark" do message = """ expected closing '%>' for EEx expression - | 1 | foo <% :bar - | ^ + | ^\ """ assert EEx.tokenize(~c"foo <% :bar", @opts) == diff --git a/lib/eex/test/eex_test.exs b/lib/eex/test/eex_test.exs index 40f6f00655..324f1b42e4 100644 --- a/lib/eex/test/eex_test.exs +++ b/lib/eex/test/eex_test.exs @@ -276,10 +276,9 @@ defmodule EExTest do test "when the token is invalid" do message = """ nofile:1:5: expected closing '%>' for EEx expression - | 1 | foo <%= bar - | ^ + | ^\ """ assert_raise EEx.SyntaxError, message, fn -> @@ -290,13 +289,12 @@ defmodule EExTest do test "when middle expression is found without a start expression" do message = """ nofile:5:1: unexpected middle of expression <% else %> - | 2 | <%= "content" %> 3 | <%= if true %> 4 | <%= "foo" %> 5 | <% else %> - | ^ + | ^\ """ assert_raise EEx.SyntaxError, message, fn -> @@ -309,10 +307,9 @@ defmodule EExTest do test "when there is only middle expression" do message = """ nofile:1:1: unexpected middle of expression <% else %> - | 1 | <% else %> - | ^ + | ^\ """ assert_raise EEx.SyntaxError, message, fn -> @@ -323,12 +320,11 @@ defmodule EExTest do test "when it is missing a `do` in case expr" do message = """ nofile:3:3: unexpected middle of expression <% :something -> %> - | 1 | content 2 | <%= case @var %> 3 | <% :something -> %> - | ^ + | ^\ """ assert_raise EEx.SyntaxError, message, fn -> @@ -339,12 +335,11 @@ defmodule EExTest do test "when it is a `do` in cond expr" do message = """ nofile:3:3: unexpected middle of expression <% true -> %> - | 1 | content 2 | <%= cond %> 3 | <% true -> %> - | ^ + | ^\ """ assert_raise EEx.SyntaxError, message, fn -> @@ -355,10 +350,9 @@ defmodule EExTest do test "when end expression is found without a start expression" do message = """ nofile:1:5: unexpected end of expression <% end %> - | 1 | foo <% end %> - | ^ + | ^\ """ assert_raise EEx.SyntaxError, message, fn -> @@ -369,11 +363,10 @@ defmodule EExTest do test "when start expression is found without an end expression" do message = """ nofile:2:1: expected a closing '<% end %>' for block expression in EEx - | 1 | foo 2 | <%= if true do %> - | ^ + | ^\ """ assert_raise EEx.SyntaxError, message, fn -> @@ -384,11 +377,10 @@ defmodule EExTest do test "when start expression with middle expression is found without an end expression" do message = """ nofile:2:1: expected a closing '<% end %>' for block expression in EEx - | 1 | foo 2 | <%= if true do %> - | ^ + | ^\ """ assert_raise EEx.SyntaxError, message, fn -> @@ -399,13 +391,12 @@ defmodule EExTest do test "when multiple start expressions is found without an end expression" do message = """ nofile:5:1: expected a closing '<% end %>' for block expression in EEx - | 2 | <%= if true do %> 3 | <%= @something %> 4 |\s 5 | <%= if @var do %> - | ^ + | ^\ """ assert_raise EEx.SyntaxError, message, fn -> @@ -418,10 +409,9 @@ defmodule EExTest do test "when nested end expression is found without a start expression" do message = """ nofile:1:31: unexpected end of expression <% end %> - | 1 | foo <%= if true do %><% end %><% end %> - | ^ + | ^\ """ assert_raise EEx.SyntaxError, message, fn -> @@ -473,10 +463,9 @@ defmodule EExTest do test "honor file names" do message = """ my_file.eex:1:5: expected closing '%>' for EEx expression - | 1 | foo <%= bar - | ^ + | ^\ """ assert_raise EEx.SyntaxError, message, fn -> diff --git a/lib/elixir/src/elixir_parser.yrl b/lib/elixir/src/elixir_parser.yrl index 960c0c6f6c..14210abb3d 100644 --- a/lib/elixir/src/elixir_parser.yrl +++ b/lib/elixir/src/elixir_parser.yrl @@ -60,7 +60,8 @@ Expect 3. %% instead "|", we should then change "::" to come after =>. %% We may also want to consider addressing the precedence of %% [foo: bar | baz], but that may be a breaking change for -%% custom DSLs. +%% custom DSLs. We should also consider removing support for +%% keywords after when (therefore brackets will be required). Left 5 do. Right 10 stab_op_eol. %% ->