Skip to content

Commit 01a51b3

Browse files
committed
Removed old compiler code and promoted new compiler code
1 parent 4080313 commit 01a51b3

143 files changed

Lines changed: 224 additions & 11343 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

lib/elixir_script.ex

Lines changed: 0 additions & 238 deletions
Original file line numberDiff line numberDiff line change
@@ -1,240 +1,2 @@
11
defmodule ElixirScript do
2-
require Logger
3-
4-
@moduledoc """
5-
Translates Elixir into JavaScript.
6-
7-
All compile functions return a list of
8-
transpiled javascript code or a tuple consisting of
9-
the file name for the code and the transpiled javascript code.
10-
11-
All compile functions also take an optional opts parameter
12-
that controls transpiler output.
13-
14-
Available options are:
15-
* `:include_path` - a boolean controlling whether to return just the JavaScript code
16-
or a tuple of the file name and the JavaScript code
17-
* `:core_path` - The es6 import path used to import the elixirscript core.
18-
When using this option, the Elixir.js file is not exported
19-
* `:full_build` - For compile_path, tells the compiler to perform a full build instead of incremental one
20-
* `:output` - option to tell compiler how to output data
21-
* `nil`: Return as list
22-
* `:stdout`: Write to standard out
23-
* `path (string)`: Write to specified path
24-
"""
25-
26-
defmacro __using__(_) do
27-
quote do
28-
import Kernel, except: [
29-
if: 2, unless: 2, abs: 1, apply: 2, apply: 3, binary_part: 3, hd: 1,
30-
tl: 1, is_atom: 1, is_binary: 1, is_bitstring: 1, is_boolean: 1, is_float: 1,
31-
is_function: 1, is_function: 2, is_integer: 1, is_list: 1, is_number: 1,
32-
is_pid: 1, is_tuple: 1, is_map: 1, is_port: 1, is_reference: 1, length: 1,
33-
map_size: 1, max: 2, min: 2, round: 1, trunc: 1, tuple_size: 1, elem: 2, is_nil: 1,
34-
make_ref: 1, spawn: 1, spawn: 3, spawn_link: 1, spawn_link: 3, spawn_monitor: 1,
35-
spawn_monitor: 3, send: 2, self: 0, match?: 2, to_string: 1, "|>": 2, in: 2, "..": 2,
36-
sigil_r: 2
37-
]
38-
import ElixirScript.Kernel
39-
require JS
40-
end
41-
end
42-
43-
# This is the serialized state of the ElixirScript.State module containing references to the standard library
44-
@lib_path Application.get_env(:elixir_script, :lib_path)
45-
@version Mix.Project.config[:version]
46-
47-
@doc """
48-
Compiles the given Elixir code string
49-
"""
50-
@spec compile(binary, Map.t) :: [binary | {binary, binary} | :ok]
51-
def compile(elixir_code, opts \\ %{}) do
52-
elixir_code
53-
|> List.wrap
54-
|> Enum.map(fn(x) ->
55-
x
56-
|> Code.string_to_quoted!
57-
|> compile_quoted(opts)
58-
end)
59-
|> List.flatten
60-
end
61-
62-
@doc """
63-
Compiles the given Elixir code in quoted form
64-
"""
65-
@spec compile_quoted(Macro.t, Map.t) :: [binary | {binary, binary} | :ok]
66-
def compile_quoted(quoted, opts \\ %{}) do
67-
68-
opts = build_compiler_options(opts)
69-
70-
data = quoted
71-
|> get_modules_from_quoted
72-
|> Enum.map(fn(x) -> %{ast: x, app: :app} end)
73-
74-
std_lib_quoted = get_quoted_std_lib()
75-
76-
%{data: std_lib_quoted ++ data}
77-
|> ElixirScript.Passes.Init.execute(opts)
78-
|> shared_passes(opts)
79-
end
80-
81-
defp shared_passes(compiler_data, opts) do
82-
compiler_data
83-
|> ElixirScript.Passes.FindModules.execute(opts)
84-
|> ElixirScript.Passes.FindLoadOnly.execute(opts)
85-
|> ElixirScript.Passes.HandleOverridables.execute(opts)
86-
|> ElixirScript.Passes.FindFunctions.execute(opts)
87-
|> ElixirScript.Passes.JavaScriptAST.execute(opts)
88-
|> ElixirScript.Passes.ConsolidateProtocols.execute(opts)
89-
|> ElixirScript.Passes.RemoveUnused.execute(opts)
90-
|> ElixirScript.Passes.CreateJSModules.execute(opts)
91-
|> ElixirScript.Passes.JavaScriptCode.execute(opts)
92-
|> ElixirScript.Passes.HandleOutput.execute(opts)
93-
end
94-
95-
defp get_quoted_std_lib() do
96-
files = [get_std_lib_path(), "**", "*.ex"]
97-
|> Path.join
98-
|> Path.wildcard
99-
100-
files
101-
|> Enum.map(fn path -> File.read!(path) end)
102-
|> Enum.map(&Code.string_to_quoted!(&1))
103-
|> Enum.flat_map(&get_modules_from_quoted(&1))
104-
|> Enum.map(fn(x) -> %{ast: x, app: :elixir} end)
105-
end
106-
107-
defp get_modules_from_quoted(quoted) do
108-
results = case quoted do
109-
{:__block__, _, list} ->
110-
{modules, not_modules} = Enum.partition(list,
111-
fn
112-
{type, _, _ } when type in [:defprotocol, :defimpl, :defmodule] ->
113-
true
114-
_ ->
115-
false
116-
end)
117-
118-
temp_module = case not_modules do
119-
[] ->
120-
[]
121-
_ ->
122-
[{:defmodule, [], [{:__aliases__, [], [:ElixirScript, :Temp]}, [do: { :__block__, [], not_modules }]]}]
123-
end
124-
125-
modules ++ temp_module
126-
127-
{type, _, _ } = x when type in [:defprotocol, :defimpl, :defmodule] ->
128-
x
129-
x ->
130-
{:defmodule, [], [{:__aliases__, [], [:ElixirScript, :Temp]}, [do: { :__block__, [], [x] }]]}
131-
end
132-
133-
List.wrap(results)
134-
end
135-
136-
@doc """
137-
Compiles the elixir files found at the given path
138-
"""
139-
@spec compile_path(binary | [binary] | map, Map.t) :: [binary | {binary, binary} | :ok]
140-
def compile_path(path, opts \\ %{})
141-
142-
def compile_path(path, opts) when is_binary(path) do
143-
compile_path([path], opts)
144-
end
145-
146-
def compile_path(path, opts) when is_list(path) do
147-
built_opts = build_compiler_options(opts)
148-
149-
app_name = cond do
150-
!is_nil(built_opts[:app]) ->
151-
built_opts[:app]
152-
Code.ensure_loaded?(Mix) ->
153-
Mix.Project.config()[:app]
154-
true ->
155-
:app
156-
end
157-
158-
compile_path(Map.put(%{}, app_name, path), opts)
159-
end
160-
161-
def compile_path(path, opts) do
162-
opts = build_compiler_options(opts)
163-
164-
deps = path
165-
|> Map.to_list
166-
|> Enum.map(fn {app, path} -> {app, List.wrap(path)} end)
167-
168-
deps_wrapped = [{:elixir, List.wrap(get_std_lib_path())}] ++ deps
169-
170-
result = %{data: deps_wrapped}
171-
|> ElixirScript.Passes.Init.execute(opts)
172-
|> ElixirScript.Passes.ASTFromFile.execute(opts)
173-
|> ElixirScript.Passes.LoadModules.execute(opts)
174-
|> shared_passes(opts)
175-
176-
result
177-
end
178-
179-
defp build_compiler_options(opts) do
180-
default_options = Map.new
181-
|> Map.put(:include_path, false)
182-
|> Map.put(:root, nil)
183-
|> Map.put(:env, __ENV__)
184-
|> Map.put(:import_standard_libs, true)
185-
|> Map.put(:core_path, "Elixir.Bootstrap")
186-
|> Map.put(:full_build, false)
187-
|> Map.put(:output, nil)
188-
|> Map.put(:app, :app)
189-
|> Map.put(:format, :es)
190-
|> Map.put(:js_modules, [])
191-
|> Map.put(:remove_unused, false)
192-
193-
options = Map.merge(default_options, opts)
194-
Map.put(options, :module_formatter, get_module_formatter(options[:format]))
195-
end
196-
197-
defp get_module_formatter(:umd) do
198-
ElixirScript.ModuleSystems.UMD
199-
end
200-
201-
defp get_module_formatter(:common) do
202-
ElixirScript.ModuleSystems.Common
203-
end
204-
205-
defp get_module_formatter(_) do
206-
ElixirScript.ModuleSystems.ES
207-
end
208-
209-
@doc """
210-
Returns the contents of the bootrstrap js file
211-
"""
212-
@spec get_bootstrap_js(string) :: string
213-
def get_bootstrap_js(module_format) do
214-
path = Path.join([operating_path, "build", to_string(module_format), "Elixir.Bootstrap.js"])
215-
File.read!(path)
216-
end
217-
218-
#Gets path to js files whether the mix project is available
219-
#or when used as an escript
220-
defp operating_path() do
221-
case @lib_path do
222-
nil ->
223-
if Code.ensure_loaded?(Mix.Project) do
224-
Path.join([Mix.Project.build_path, "lib", "elixir_script", "priv"])
225-
else
226-
split_path = Path.split(Application.app_dir(:elixirscript))
227-
replaced_path = List.delete_at(split_path, length(split_path) - 1)
228-
replaced_path = List.delete_at(replaced_path, length(replaced_path) - 1)
229-
Path.join(replaced_path)
230-
end
231-
lib_path ->
232-
lib_path
233-
end
234-
end
235-
236-
defp get_std_lib_path() do
237-
Path.join([operating_path(), "std_lib"])
238-
end
239-
2402
end

