Skip to content

Commit 7de68b4

Browse files
committed
Added generation of template literals
1 parent 71f29b6 commit 7de68b4

File tree

4 files changed

+155
-6
lines changed

4 files changed

+155
-6
lines changed

lib/es_tree/template_element.ex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ defmodule ESTree.TemplateElement do
22
@type t :: %ESTree.TemplateElement{
33
type: binary,
44
loc: ESTree.SourceLocation.t | nil,
5-
value: %{cooked: binary, raw: binary},
5+
value: %{cooked: binary, value: binary},
66
tail: boolean
77
}
88
defstruct type: "TemplateElement",
99
loc: nil,
10-
value: %{cooked: "", binary: ""},
10+
value: %{cooked: "", value: ""},
1111
tail: false
1212
end

lib/es_tree/tools/builder.ex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -643,9 +643,9 @@ defmodule ESTree.Tools.Builder do
643643
boolean,
644644
ESTree.SourceLocation.t | nil
645645
) :: ESTree.TemplateElement.t
646-
def template_element(cooked_value, raw_value, tail, loc \\ nil) do
646+
def template_element(value, cooked_value, tail, loc \\ nil) do
647647
%ESTree.TemplateElement{
648-
value: %{cooked: cooked_value, raw: raw_value}, tail: tail, loc: loc
648+
value: %{cooked: cooked_value, value: value}, tail: tail, loc: loc
649649
}
650650
end
651651

lib/es_tree/tools/generator.ex

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,7 @@ defmodule ESTree.Tools.Generator do
4141
end
4242

4343
def generate(%ESTree.Literal{value: value}) when is_binary(value) do
44-
value = String.replace(value, "\n", "\\n")
45-
|> String.replace("\t", "\\t")
44+
value = convert_string_characters(value)
4645

4746
"'#{value}'"
4847
end
@@ -645,6 +644,51 @@ defmodule ESTree.Tools.Generator do
645644
source = generate(source)
646645
"export * from #{source};"
647646
end
647+
648+
def generate(%ESTree.TaggedTemplateExpression{tag: tag, quasi: quasi}) do
649+
tag = generate(tag)
650+
quasi = generate(quasi)
651+
652+
"#{tag} #{quasi}"
653+
end
654+
655+
def generate(%ESTree.TemplateLiteral{expressions: [], quasis: []}) do
656+
"``"
657+
end
658+
659+
def generate(%ESTree.TemplateLiteral{expressions: [expression], quasis: []}) do
660+
expression = generate(expression)
661+
"`${#{expression}}`"
662+
end
663+
664+
def generate(%ESTree.TemplateLiteral{expressions: [], quasis: [quasi]}) do
665+
quasi = convert_string_characters(quasi.value.value)
666+
"`#{quasi}`"
667+
end
668+
669+
def generate(%ESTree.TemplateLiteral{expressions: expressions, quasis: quasis}) do
670+
elements = expressions ++ quasis
671+
672+
literal = Enum.sort(elements, fn(one, two) ->
673+
one.loc.start.column < two.loc.start.column
674+
end)
675+
|> Enum.reduce("", fn(el, str) ->
676+
case el do
677+
%ESTree.TemplateElement{} ->
678+
str <> convert_string_characters(el.value.value)
679+
_ ->
680+
str <> "${#{generate(el)}}"
681+
end
682+
end)
683+
684+
685+
"`#{literal}`"
686+
end
687+
688+
defp convert_string_characters(str) do
689+
String.replace(str, "\n", "\\n")
690+
|> String.replace("\t", "\\t")
691+
end
648692

649693
defp params_and_defaults(params, []) do
650694
Enum.map_join(params, ",", &generate(&1))
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
defmodule ESTree.Tools.Generator.TemplateLiteral.Test do
2+
use ShouldI
3+
alias ESTree.Tools.Builder
4+
alias ESTree.Tools.Generator
5+
6+
7+
should "convert empty template literal" do
8+
ast = Builder.template_literal([],[])
9+
assert Generator.generate(ast) == "``"
10+
end
11+
12+
should "convert template literal with no expressions" do
13+
ast = Builder.template_literal([
14+
Builder.template_element("hello ", "hello ", false,
15+
Builder.source_location(
16+
nil,
17+
Builder.position(0, 1),
18+
Builder.position(0, 5)
19+
)
20+
),
21+
Builder.template_element("there", "there", true,
22+
Builder.source_location(
23+
nil,
24+
Builder.position(0, 5),
25+
Builder.position(0, 10)
26+
)
27+
)
28+
],[])
29+
assert Generator.generate(ast) == "`hello there`"
30+
end
31+
32+
should "convert template literal with no quasis" do
33+
ast = Builder.template_literal([],[
34+
Builder.identifier(:a,
35+
Builder.source_location(
36+
nil,
37+
Builder.position(0, 1),
38+
Builder.position(0, 2)
39+
)
40+
)
41+
])
42+
assert Generator.generate(ast) == "`${a}`"
43+
end
44+
45+
46+
should "convert template literal with interlaping quasis and expressions" do
47+
ast = Builder.template_literal([
48+
Builder.template_element("hello ", "hello ", false,
49+
Builder.source_location(
50+
nil,
51+
Builder.position(0, 1),
52+
Builder.position(0, 5)
53+
)
54+
),
55+
Builder.template_element(" there", " there", true,
56+
Builder.source_location(
57+
nil,
58+
Builder.position(0, 6),
59+
Builder.position(0, 12)
60+
)
61+
)
62+
],[
63+
Builder.identifier(:a,
64+
Builder.source_location(
65+
nil,
66+
Builder.position(0, 5),
67+
Builder.position(0, 6)
68+
)
69+
)
70+
])
71+
assert Generator.generate(ast) == "`hello ${a} there`"
72+
end
73+
74+
should "convert tagged template expressions" do
75+
ast = Builder.tagged_template_expression(
76+
Builder.identifier(:tag),
77+
Builder.template_literal([
78+
Builder.template_element("hello ", "hello ", false,
79+
Builder.source_location(
80+
nil,
81+
Builder.position(0, 1),
82+
Builder.position(0, 5)
83+
)
84+
),
85+
Builder.template_element(" there", " there", true,
86+
Builder.source_location(
87+
nil,
88+
Builder.position(0, 6),
89+
Builder.position(0, 12)
90+
)
91+
)
92+
],[
93+
Builder.identifier(:a,
94+
Builder.source_location(
95+
nil,
96+
Builder.position(0, 5),
97+
Builder.position(0, 6)
98+
)
99+
)
100+
])
101+
)
102+
assert Generator.generate(ast) == "tag `hello ${a} there`"
103+
end
104+
105+
end

0 commit comments

Comments
 (0)