From e85b45effbbdf3dfa1b44e020942efe9079cd6ae Mon Sep 17 00:00:00 2001 From: Marlus Saraiva Date: Sat, 8 May 2021 08:48:04 -0300 Subject: [PATCH] Convert embedded interpolation --- lib/surface/compiler/converter.ex | 5 +++++ lib/surface/compiler/converter_0_5.ex | 10 ++++++++++ lib/surface/compiler/tokenizer.ex | 14 ++++++++++++-- test/compiler/converter_0_5_test.exs | 23 ++++++++++++++++++++++ test/compiler/tokenizer_test.exs | 28 +++++++++++++++++++++++++++ 5 files changed, 78 insertions(+), 2 deletions(-) diff --git a/lib/surface/compiler/converter.ex b/lib/surface/compiler/converter.ex index adecb7d3..4bd35e5b 100644 --- a/lib/surface/compiler/converter.ex +++ b/lib/surface/compiler/converter.ex @@ -153,6 +153,11 @@ defmodule Surface.Compiler.Converter do [{:unquoted_string, meta} | acc] end + defp extract_meta({:string, _name, %{delimiter: ?"} = meta}, acc) do + meta = %{meta | column: meta.column - 1, column_end: meta.column_end + 1} + [{:double_quoted_string, meta} | acc] + end + defp extract_meta(_node, acc) do acc end diff --git a/lib/surface/compiler/converter_0_5.ex b/lib/surface/compiler/converter_0_5.ex index 17b96922..f43b3033 100644 --- a/lib/surface/compiler/converter_0_5.ex +++ b/lib/surface/compiler/converter_0_5.ex @@ -15,6 +15,16 @@ defmodule Surface.Compiler.Converter_0_5 do "{#{value}}" end + def convert(:double_quoted_string, value, _state, _opts) do + new_value = Regex.replace(~r/{{(.+?)}}/, value, "\#{\\1}") + + if new_value != value do + "{#{new_value}}" + else + value + end + end + def convert(:tag_name, "template", _state, _opts) do "#template" end diff --git a/lib/surface/compiler/tokenizer.ex b/lib/surface/compiler/tokenizer.ex index 00029fc2..c2101d9e 100644 --- a/lib/surface/compiler/tokenizer.ex +++ b/lib/surface/compiler/tokenizer.ex @@ -353,10 +353,12 @@ defmodule Surface.Compiler.Tokenizer do end defp handle_attr_value_begin("\"" <> rest, line, column, acc, state) do + acc = put_attr_value(acc, {:string, nil, %{line: line, column: column + 1, delimiter: ?"}}) handle_attr_value_double_quote(rest, line, column + 1, [], acc, state) end defp handle_attr_value_begin("'" <> rest, line, column, acc, state) do + acc = put_attr_value(acc, {:string, nil, %{line: line, column: column + 1, delimiter: ?'}}) handle_attr_value_single_quote(rest, line, column + 1, [], acc, state) end @@ -388,7 +390,11 @@ defmodule Surface.Compiler.Tokenizer do defp handle_attr_value_double_quote("\"" <> rest, line, column, buffer, acc, state) do value = buffer_to_string(buffer) - acc = put_attr_value(acc, {:string, value, %{delimiter: ?"}}) + + acc = + update_attr_value(acc, fn {type, _old_value, meta} -> + {type, value, Map.merge(meta, %{line_end: line, column_end: column})} + end) handle_maybe_tag_open_end(rest, line, column + 1, acc, state) end @@ -415,7 +421,11 @@ defmodule Surface.Compiler.Tokenizer do defp handle_attr_value_single_quote("'" <> rest, line, column, buffer, acc, state) do value = buffer_to_string(buffer) - acc = put_attr_value(acc, {:string, value, %{delimiter: ?'}}) + + acc = + update_attr_value(acc, fn {type, _old_value, meta} -> + {type, value, Map.merge(meta, %{line_end: line, column_end: column})} + end) handle_maybe_tag_open_end(rest, line, column + 1, acc, state) end diff --git a/test/compiler/converter_0_5_test.exs b/test/compiler/converter_0_5_test.exs index 187e236b..49f571bc 100644 --- a/test/compiler/converter_0_5_test.exs +++ b/test/compiler/converter_0_5_test.exs @@ -207,6 +207,29 @@ defmodule Surface.Compiler.Converter_0_5Test do """ end + test "convert literal strings with embedded interpolation" do + expected = + convert(""" +
+
+
+
+ """) + + assert expected == """ +
+
+
+
+ """ + end + ## Planned changes. Uncomment as the related implementation gets merged # test "convert into <#For>" do diff --git a/test/compiler/tokenizer_test.exs b/test/compiler/tokenizer_test.exs index 9f40b7cb..b56f473a 100644 --- a/test/compiler/tokenizer_test.exs +++ b/test/compiler/tokenizer_test.exs @@ -333,6 +333,20 @@ defmodule Surface.Compiler.TokenizerTest do ] = tokens end + test "compute line and columns" do + attrs = + tokenize_attrs(""" +
\ + """) + + assert [ + {"title", {:string, _, %{line: 2, column: 10, line_end: 4, column_end: 6}}, %{}} + ] = attrs + end + test "raise on incomplete attribute value (EOF)" do assert_raise ParseError, "nofile:2:15: expected closing `\"` for attribute value", fn -> tokenize!(""" @@ -380,6 +394,20 @@ defmodule Surface.Compiler.TokenizerTest do ] = tokens end + test "compute line and columns" do + attrs = + tokenize_attrs(""" +
\ + """) + + assert [ + {"title", {:string, _, %{line: 2, column: 10, line_end: 4, column_end: 6}}, %{}} + ] = attrs + end + test "raise on incomplete attribute value (EOF)" do assert_raise ParseError, "nofile:2:15: expected closing `\'` for attribute value", fn -> tokenize!("""