Packages

Represents the JavaScript AST from the ESTree spec. Includes tools for building an AST and generating code from it.

Current section

17 Versions

Jump to

Compare versions

5 files changed
+74 additions
-35 deletions
  @@ -1,3 +1,7 @@
1 + # v2.4.0
2 + * Enhancements:
3 + * Added exponential operators from ES2016
4 +
1 5 # v2.3.0
2 6 * Enhancements:
3 7 * Added AssignmentProperty for use with ObjectPattern
  @@ -72,4 +72,4 @@
72 72 {<<"maintainers">>,[<<"Bryan Joseph">>]}.
73 73 {<<"name">>,<<"estree">>}.
74 74 {<<"requirements">>,[]}.
75 - {<<"version">>,<<"2.3.0">>}.
75 + {<<"version">>,<<"2.4.0">>}.
  @@ -22,13 +22,13 @@ defmodule ESTree do
22 22
23 23 @type binary_operator :: :== | :!= | :=== | :!== | :< | :<= | :> | :>= |
24 24 :"<<" | :">>" | :>>> | :+ | :- | :* | :/ | :% | :| |
25 - :^ | :& | :in | :instanceof
25 + :^ | :& | :in | :instanceof | :"**"
26 26
27 27 @type logical_operator :: :|| | :&&
28 28
29 29 @type assignment_operator :: := | :"+=" | :"-=" | :"*=" | :"/=" | :"%=" |
30 30 :"<<=" | :">>=" | :">>>=" |
31 - :"|=" | :"^=" | :"&="
31 + :"|=" | :"^=" | :"&=" | :"**="
32 32
33 33 @type update_operator :: :++ | :--
  @@ -16,8 +16,8 @@ defmodule ESTree.Tools.Generator do
16 16 @indent " "
17 17
18 18 @spec generate(ESTree.operator | ESTree.Node.t, integer) :: binary
19 - def generate(value, level \\ 0) do
20 - "#{indent(level)}#{do_generate(value, level + 1)}"
19 + def generate(value, level \\ nil) do
20 + "#{do_generate(value, calculate_next_level(level))}"
21 21 end
22 22
23 23 def do_generate(nil, level)do
  @@ -63,7 +63,7 @@ defmodule ESTree.Tools.Generator do
63 63 end
64 64
65 65 def do_generate(%ESTree.Program{body: body}, level) do
66 - Enum.map_join(body, "\n", &generate(&1, level + 1))
66 + Enum.map_join(body, newline(level), &generate(&1, calculate_next_level(level)))
67 67 end
68 68
69 69 def do_generate(%ESTree.FunctionDeclaration{} = ast, level) do
  @@ -73,7 +73,7 @@ defmodule ESTree.Tools.Generator do
73 73 params = params_and_defaults(ast.params, ast.defaults)
74 74 id = generate(ast.id)
75 75
76 - "#{async}function#{generator} #{id}(#{params})#{generate(ast.body, level + 1)}"
76 + "#{async}function#{generator} #{id}(#{params})#{generate(ast.body, calculate_next_level(level))}"
77 77 end
78 78
79 79 def do_generate(%ESTree.FunctionExpression{} = ast, level) do
  @@ -81,7 +81,7 @@ defmodule ESTree.Tools.Generator do
81 81 async = if ast.async, do: "async ", else: ""
82 82 params = params_and_defaults(ast.params, ast.defaults)
83 83
84 - "#{async}function#{generator}(#{params})#{generate(ast.body, level + 1)}"
84 + "#{async}function#{generator}(#{params})#{generate(ast.body, calculate_next_level(level))}"
85 85 end
86 86
87 87 def do_generate(%ESTree.EmptyStatement{}, level) do
  @@ -89,7 +89,7 @@ defmodule ESTree.Tools.Generator do