lib/elixir_script/lib/js.ex

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
defmodule JS do
2+
@moduledoc """
3+
This module defines macros and functions which implement
4+
JavaScript functionality that may not translate easily to
5+
Elixir. For instance, creating a new object
6+
"""
7+
8+
@doc """
9+
Creates new JavaScript objects.
10+
11+
ex:
12+
JS.new User, ["first_name", "last_name"]
13+
"""
14+
defmacro new(module, params)
15+
16+
@doc """
17+
Returns the type of the given value
18+
"""
19+
defmacro typeof(value)
20+
21+
@doc """
22+
Determines if value is an instance of type.
23+
"""
24+
defmacro instanceof(value, type)
25+
26+
@doc """
27+
Throws the term given
28+
"""
29+
defmacro throw(term)
30+
31+
@doc """
32+
Creates a breakpoint for JavaScript debuggers to stop at
33+
"""
34+
defmacro debugger()
35+
36+
@doc """
37+
The current JavaScript context
38+
"""
39+
defmacro this()
40+
end
Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ defmodule ElixirScript.String do
33
import Kernel, except: [length: 1]
44

55
def to_atom(str) do
6-
JS.Symbol.for(str)
6+
:erlang.binary_to_atom(str, :utf8)
77
end
88

99
def to_existing_atom(str) do
10-
JS.Symbol.for(str)
10+
:erlang.binary_to_existing_atom(str, :utf8)
1111
end
1212