89 89 end
90 90
91 91 def do_generate(%ESTree.BlockStatement{body: body}, level) do
92 - "{\n#{indent(level + 1)}" <> Enum.map_join(body, "\n#{indent(level + 1)}", &generate(&1)) <> "\n#{indent(level)}}"
92 + "{#{newline(level)}#{indent(calculate_next_level(level))}" <> Enum.map_join(body, "#{newline(level)}#{indent(calculate_next_level(level))}", &generate(&1)) <> "#{newline(level)}#{indent(level)}}"
93 93 end
94 94
95 95 def do_generate(%ESTree.ExpressionStatement{expression: expression}, level) do
  @@ -98,11 +98,11 @@ defmodule ESTree.Tools.Generator do
98 98
99 99 def do_generate(%ESTree.IfStatement{test: test, consequent: consequent, alternate: alternate}, level) do
100 100 test = generate(test)
101 - consequent = generate(consequent, level + 1)
101 + consequent = generate(consequent, calculate_next_level(level))
102 102 result = "if(#{test}) #{consequent}"
103 103
104 104 if alternate do
105 - result = result <> " else #{generate(alternate, level + 1)}"
105 + result = result <> " else #{generate(alternate, calculate_next_level(level))}"
106 106 end
107 107
108 108 result
  @@ -111,7 +111,7 @@ defmodule ESTree.Tools.Generator do
111 111 def do_generate(%ESTree.LabeledStatement{label: label, body: body}, level) do
112 112 """
113 113 #{generate(label, level)}:
114 - #{generate(body, level + 1)}
114 + #{generate(body, calculate_next_level(level))}
115 115 """
116 116 end
117 117
  @@ -132,47 +132,47 @@ defmodule ESTree.Tools.Generator do
132 132 end
133 133
134 134 def do_generate(%ESTree.WithStatement{object: object, body: body}, level) do
135 - "with(#{generate(object)})#{generate(body, level + 1)}"
135 + "with(#{generate(object)})#{generate(body, calculate_next_level(level))}"
136 136 end
137 137
138 138 def do_generate(%ESTree.SwitchStatement{discriminant: discriminant, cases: cases}, level) do
139 - cases = Enum.map_join(cases, "\n", &generate(&1, level + 1))
139 + cases = Enum.map_join(cases, newline(level), &generate(&1, calculate_next_level(level)))
140 140 "switch(#{generate(discriminant)}){ #{cases} }"
141 141 end
142 142
143 143 def do_generate(%ESTree.ReturnStatement{argument: argument}, level) do
144 - "return #{generate(argument, level + 1)};"
144 + "return #{generate(argument, calculate_next_level(level))};"
145 145 end
146 146
147 147 def do_generate(%ESTree.ThrowStatement{argument: argument}, level) do
148 - "throw #{generate(argument, level + 1)};"
148 + "throw #{generate(argument, calculate_next_level(level))};"
149 149 end
150 150
151 151 def do_generate(%ESTree.TryStatement{block: block, handler: handler, finalizer: nil}, level) do
152 - "try#{generate(block, level + 1)}#{generate(handler, level + 1)}"
152 + "try#{generate(block, calculate_next_level(level))}#{generate(handler, calculate_next_level(level))}"
153 153 end
154 154
155 155 def do_generate(%ESTree.TryStatement{block: block, handler: nil, finalizer: finalizer}, level) do
156 - "try#{generate(block, level + 1)}finally#{generate(finalizer, level + 1)}"
156 + "try#{generate(block, calculate_next_level(level))}finally#{generate(finalizer, calculate_next_level(level))}"
157 157 end
158 158
159 159 def do_generate(%ESTree.TryStatement{block: block, handler: handler, finalizer: finalizer}, level) do
160 - "try#{generate(block, level + 1)}#{generate(handler, level + 1)}finally#{generate(finalizer, level + 1)}"
160 + "try#{generate(block, calculate_next_level(level))}#{generate(handler, calculate_next_level(level))}finally#{generate(finalizer, calculate_next_level(level))}"
161 161 end
162 162
163 163 def do_generate(%ESTree.WhileStatement{test: test, body: body}, level) do
164 - "while(#{generate(test)}) #{generate(body, level + 1)}"
164 + "while(#{generate(test)}) #{generate(body, calculate_next_level(level))}"
165 165 end
166 166
167 167 def do_generate(%ESTree.DoWhileStatement{test: test, body: body}, level) do
168 - "do #{generate(body, level + 1)} while(#{generate(test, level)});"
168 + "do #{generate(body, calculate_next_level(level))} while(#{generate(test, level)});"
169 169 end
170 170
171 171 def do_generate(%ESTree.ForStatement{init: init, test: test, update: update, body: body}, level) do
172 172 init = generate(init)
173 173 test = generate(test)
174 174 update = generate(update)
175 - body = generate(body, level + 1)
175 + body = generate(body, calculate_next_level(level))
176 176
177 177 "for(#{init}; #{test}; #{update}) #{body}"
178 178 end
  @@ -180,7 +180,7 @@ defmodule ESTree.Tools.Generator do
180 180 def do_generate(%ESTree.ForInStatement{left: left, right: right, body: body}, level) do
181 181 left = generate(left) |> String.replace(";","")
182 182 right = generate(right)
183 - body = generate(body, level + 1)
183 + body = generate(body, calculate_next_level(level))
184 184
185 185 "for(#{left} in #{right}) #{body}"
186 186 end
  @@ -232,7 +232,10 @@ defmodule ESTree.Tools.Generator do
232 232 end
233 233
234 234 def do_generate(%ESTree.ObjectExpression{properties: properties}, level) do
235 - "{\n#{indent(level + 1)}" <> Enum.map_join(properties, ", ", &generate(&1, level + 1)) <> "\n#{indent(level)}}"
235 + next_level = calculate_next_level(level)
236 + previous_level = calculate_previous_level(level)
237 + key_value_separator = ",#{newline(level)}#{indent(level)}"
238 + "{#{newline(level)}#{indent(level)}" <> Enum.map_join(properties, key_value_separator, &generate(&1)) <> "#{newline(level)}#{indent(previous_level)}}"
236 239 end
237 240
238 241 def do_generate(%ESTree.Property{key: key, value: value, kind: :init, shorthand: false, method: false, computed: false}, level) do
  @@ -360,8 +363,8 @@ defmodule ESTree.Tools.Generator do
360 363 end
361 364
362 365 def do_generate(%ESTree.CallExpression{callee: %ESTree.MemberExpression{ object: %ESTree.FunctionExpression{} } = callee, arguments: arguments}, level) do
363 - callee = generate(callee)
364 - arguments = Enum.map_join(arguments, ",", &generate(&1))
366 + callee = generate(callee, level)
367 + arguments = Enum.map_join(arguments, ",", &generate(&1, level))
365 368
366 369 "(#{callee}(#{arguments}))"
367 370 end
  @@ -374,7 +377,7 @@ defmodule ESTree.Tools.Generator do
374 377
375 378 def do_generate(%ESTree.CallExpression{callee: callee, arguments: arguments}, level) do
376 379 callee = generate(callee)
377 - arguments = Enum.map_join(arguments, ",", &generate(&1))
380 + arguments = Enum.map_join(arguments, ",", &generate(&1, calculate_previous_level(level)))
378 381
379 382 "#{callee}(#{arguments})"
380 383 end
  @@ -409,7 +412,7 @@ defmodule ESTree.Tools.Generator do