1313
def to_char_list(str) do
@@ -198,12 +198,7 @@ defmodule ElixirScript.String do
198198
do_codepoints(str.substr(1), codepoint_list ++ [first(str).codePointAt(0)])
199199
end
200200

201-
def valid_character?(codepoint) do
202-
try do
203-
JS.String.fromCodePoint(codepoint) != nil
204-
rescue
205-
_ ->
206-
false
207-
end
201+
def valid?(str) do
202+
is_binary(str)
208203
end
209204
end

lib/elixir_script/module_systems/common.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ defmodule ElixirScript.ModuleSystems.Common do
2121
end
2222

2323
defp import_module(module_name, from) do
24-
js_module_name = ElixirScript.Translator.Identifier.make_namespace_members(module_name)
24+
js_module_name = ElixirScript.Translate.Identifier.make_namespace_members(module_name)
2525
do_import_module(js_module_name, from)
2626
end
2727

lib/elixir_script/module_systems/es.ex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ defmodule ElixirScript.ModuleSystems.ES do
2222
end
2323

2424
defp import_namespace_module(module_name, from) do
25-
js_module_name = ElixirScript.Translator.Identifier.make_namespace_members(module_name)
25+
js_module_name = ElixirScript.Translate.Identifier.make_namespace_members(module_name)
2626

2727
import_specifier = JS.import_namespace_specifier(
2828
js_module_name,
@@ -33,7 +33,7 @@ defmodule ElixirScript.ModuleSystems.ES do
3333
end
3434

3535
defp import_module(import_name, from) do
36-
js_module_name = ElixirScript.Translator.Identifier.make_namespace_members(import_name)
36+
js_module_name = ElixirScript.Translate.Identifier.make_namespace_members(import_name)
3737

3838
import_specifier = JS.import_default_specifier(
3939
js_module_name

lib/elixir_script/module_systems/namespace.ex

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ defmodule ElixirScript.ModuleSystems.Namespace do
44
alias ElixirScript.Translator
55
alias ElixirScript.Translator.State
66
alias ElixirScript.Translator.Utils
7-
alias ElixirScript.Translator.Identifier
7+
alias ElixirScript.Translate.Identifier
88

99
def build(module_name, body, exports, env) do
1010
List.wrap(make_namespace_body(module_name, body, exports))
@@ -69,12 +69,12 @@ defmodule ElixirScript.ModuleSystems.Namespace do
6969
JS.identifier("__exports")
7070
)
7171

72-
exports = [JS.return_statement(JS.identifier("__exports"))]
72+
exports = [JS.return_statement(JS.identifier("__exports"))]
7373

7474
make = JS.member_expression(
7575
JS.call_expression(
7676
build_namespace(),
77-
[JS.identifier("Elixir"), JS.literal(Utils.name_to_js_file_name(module_name))]
77+
[JS.identifier("Elixir"), JS.literal(Enum.join(["Elixir"] ++ Module.split(module_name), "."))]
7878
),
7979
JS.identifier("__load")
8080
)

lib/elixir_script/module_systems/umd.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ defmodule ElixirScript.ModuleSystems.UMD do
2121
end
2222

2323
defp import_module(module_name, from) do
24-
js_module_name = ElixirScript.Translator.Identifier.make_namespace_members(module_name)
24+
js_module_name = ElixirScript.Translate.Identifier.make_namespace_members(module_name)
2525
{js_module_name, JS.literal(from)}
2626
end
2727

lib/elixir_script/passes/ast_from_file.ex

Lines changed: 0 additions & 26 deletions
This file was deleted.

0 commit comments

Comments
 (0)