409 412 end
410 413
411 414 def do_generate(%ESTree.SwitchCase{test: nil, consequent: consequent}, level) do
412 - consequent = Enum.map_join(consequent, "\n", &generate(&1))
415 + consequent = Enum.map_join(consequent, newline(level), &generate(&1))
413 416 """
414 417 default:
415 418 #{consequent}
  @@ -418,7 +421,7 @@ defmodule ESTree.Tools.Generator do
418 421
419 422 def do_generate(%ESTree.SwitchCase{test: test, consequent: consequent}, level) do
420 423 test = generate(test)
421 - consequent = Enum.map_join(consequent, "\n", &generate(&1))
424 + consequent = Enum.map_join(consequent, newline(level), &generate(&1))
422 425
423 426 """
424 427 case #{test}:
  @@ -523,7 +526,7 @@ defmodule ESTree.Tools.Generator do
523 526 end
524 527
525 528 def do_generate(%ESTree.ClassBody{body: body}, level) do
526 - body = Enum.map_join(body, "\n", &generate(&1))
529 + body = Enum.map_join(body, newline(level), &generate(&1))
527 530
528 531 "{ #{body} }"
529 532 end
  @@ -728,8 +731,12 @@ defmodule ESTree.Tools.Generator do
728 731
729 732 def do_generate(%ESTree.JSXOpeningElement{ name: name, attributes: attributes, selfClosing: selfClosing }, level) do
730 733 selfClosing = if selfClosing, do: "/", else: ""
731 -
732 - "<#{generate(name)} #{ Enum.map(attributes, &generate(&1)) |> Enum.join(" ") }#{selfClosing}>"
734 + attributesValue = cond do
735 + Enum.empty?(attributes) -> ""
736 + true ->
737 + " #{Enum.map(attributes, &generate(&1)) |> Enum.join(" ")}"
738 + end
739 + "<#{generate(name)}#{attributesValue}#{selfClosing}>"
733 740 end
734 741
735 742 def do_generate(%ESTree.JSXClosingElement{ name: name }, level) do
  @@ -745,7 +752,7 @@ defmodule ESTree.Tools.Generator do
745 752 end
746 753
747 754 def do_generate(%ESTree.JSXElement{ openingElement: openingElement, children: children, closingElement: closingElement }, level) do
748 - "#{ generate(openingElement) } #{ Enum.map(children, &generate(&1, level + 1)) |> Enum.join(" ") } #{ generate(closingElement) }"
755 + "#{ generate(openingElement) }#{ Enum.map(children, &generate(&1, calculate_next_level(level))) |> Enum.join(" ") }#{ generate(closingElement) }"
749 756 end
750 757
751 758 defp convert_string_characters(str) do
  @@ -765,7 +772,35 @@ defmodule ESTree.Tools.Generator do
765 772 end)
766 773 end
767 774
775 + defp indent(nil) do
776 + ""
777 + end
778 +
768 779 defp indent(level) do
769 780 String.duplicate(" ", level)
770 781 end
782 +
783 + defp calculate_next_level(nil) do
784 + nil
785 + end
786 +
787 + defp calculate_next_level(level) do
788 + level + 1
789 + end
790 +
791 + defp calculate_previous_level(nil) do
792 + nil
793 + end
794 +
795 + defp calculate_previous_level(level) do
796 + level - 1
797 + end
798 +
799 + defp newline(nil) do
800 + ""
801 + end
802 +
803 + defp newline(level) do
804 + "\n"
805 + end
771 806 end
  @@ -3,7 +3,7 @@ defmodule ESTree.Mixfile do
3 3
4 4 def project do
5 5 [app: :estree,
6 - version: "2.3.0",
6 + version: "2.4.0",
7 7 elixir: "~> 1.0",
8 8 deps: deps,
9 9 description: description,
  @@ -18,7 +18,7 @@ defmodule ESTree.Mixfile do
18 18 defp deps do
19 19 [
20 20 {:earmark, "~> 0.2", only: :dev},
21 - {:ex_doc, "~> 0.11", only: :dev},
21 + {:ex_doc, "~> 0.12", only: :dev},
22 22 {:dialyze, "~> 0.2", only: :dev},
23 23 {:shouldi, only: :test}
24 24 ]